- 练习项目地址:github.com/1628415507/…
【基础入门篇】
(一)环境准备
- node:16.12.1(node版本需14.0.0以上)
- 项目搭建
- 创建⼀个Vite的初始化项⽬:
npm init vite - 选择模板
(二)Composition API
- 组合式 API
- 单⽂件组件
<script setup>Composition API的语法中,所有的功能都是通过全局引⼊的⽅式使⽤的,并且通过<script setup>的功能,我们定义的变量、函数和引⼊的组件,都不需要额外的⽣命周期,就可以直接在模板中使⽤。
1. ref:定义单个变量
- 通过ref申明的变量才是响应式的
- ref可以定位dom元素
用法
<div ref="dom"></div>
const dom = ref()
- shawdowRef
2. reactive
- toRef
- 只能用于响应式对象的解构,不是响应式对象,解构出来也不是响应式对象
- 使用场景,修改通过toRef取出的值时,reactive对象里面的对应字段的属性也会跟着变
const state = reactive({ foo: 1, bar: 2 }) // 双向 ref,会与源属性同步 const fooRef = toRef(state, 'foo') // 更改该 ref 会更新源属性 fooRef.value++ console.log(state.foo) // 2 // 更改源属性也会更新该 ref state.foo++ console.log(fooRef.value) // 3 - 在想把一个 prop 的 ref 传递给一个组合式函数时会很有用??
- toRefs:响应式解构
用于reactive对象的解构取值,解构出来的值也是响应式的
- toRaw:非响应式解构
用于reactive对象的解构取值,解构出来的值是非响应式的
3.computed
- 选项式写法,有get和set,允许修改值
const count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: (val) => {
count.value = val - 1
}
})
// 可以对computed进行赋值,同时会触发set
plusOne.value = 1
console.log(count.value) // 0
- 只读
const plusOne = computed(() => count.value + 1)
4.watch&watchEffet
- watch
- 视频
- 侦听多个的话以数组的形式
- 监听属性中的单一值需要转成函数才能监听到
- 引用类型的监听新旧值是一样的
- watchEffet高级监听
- 视频
- 立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。
- 第一个参数就是要运行的副作用函数可以用来清理无效的副作用
- 返回值是一个用来停止该副作用的函数
5.父子组件传值
- 父传子:defineProps
- 子传父:defineEmits
- 暴露方法:defineExports
- 使用场景:如表单的验证、重置方法
- 使用场景:如表单的验证、重置方法
2. style(单⽂件组件样式特性)
v-bind(color)
在style内部,我们使⽤v-bind函数绑定color的值,就可以动态地通过JavaScript的变量实现CSS的变化
<template>
<div>
<h1 @click="add">{{ count }}</h1>
</div>
</template>
<script setup>
import { ref } from 'vue';
let count = ref(1);
let color = ref('red');
function add() {
count.value++;
color.value = Math.random() > 0.5 ? 'blue' : 'red';
}
</script>
<style scoped>
h1 {
color: v-bind(color); //☆☆☆
}
</style>
>
(三)vue3的响应式
1. Proxy
Vue 3 的响应式机制是基于Proxy实现的。我们看下⾯的代码,在其中我们通过new Proxy代理了obj这个对象,然后通过get、set和deleteProperty函数代理了对象的读取、修改和删除操作,从⽽实现了响应式的功能。
let proxy = new Proxy(obj,{
get : function (target,prop) {
return target[prop]
},
set : function (target,prop,value) {
target[prop] = value;
if(prop==='count'){
double = getDouble(value)
}
},
deleteProperty(target,prop){
delete target[prop]
if(prop==='count'){
double = NaN
}
}
})
console.log(obj.count,double)
proxy.count = 2
console.log(obj.count,double)
delete proxy.count
// 删除属性后,我们打印log时,输出的结果就会是 undefined NaN
console.log(obj.count,double)
2. watchEffect
(四)组件化开发,组件间传值
现在组件的⽰意图如下,我们通过defifineProps定义了传递数据的格式,通过defifineEmits定义了监听的函数,最终实现了组件和外部数据之间的同步。
1. defineProps
defifineProps可以用来规范传递数据的格式
let props = defineProps({
value: Number,// 这⾥规定了组件会接收外部传来的value属性,并且只能是数字
theme: {
type: String,
default: 'orange'
}
});
2. defineEmits
在Vue 3中,我们使⽤defifineEmit来定义对外“发射”的数据,
// 父组件通过v-bind:绑定
<Rate2 :value="score2" @update-rate="updateRate" />
// 子组件
let emits = defineEmits('update-rate') // 定义emits
function onRate(num){
emits('update-rate',num)
}
3. 组件的v-model
对于⾃定义组件来说,v-model是两个语法,也就是:传⼊属性和接收组件传递数据和的简写。
在下⾯的代码中,⾸先我们把属性名修改成modelValue,然后如果我们想在前端⻚⾯进⾏点击评级的操作,我们只需要通过update:modelValue这个emit事件发出通知即可。
// 父组件通过v-model绑定
<Rate3 v-model="score3" theme="pink">插槽</Rate3>
// 子组件
let emits = defineEmits(['update:modelValue']);
function onRate(num) {
emits('update:modelValue', num);
}
(四)动画
1. traisition:单个组件过渡
- 在Vue中,如果我们想要在显⽰和隐藏标题⽂字的时候,加⼊动效进⾏过渡,直接使⽤
traisition组件包裹住需要动画的元素就可以了。 - transition组件会把⼦元素作为⼀个整体同时去过渡
<transition name="fade">
<h1 v-if="showTitle">你好 Vue 3</h1>
</transition>
- 图⾥的
v-enter-from中的v,就是我们上面代码中设置的name属性。 - 标签在进⼊和离开的时候,会有
[name]-enter-active和[name]-leave-active的class, - 进⼊的开始和结束会有
[name]-enter-from和[name]-enter-to两个class。
<style>
.fade-enter-active,
.fade-leave-active {
/* 设置opacity有0.5秒的过渡时间*/
transition: opacity 0.5s linear;
}
/* 在元素进⼊前和离开后设置 opacity为0 */
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>
2. transition-group:列表过渡
- 组件transition-group。用于实现列表项依次动画出现的效果。在Vue中,我们把这种需求称之为列表过渡。
- 在v-for渲染列表的场景之下,我们使⽤transition-group组件去包裹元素,通过tag属性去指定渲染⼀个元素。
- transition-group组件还有⼀个特殊之处,就是不仅可以进⼊和离开动画,还可以改变定位。
【全家桶实战篇】
(五)VUEX(实现原理)
(六)vue-router
(七)JSX
(八)TypeScript
TypeScript的主要作⽤是给JavaScript赋予强类型的语⾔环境
(九)项⽬的规范和基础库封装
1. 组件库安装
element 3
- (1)安装:
npm install element3 --save - (2)使用:
// src/main.js import Element3 from 'element3' import 'element3/lib/theme-chalk/index.css' app.use(store).use(Element3).mount('#app')
element plus
2. axios
3. 集成CSS预编译器:sass安装
- (1)安装:
npm install -D sass - (2)使用
<style lang="scss"></style>
5. eslint安装
- 安装:
npm i eslint -D - 初始化文件:
npx eslint --init - 配置:
- 检查eslint规范:
npx eslint src - 注意事项:默认的eslint配置无法检测ts的语法,有些关键字会报错
- ts 关键字报错,解决方式:在eslint的文件中加上
//.eslintrc.js
"extends": [
"eslint:recommended",
"plugin:vue/vue3-essential",
// 解决interface关键字等识别报错的问题
"@vue/typescript-eslint/recommended"
],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module",
// parserOptions.parser配置使用typescript语法插件的parser就可以正确识别项目中.vue文件的ts代码
// 解决interface关键字等识别报错的问题
"parser": "@typescript-eslint/parser"
},
- node关键字报错:如require关键字,process 解决方式:
//.eslintrc.js
"env": {
"browser": true,
"es2021": true,
"node":true,// 启用node中全局变量
},
- husky安装
注意事项:pre-commit文件开头不能乱加其他注释 husky这个库可以很⽅便地帮助我们设置Git的钩⼦函数,可以允许我们在代码提交之前进⾏代码质量的监测- 安装husky:
npm install -D husky - 初始化husky:
npx husky install - 新增commit msg钩⼦,husky会在我们执⾏git commit提交代码的时候执⾏ node scripts/verifyCommit命令来校验commit信息格式:
npx husky add .husky/commit-msg "node scripts/verifyCommit.js"
- 安装husky:
- 然后我们来到项⽬⽬录下的verifyCommit⽂件。在下⾯的代码中,我们先去 .git/COMMIT_EDITMSG⽂件中读取了commit提交的信息,然后使⽤了正则去校验提交信息的格式。如果commit的信息不符合要求,会直接报错并且终⽌代码的提交。
// 1. 我们先去 .git/COMMIT_EDITMSG⽂件中 读取了commit提交的信息
const msg = require('fs').readFileSync('.git/COMMIT_EDITMSG', 'utf-8').trim()
// 2. 然后使⽤正则去校验提交信息的格式
const commitRE = /^(revert: )?(feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip|release)(\(.+\))?: .{1,50}/
const mergeRe = /^(Merge pull request|Merge branch)/
if (!commitRE.test(msg)) {
if (!mergeRe.test(msg)) {
console.log('git commit信息校验不通过')
console.error(`git commit的信息格式不对, 需要使用 title(scope): desc的格式
比如 fix: xxbug
feat(test): add new
具体校验逻辑看 scripts/verifyCommit.js
`)
// 3.如果commit的信息不符合要求,会直接报错并且终⽌代码的提交。
process.exit(1)
}
} else {
console.log('git commit信息校验通过')
}
- commit-msg是代码执⾏提交的时候执⾏的,我们还可以使⽤代码执⾏之前的钩⼦pre-commit去执⾏ESLint代码格式。这样我们在执⾏git commit的同时,就会⾸先进⾏ESLint校验,然后执⾏commit的log信息格式检查:
npx husky add .husky/pre-commit "npm run lint"
(十) 权限管理
-
- 路由守卫:token验证
-
- 角色权限-RBAC管理机制:动态路由
每个⽤⼾有不同的⻆⾊,每个⻆⾊对应不同的⻚⾯权限,这个数据结构的关系设计主要是由后端来实现。
- 角色权限-RBAC管理机制:动态路由
-
- 登录时间限制
(十一) 第三方库
-
- axios
-
- echarts
-
- 指令封装
-
- eslint
(十二)性能优化策略
- ⽹络请求优化
-
- DNS与解析
-
- 图片懒加载
-
- 路由懒加载
-
- 可视化插件报告(rollup-plugin-visualizer)
-
- 代码效率优化
- 例:对斐波那契数列的计算⽽⾔,得到最好性能的⽅式是使⽤数学公式+矩阵来计算
- 用户体验优化
-
- 图片预加载??
-
(十三)打包部署上线
代码部署难点:
- ⾸先是,如何⾼效地利⽤项⽬中的⽂件缓存;
- 然后是,如何能够让整个项⽬的上线部署过程⾃动化,尽可能避免⼈⼒的介⼊,从⽽提⾼上线的稳定性;
- 最后,项⽬上线之后,如果发现有重⼤Bug,我们就要考虑如何尽快回滚代码 采⽤能保证环境⼀致性的Docker;⾃动化构建
自动化部署
- 触发可以通过GitHub Actions;GitHub的actions功能相当于给我们提供了⼀个免费的服务器,可以很⽅便地监控代码的推送、安装依赖、代码编译⾃动上传到服务器。
【进阶开发篇】
(十四)单元测试 jest
(十五)组件封装
1.布局组件封装
2.表单组件封装
3.弹窗组件
这类组件的主要特点是需要渲染在最外层body标签之内,并且还需要⽀持JavaScript动态创建和调⽤组件
4.树形组件
递归
5.表格组件
- 性能优化主要的思路就是如何能够减少计算量。
⽐如我们 的表格如果有1000⾏要显⽰,但是我们浏览器最多只能显⽰100条,其他的需要通过滚动条的⽅式进⾏滚动 显⽰,屏幕之外,成千上万个dom元素就成了性能消耗的主要原因。 - 针对这种情况,我们可以考虑类似图⽚懒加载的⽅案,对屏幕之外的dom元素做懒渲染,也就是⾮常常⻅ 的虚拟列表解决⽅案。
- 在虚拟列表解决⽅案中,我们⾸先要获取窗⼝的⾼度、元素的⾼度以及当前滚动的距离,通过这些数据计算 出当前屏幕显⽰出来的数据。然后创建这些元素标签,设置元素的transform属性模拟滚动效果。
- 这样表⾯ 看是1000条数据在表格⾥显⽰,实际只渲染了屏幕中间的这100⾏数据,当我们滚动⿏标的同时,去维护这 100个数据列表,这样就完成了标签过多的性能问题。
(十六)组件⽂档
vuepress
它是Vue官⽹团队维护的在线技术⽂档⼯具,样式和Vue的官⽅⽂档保持⼀致。
(十七)自定义渲染器
⾸先我们了解了⾃定义渲染器的原理,就是把所有的增删改查操作暴露出去,使⽤的时候不需要知道内部的 把 实现细节,我们只需要针对每个平台使⽤不同的API即可。在Vue渲染器的设计中就把document所有的操作都抽离成了nodeOps,并且通过调⽤Vue的createRenderer函数创建平台的渲染器。
- 1.引入createRenderer
import { createRenderer } from '@vue/runtime-core'; - 2.实现draw函数
这⾥我们就是⽤对应框架(如cavans、three)的操作⽅法,递归地把该对象渲染到对应标签内部 - 3.在createRenderer的insert方法中调用draw函数
- 重写createApp
- 在main.js中引入自己写的createApp
【生态源码篇】
响应式
- Vue3 的组件之间是通过响应式机制来通知的,响应式机制可以⾃动收集系统中数据的依赖,并且在修改数据之后 ⾃动执⾏更新,极⼤提⾼开发的效率。
- 响应式机制的主要功能就是,可以把普通的JavaScript对象封装成为 响 响应式对象,拦截数据的获取和修改操作,实现依赖数据的⾃动化更新 响 。