vue3全家桶 学习笔记

253 阅读10分钟

【基础入门篇】

(一)环境准备

  • node:16.12.1(node版本需14.0.0以上)
  • 项目搭建
  • 创建⼀个Vite的初始化项⽬:npm init vite
  • 选择模板 image.png

(二)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对象的解构取值,解构出来的值也是响应式的

image.png

  • 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 image.png
  • 子传父:defineEmits image.png
  • 暴露方法:defineExports
    • 使用场景:如表单的验证、重置方法 image.png

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的响应式

image.png

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定义了监听的函数,最终实现了组件和外部数据之间的同步。
image.png

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。 image.png
<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 image.png
  • 配置:image.png
  • 检查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中全局变量
},
  1. 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"
  • 然后我们来到项⽬⽬录下的verifyCommit⽂件。在下⾯的代码中,我们先去 .git/COMMIT_EDITMSG⽂件中读取了commit提交的信息,然后使⽤了正则去校验提交信息的格式。如果commit的信息不符合要求,会直接报错并且终⽌代码的提交。 image.png image.png
// 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"

(十) 权限管理

    1. 路由守卫:token验证
    1. 角色权限-RBAC管理机制:动态路由
      每个⽤⼾有不同的⻆⾊,每个⻆⾊对应不同的⻚⾯权限,这个数据结构的关系设计主要是由后端来实现。
    1. 登录时间限制

(十一) 第三方库

    1. axios
    1. echarts
    1. 指令封装
    1. eslint

(十二)性能优化策略

  • ⽹络请求优化
      1. DNS与解析
      1. 图片懒加载
      1. 路由懒加载
      1. 可视化插件报告(rollup-plugin-visualizer)
  • 代码效率优化
    • 例:对斐波那契数列的计算⽽⾔,得到最好性能的⽅式是使⽤数学公式+矩阵来计算
  • 用户体验优化

(十三)打包部署上线

image.png 代码部署难点:

  • ⾸先是,如何⾼效地利⽤项⽬中的⽂件缓存
  • 然后是,如何能够让整个项⽬的上线部署过程⾃动化,尽可能避免⼈⼒的介⼊,从⽽提⾼上线的稳定性;
  • 最后,项⽬上线之后,如果发现有重⼤Bug,我们就要考虑如何尽快回滚代码 采⽤能保证环境⼀致性的Docker;⾃动化构建

自动化部署

image.png

  • 触发可以通过GitHub Actions;GitHub的actions功能相当于给我们提供了⼀个免费的服务器,可以很⽅便地监控代码的推送、安装依赖、代码编译⾃动上传到服务器。

【进阶开发篇】

(十四)单元测试 jest

(十五)组件封装

课程项目源码

1.布局组件封装

2.表单组件封装

3.弹窗组件

这类组件的主要特点是需要渲染在最外层body标签之内,并且还需要⽀持JavaScript动态创建和调⽤组件

4.树形组件

递归

5.表格组件

  • 性能优化主要的思路就是如何能够减少计算量
    ⽐如我们 的表格如果有1000⾏要显⽰,但是我们浏览器最多只能显⽰100条,其他的需要通过滚动条的⽅式进⾏滚动 显⽰,屏幕之外,成千上万个dom元素就成了性能消耗的主要原因。
  • 针对这种情况,我们可以考虑类似图⽚懒加载的⽅案,对屏幕之外的dom元素做懒渲染,也就是⾮常常⻅ 的虚拟列表解决⽅案
  • 在虚拟列表解决⽅案中,我们⾸先要获取窗⼝的⾼度、元素的⾼度以及当前滚动的距离,通过这些数据计算 出当前屏幕显⽰出来的数据。然后创建这些元素标签,设置元素的transform属性模拟滚动效果。
  • 这样表⾯ 看是1000条数据在表格⾥显⽰,实际只渲染了屏幕中间的这100⾏数据,当我们滚动⿏标的同时,去维护这 100个数据列表,这样就完成了标签过多的性能问题。

(十六)组件⽂档

vuepress

它是Vue官⽹团队维护的在线技术⽂档⼯具,样式和Vue的官⽅⽂档保持⼀致。

(十七)自定义渲染器

代码:github.com/1628415507/…

⾸先我们了解了⾃定义渲染器的原理,就是把所有的增删改查操作暴露出去,使⽤的时候不需要知道内部的 把 实现细节,我们只需要针对每个平台使⽤不同的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对象封装成为 响 响应式对象,拦截数据的获取和修改操作,实现依赖数据的⾃动化更新 响 。