目录
一、概述
二、创建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语法
*, *::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);
}
}
零碎笔记:
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组件
点击可实现滑动效果
分析
代码
Welcome Back !
To keep connected with us please login with your personal info
Hello Friend !
Enter your personal details and start journey with us
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");
}
@import './login.css';
/*
将源码中的css样式单独存放,在各组件中导入就可以。
后续整理代码时建议,将全局样式和局部样式分开。
*/
部分css样式
实现隐藏
隐藏元素的几种方法:opacity: 0、visibility: hidden、display: none
移动主要是靠设置 left 偏移得到的
移动过程中的动画
4.3、sign组件
两者结构部分
@import './login.css';
/* 将源码中的css样式单独存放,在各组件中导入就可以。*/
@import './login.css';
/* 将源码中的css样式单独存放,在各组件中导入就可以。*/
像组件中如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.emitter
return emitter
}
5.1、在switch组件中添加部分代码
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.value
emitter.emit('change', sidebarOpen.value)
}
vscode中可能会有错误提示,用的语法是ts的,导入自定义js时会检查其类型。
取消检查==>
修改tsconfig.json中的compilerOptions,将"allowJs"设为true,没有则自行添加
5.2、sign_in/sign_up内添加:
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");
}
}
})
})
到这边样式部分基本完毕了,存在什么问题、遗漏,请多多交流,帮帮本萌新,之后会对登录、注册的功能进行实现。
vue 3 项目实战二(实现登录、注册)_咔卡熊的博客-CSDN博客
参考阅读
发表评论