目录

一、概述

二、创建vue项目

三、需求分析

四、构建组件

五、vue组件之间的通信


一、概述

本文记录了项目实现的详细步骤以及原理,十分适合初学vue的萌新练手,也是阶段性学习的一个总结,可能会有些啰嗦,勿怪~。

先从登录界面开始,常规的登录界面不太好看,起不到复习巩固的作用,于是找到了下面这个

源码

https://codepen.io/ricardoolivaalonso/pen/YzyaRPNhttps://codepen.io/ricardoolivaalonso/pen/YzyaRPN下面将其拆解并封装,相当于化简为繁,将原本的html+css+js 项目转变为了vue项目,拆分成了三个组件。过程比较详细且啰嗦,选择性观看即可。

二、创建vue项目

1、vue create project_name

2、相关配置

3、cd project_name

4、code .         //快捷打开vscode

Typescript 是JavaScript的超集,Typescript语法在执行是会先转成JavaScript,在使用时如果不习惯ts可以转 js语法  <script setup lang="js"> 。

项目结构:

三、需求分析

 运行源代码可以发现,页面可分为三个主要部分:

因此将这三个部分封装成组件 ,在src下新建login文件夹,用于单独存放该项目的一些文件

进行一些初始化、将 router/index.ts 路由改写

import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'const routes: Array<RouteRecordRaw> = [{ path: '/', component: () => import('@/login/login.vue') },
]const router = createRouter({history: createWebHashHistory(),routes
})export default router

简单测试一下

四、构建组件

4.1、背景组件,也是该登录界面的父组件

 login/login.vue 文件代码

<template><div class="body"><div class="main">adad</div></div>
</template><script setup lang="ts"></script><style scoped >
*, *::after, *::before {margin: 0;padding: 0;box-sizing: border-box;user-select: none;}.body {width: 100%;height: 100vh;display: flex;justify-content: center;align-items: center;font-family: "Montserrat", sans-serif;font-size: 12px;background-color: #ecf0f3;color: #a0a5a8;}.main {position: relative;width: 1000px;min-width: 1000px;min-height: 600px;height: 600px;padding: 25px;background-color: #ecf0f3;box-shadow: 10px 10px 10px #d1d9e6, -10px -10px 10px #f9f9f9;border-radius: 20px;overflow: hidden;}@media (max-width: 1200px) {.main {transform: scale(0.7);}}@media (max-width: 1000px) {.main {transform: scale(0.6);}}@media (max-width: 800px) {.main {transform: scale(0.5);}}@media (max-width: 600px) {.main {transform: scale(0.4);}}
</style>

零碎笔记:

1.css盒子模型

即元素可以看成一个盒子,即拥有margin、border、padding、content四个属性

2.css的伪类和伪元素

伪类:为处于某个状态的已有元素添加对应的样式,(项目的切换按钮用到了伪类),例如

  • 设置鼠标悬停在元素上时的样式     :hover
  • 为已访问和未访问链接设置不同的样式    :link   :visited
  • 设置元素获得焦点时的样式  :focus

        注意:如果同时作用在一个元素上,有书写顺序,比如对a标签进行操作:

a:link  ->   a:visited  ->  a:hover  -> a:active

伪元素: 由“ :: ” 表示,创建一些不在文档树中的元素,并为其添加样式

  • ::after       在每个 元素之后插入内容。
  • ::befor      在每个元素之前插入内容。

3、元素定位:遵从 “ 子绝父相 ”

4.2、switch组件

点击可实现滑动效果

分析

代码

<template>
<div class="switch" id="switch-cnt"><div class="switch__circle"></div><div class="switch__circle switch__circle--t"></div><div class="switch__container" id="switch-c1"><h2 class="switch__title title">Welcome Back !</h2><p class="switch__description description">To keep connected with us please login with your personal info</p><button class="switch__button button switch-btn" @click="change">SIGN IN</button></div><div class="switch__container is-hidden" id="switch-c2"><h2 class="switch__title title">Hello Friend !</h2><p class="switch__description description">Enter your personal details and start journey with us</p><button class="switch__button button switch-btn" @click="change">SIGN UP</button></div></div>
</template><script setup lang="ts">const change = () => {const switchC1 = document.querySelector("#switch-c1") as any;const switchC2 = document.querySelector("#switch-c2") as any;const switchCircle = document.querySelectorAll(".switch__circle") as any;const switchCtn = document.querySelector("#switch-cnt") as any;  switchCtn.classList.add("is-gx");setTimeout(function(){switchCtn.classList.remove("is-gx");}, 1500)switchCtn.classList.toggle("is-txr");switchCircle[0].classList.toggle("is-txr");switchCircle[1].classList.toggle("is-txr");switchC1.classList.toggle("is-hidden");switchC2.classList.toggle("is-hidden");}
</script><style scoped>
@import './login.css';
/*
将源码中的css样式单独存放,在各组件中导入就可以。
后续整理代码时建议,将全局样式和局部样式分开。
*/
</style>

部分css样式

实现隐藏

隐藏元素的几种方法:opacity: 0、visibility: hidden、display: none

移动主要是靠设置 left 偏移得到的

移动过程中的动画

4.3、sign组件

两者结构部分

<!-- sign_up -->
<template><div class="container a-container" id="a-container"><form class="form" id="a-form" method="" action=""><h2 class="form_title title">Create Account</h2><div class="form__icons"><img class="form__icon" src=" "><img class="form__icon" src=" "><img class="form__icon" src=" "></div><span class="form__span">or use email for registration</span><input class="form__input" type="text" placeholder="Name"><input class="form__input" type="text" placeholder="Email"><input class="form__input" type="password" placeholder="Password"><button class="form__button button submit">SIGN UP</button></form></div>
</template>
<style scoped>
@import './login.css';
/* 将源码中的css样式单独存放,在各组件中导入就可以。*/
</style>
<!-- sign_in -->
<template>
<div class="container b-container" id="b-container"><form class="form" id="b-form" method="" action=""><h2 class="form_title title">Sign in to Website</h2><div class="form__icons"><img class="form__icon" src=" "><img class="form__icon" src=" "><img class="form__icon" src=" "></div><span class="form__span">or use your email account</span><input class="form__input" type="text" placeholder="用户名" v-model="loginFrom.username"><input class="form__input" type="password" placeholder="密码" v-model.lazy="loginFrom.password"><a class="form__link">Forgot your password?</a><button class="form__button button submit">SIGN IN</button></form>
</div>
</template>
<style scoped>
@import './login.css';
/* 将源码中的css样式单独存放,在各组件中导入就可以。*/
</style>

像组件中如facebook的小图标,利用base64 将图片转为字符串以此来代替src的位置,可以减少http请求。 (base64推荐小图标使用,jpg转base64,体积会变大一点点。)

也可以使用矢量图:iconfont-阿里巴巴矢量图标库

组件的移动和switch类似,多了个 z-index 来对这两个组件进行了堆叠

五、vue组件之间的通信

现在各组件已经构建好了,但想要让switch子组件的按钮事件,也能控制到sign_in/sign_up子组件,则需要借助 Event Bus(用其它的方式也行,比如vuex )。  常用的父子组件通讯方式有:props,$emit ,$ref 等。

Event Bus:就是A-->B 有困难,那么就借助全局C来传数据,A-->C-->B

Vue3中需要借助 mitt 组件库来完成

1、安装:npm i mitt

2、在main中声明

// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import mitt from 'mitt'const app=createApp(App)
app.config.globalProperties.emitter = mitt()app.use(router)
app.mount('#app')

3、新建文件、进封装

// src/hooks/useEmitter.js
import { getCurrentInstance } from 'vue'export default function useEmitter() {const internalInstance = getCurrentInstance()const emitter = internalInstance.appContext.config.globalProperties.emitterreturn emitter
}

 5.1、在switch组件中添加部分代码

<script setup lang="ts">import { ref } from 'vue'import useEmitter from '@/hooks/useEmitter.js'const sidebarOpen = ref(true)const emitter = useEmitter()const change = () => {const switchC1 = document.querySelector("#switch-c1") as any;const switchC2 = document.querySelector("#switch-c2") as any;const switchCircle = document.querySelectorAll(".switch__circle") as any;const switchCtn = document.querySelector("#switch-cnt") as any;switchCtn.classList.add("is-gx");setTimeout(function(){switchCtn.classList.remove("is-gx");}, 1500)switchCtn.classList.toggle("is-txr");switchCircle[0].classList.toggle("is-txr");switchCircle[1].classList.toggle("is-txr");switchC1.classList.toggle("is-hidden");switchC2.classList.toggle("is-hidden");sidebarOpen.value = !sidebarOpen.valueemitter.emit('change', sidebarOpen.value)}
</script>

vscode中可能会有错误提示,用的语法是ts的,导入自定义js时会检查其类型。

取消检查==>

修改tsconfig.json中的compilerOptions,将"allowJs"设为true,没有则自行添加

 5.2、sign_in/sign_up内添加:

<script setup lang="ts">import { ref, onMounted } from 'vue'import useEmitter from '@/hooks/useEmitter.js'// const isOpen  = ref(true)const emitter = useEmitter()onMounted(() => {emitter.on('change', (isOpen : boolean) => {watch: {isOpen:{let aContainer = document.querySelector("#a-container") as any;aContainer.classList.toggle("is-txl");//b中样式// let bContainer = document.querySelector("#b-container") as any;// bContainer.classList.toggle("is-txl");// bContainer.classList.toggle("is-z200");}}})})</script>

到这边样式部分基本完毕了,存在什么问题、遗漏,请多多交流,帮帮本萌新,之后会对登录、注册的功能进行实现。

vue 3 项目实战二(实现登录、注册)_咔卡熊的博客-CSDN博客

vue 3 项目实战一(绘制登录界面)相关推荐

  1. python项目实战:pyqt5实现登录界面模板

    2019独角兽企业重金招聘Python工程师标准>>> 前言 今天为大家介绍一个利用开发登录界面模板,基于pyqt5库,pyqt5这也一个PythonGUI界面开发的库,非常强大,关 ...

  2. vue.js项目实战运用篇之抖音视频APP-第十一节: 注册登录及验证码功能

    [温馨提示]:若想了解更多关于本次项目实战内容,可转至vue.js项目实战运用篇之抖音视频APP-项目规划中进一步了解项目规划. [项目地址] 项目采用Git进行管理,最终项目将会发布到GitHub中 ...

  3. vue.js项目实战运用篇之抖音视频APP-第三节:底部导航栏组件功能

    [温馨提示]:若想了解更多关于本次项目实战内容,可转至vue.js项目实战运用篇之抖音视频APP-项目规划中进一步了解项目规划. [项目地址] 项目采用Git进行管理,最终项目将会发布到GitHub中 ...

  4. vue.js项目实战运用篇之抖音视频APP-第二节:项目基础架构搭建

    [温馨提示]:若想了解更多关于本次项目实战内容,可转至vue.js项目实战运用篇之抖音视频APP-项目规划中进一步了解项目规划. [项目地址] 项目采用Git进行管理,最终项目将会发布到GitHub中 ...

  5. Vue ts 项目实战

    Vue ts 项目实战 首先,没装vue-cli的,可以使用下列任一命令安装这个新的包: npm install -g @vue/cli # OR yarn global add @vue/cli 安 ...

  6. vue+element ui实现好看的登录界面

    闲暇之余使用vue+element ui制作了个登录界面 话不多说,先上图 界面效果图 下面直接上代码: <template><div class="loginbody&q ...

  7. Vue + Element-UI —— 项目实战(零)(项目概述)

    Vue + ElementUI 后台管理项目实战 内容 参考链接 一 Vue + Element-UI -- 项目实战(零)(项目概述[附源码]) 二 Vue + Element-UI -- 项目实战 ...

  8. vue.js项目实战运用篇之抖音视频APP-第八节: 视频播放功能

    [温馨提示]:若想了解更多关于本次项目实战内容,可转至vue.js项目实战运用篇之抖音视频APP-项目规划中进一步了解项目规划. [项目地址] 项目采用Git进行管理,最终项目将会发布到GitHub中 ...

  9. vue.js项目实战运用篇之抖音视频APP-第一节:项目环境搭建

    [温馨提示]:若想了解更多关于本次项目实战内容,可转至vue.js项目实战运用篇之抖音视频APP-项目规划中进一步了解项目规划. [项目地址] 项目采用Git进行管理,最终项目将会发布到GitHub中 ...

最新文章

  1. MATLAB从入门到精通-新增返回数组高、宽数字特征的全新方式
  2. 经验|博士毕业,也写一些发文章的心得
  3. Entity Framework Core 执行SQL语句和存储过程
  4. 清华男神再获世界大奖,从放牛娃到清华校长,他考研3次,读博7年,做出诺奖级的科研成果...
  5. OpenCV 3.1 imwrite()函数写入异常问题解决方法
  6. docker build no such file or directory
  7. Tensorflow报错_np_qint8 = np.dtype([(“qint8“, np.int8, 1)])
  8. 01-操作数组的方法
  9. MySQL多线程备份工具mydumper
  10. API之实用工具Postman 使用方法
  11. MySQL客户端工具的选择
  12. linux yum 五笔输入法,CentOS 7 安装五笔输入法
  13. Entry name ‘res/layout/test_toolbar.xml‘ collided
  14. python 全栈开发,Day104(DRF用户认证,结算中心,django-redis)
  15. PAT_乙级_1007_筱筱
  16. oracle数据库直方图,[转] oracle统计信息(statistics)和直方图(histogram)
  17. Profinet协议基础知识(三)
  18. [华为 HCNA ] VLAN的介绍和划分
  19. 静心,多听,善思--学习之道也
  20. 先别急着练速写,人物慢写才是第一步

热门文章

  1. DataGrid梆定DroDownList
  2. 狂暴者 pat basic 练习二十九 旧键盘
  3. 蓝牙耳机超长续航哪个牌子好?长续航时间的无线耳机推荐!
  4. Prim算法(matlab实现)
  5. 高德地图驾车路径规划API,获取两地点之间的驾车里程和时间
  6. 【LeetCode刷题】374. 猜数字大小
  7. Survivor区放不下存活对象,那么存活对象直接就分配到老年代?
  8. NYOJ 整数划分(三) (划分数大集合)
  9. 体验 IntelliJ IDEA 2021.1 Run Targets 远程环境调试程序
  10. 火星人培训python