vue3篇

一. 创建vue3项目

  1. 使用vue-cli脚手架创建
    • 安装vue-cli要求脚手架版本必须大于4.5
      • yarn global add @vue/cli
      • npm install -g @vue/cli
    • 创建vue3项目:vue create my-project
  2. 使用vite安装并指定模板
    • npm create vite@latest my-vue-app --template vue
    • yarn create vite my-vue-app --template vue
  3. 直接安装(默认基于vite构建),根据提示安装需要的依赖
    • npm init vue@latest
  4. 建议使用时方法三。
  5. 具体安装方法可以参考

二. 生命周期

  1. 创建前:beforeCreate -> 使用setup()
  2. 创建后:created -> 使用setup()
  3. 挂载前:beforeMount -> onBeforeMount
  4. 挂载后:mounted -> onMounted
  5. 更新前:beforeUpdate -> onBeforeUpdate
  6. 更新后:updated -> onUpdated
  7. 销毁前:beforeDestroy -> onBeforeUnmount
  8. 销毁后:destroyed -> onUnmounted
  9. 异常捕获:errorCaptured -> onErrorCaptured
  10. 被激活:onActivated 被包含在中的组件,会多出两个生命周期钩子函数。被激活时执行。
  11. 切换:onDeactivated 比如从 A 组件,切换到 B 组件,A 组件消失时执行

三. 组合式API和选项式API

  1. options Api在vue2中使用的。将每一个功能写到对应的Api下。当逻辑复杂的时候这种写法不利于代码阅读和代码维护。
  2. composition Api在vue3中使用。将每一个功能独立完整的写在setup(){}里面,有利于代码阅读和维护

四.ref响应式数据

  1. 作用:定义一个响应式数据
  2. 语法:const xxx = ref<数据类型:string|number> = (1)
  3. 操作:xxx.value
  4. 使用:在模板中不需要使用.value 可以直接使用
  5. 备注:可以定义基本数据类型也可以定义复杂数据类型例如对象
    • 基本数据类型:响应式的原理依然是通过Object.definedProperty()的get()和set()来做数据劫持和数据更新。
    • 复杂数据类型:内部求助reactive通过Proxy代理实现

五. reactive响应式数据

  1. 作用:定义一个复杂类型的响应式数据,例如对象
  2. 语法: const xxx = reactive<数据类型> = ({})
  3. 操作:直接读取不需要.value
  4. 备注:通过Proxy代理对象对源对象数据进行操作,是深层次的

六.响应式原理

  1. vue2通过Object.definedProperty()的get()和set()来做数据劫持、结合和发布订阅者模式来实现。
  2. vue3通过proxy的方式实现
  3. proxy的优势:不需要像Object.definedProperty()的那样遍历每一个属性,有一定的性能提升
    proxy可以理解为在目标对象之前架设一层“拦截”,外界对该对象的访问都必须通过这一层拦截。这个拦截可以对外界的访问进行过滤和改写。
  4. 当属性过多的时候利用Object.definedProperty()要通过遍历的方式监听每一个属性。利用proxy则不需要遍历,会自动监听所有属性,有利于性能的提升

七. watch监听

  1. 监听一个ref属性:
watch(a,(newValue,oldValue)=>{
    
    },immediate:true,deep:true) // 得到的newValue和oldValue是一个值

在这里插入图片描述

  1. 监听多个ref属性:
watch([a,b,c,...],(newValue,oldValue)=>{
    
    },immediate:true,deep:true)  // 得到的newValue和oldValue是一个数组

在这里插入图片描述

  1. 监听一个reactive里面的某一属性:
watch(()=>a.name,(newValue,oldValue)=>{
    
    })

在这里插入图片描述

  1. 监听一个reactive里面的某一些属性:
watch([()=>a.name,()=>a.age],(newValue,oldValue)=>{
    
    })

在这里插入图片描述

  1. 监听一个reactive里面的所有属性:
watch(a,(newValue,oldValue)=>{
    
    })
// 无法获取oldValue
// 强制开启了深度监听(deep配置无效)

在这里插入图片描述

  1. 同时监听ref和reactive数据:
watch([a,()=>a.age],(newValue,oldValue)=>{
    
    })

在这里插入图片描述

  1. 特殊情况:
watch(()=>a.job,(newValue,oldValue)=>{
    
    },deep:true)  
// job是一个复杂对象必须开启深度监听,无法获取oldValue
// 如果直接监听一个对象不需要开启深度监听
// 如果是用箭头函数形式则必须开启

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

八. watchEffect监听

  1. 说明:不用指定哪个属性,在函数体中使用了哪个属性,就是监听了哪一个属性。
  2. 和watch的区别
    • 不需要手动传入依赖
    • 立即执行,每次初始化的时候都会执行一次回调函数来自动获取依赖
    • 无法获取到原来的值,只能得到变化后的值
  3. 语法:watchEffect((newValue)=>{})
    在这里插入图片描述
watchEffect(() => {
    
    
  userInfo.value = user.name + user.more.age;  // 可以看到上图中watchEffect实现了对name和age的监听
});

九. toRef和toRefs

  1. 作用:可以用来复制reactive里面的属性然后转成ref,既保留了响应式也保留了引用。也就是你从 reactive 复制过来的属性进行修改后,除了视图会更新,原有 ractive 里面对应的值也会跟着更新。
  2. toRef:复制 reactive 里的单个属性并转成 ref
  3. toRefs: 复制 reactive 里的所有属性并转成 ref
  4. 使用
// toRef的使用
<template>
	// toRef的使用
	<h1>{
    
    {
    
    username}}</h1>
	// toRef的使用
	<h1>{
    
    {
    
    age}}</h1>
</template>
<script setup>
  	import {
    
    reactive,toRef,toRefs} from 'vue'
	const info = reactive({
    
    
		name:'wangjiajia',
		age:'25'
	})
	// toRef的使用
	const username = toRef(info,'name')

	// toRefs的使用
	const {
    
    name,age} = toRefs(info)
</script>
  1. 总结
    • 使用toRef()解构出来的是对象中的某一个属性,可以在template中直接使用不用加.value。
    • 使用toRefs()是将整个对象解构,必须加上...,这样在template中就可以直接使用不用加.value。

十. shallowReactive 和 shallowRef

  1. 作用:做数据响应式性能优化的
  2. shallowReactive:只处理对象最外层的响应(浅层响应)
  3. shallowRef:只处理基本数据类型的响应式, 不进行对象的响应式处理。
  4. 使用条件:
    • 如果有一个对象类型数据,结构比较深,但变化时只是外层属性变化使用shallowReactive。
    • 如果有一个对象类型数据,不希望他是响应式,使用shallowRef
  5. 例如:
// shallowReactive的使用
const userInfo = shallowReactive({
    
       // 只将第一层数据做了响应式处理 
	name:'wangjiajia',
	age:25,
	like:{
    
    
		food:{
    
    
			apple:'橙子'    // 深层次的数据将会是一个普通的对象
		}
	}
})

// shallowRef的使用
const userInfo = shallowRef({
    
       // userInfo将不在是一个响应式对象
	name:'wangjiajia'
}) 

十一. readonly 和 shallowReadonly

  • readonly:让一个响应式数据变为只读的。(深层次)
  • shallowReadonly:让一个响应式数据变为只读的。(浅层次)
  • 应用场景:不希望数据被修改
let person=reactive({
    
    
    name:'张三',
    age:18,
    job:{
    
    
        j1:{
    
    
            salary:20
		}
	}
})
person = readonly(person)   // person里面的所有属性都不可以被修改
person = shallowReadonly(person)   // person里面只有第一层属性不可以被修改

十二. toRaw 和 markRaw

  1. toRaw:
    • 作用:将一个reactive生成的响应式数据转为普通对象
    • 使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作不会引起页面更新
  2. markRaw:
    • 标记一个对象使其永远不会成为响应式
    • 应用场景:
      • 有些值不应该被设为响应式的。例如一些复杂的第三方库
      • 当渲染具有不可变数据源的大列表时候,跳过响应式可以提高性能
  3. markRaw和readonly的区别
    • markRaw标记一个对象使其永远不会成为响应式
    • readonly禁止对值得修改,响应式本身还存在。

十三. 响应式数据的判断

  1. isRef(): 检查一个值是否为ref对象,返回true/false
  2. isReactive:检查一个对象是否为reactive对象,返回true/false
  3. isReadonly:检查一个对象是否是由readonly创建的只读属性
  4. isProxy:检查一个对象是否是proxy对象

十四. provide 和 inject

关于组件之间的通信回头重点讲一下

十五. vue3路由跳转(编程式和声明式)

  1. 声明式:<router-link :to="{name:'',query:{}}">
  2. 编程式:
    import { useRouter } from ‘vue-router’;
    const router = useRouter();
    • 不带参数:
      • router.push(‘/home’)
      • router.push({name:‘home’})
      • router.push({path:‘/home’})
    • 带参数 ---- query传参
      • router.push(name:‘home’,query:{id:1})
      • router.push(path:‘/home’,query:{id:1})
    • 带参数 ---- params传参
      • router.push(name:‘home’,params:{id:1})
    • 说明:query传参既可以用name也可以用path。跳转之后会拼接参数。params传参只能用name,跳转之后不会拼接参数。所以说query传参没有params传参安全。
    • vue2路由跳转用this.$router.push就行剩下的参数内容和vue3一样

十六. vue3性能提升主要通过哪几个方面体现的

  1. 响应式系统
  2. 源码体积:通过在源码中加入了tree sharking是什么,项目打包体积变小了。模块按需加载
  3. 编译阶段
    • diff算法不同,vue2是遍历每一个DOM节点。vue3是给每一个节点先做标记,只遍历标记变化的节点
    • 静态提升:在vue3中对于不参与更新的元素会做静态提升,只会被创建一次,下一次直接使用,而不需要重新渲染
    • 开启事件监听缓存
    • SSR(服务器渲染)优化,当静态内容大到一定程度的时候,会生成一个static node这些静态node,会被直接innerHtml,就不需要创建对象,然后根据对象渲染

十七. vue3的设计目标

  1. 更小:按需加载,具有更小的打包体积
  2. 更快:diff算法,静态提升,开启事件监听缓存,性能优化
  3. 更友好:源码是通过monorepo(一种整合代码的微前端技术)方式维护的
    • composition Apimonorepo
    • 更好地ts支持

十八. vue3里面的setup

十九. 父组件和子组件的生命周期顺序

  1. 在setup中执行生命周期和外部的生命周期函数相比,会优先指向setup内的生命周期函数,再去执行外部的生命周期函数。
  2. 总体顺序如下:
    • 父setup
    • 父onBeforeMount
    • 子setup
    • 子onBeforeMount
    • 子onMounted
    • 父onMounted
    • 父onBeforeUpdate
    • 子onBeforeUpdate
    • 子onUpdated
    • 父onUpdated
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

二十. vue3的组件通信方式

  • props / emit
  • v-model
  • provide/inject
  • refs
  • eventBus
  • vuex/pinia
  1. props / emit
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  2. v-model:双向绑定,props + emit('update:xxx',xxx)
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述

  3. provide/inject

    • 是 Vue 中提供的一对 API。
    • 无论层级多深,API 都可以实现父组件到子孙组件的数据传递。
    • 只能用于父组件向后代组件传值。
    • 使用 provide 进行数据传输时,尽量使用 readonly 封装数据,避免子组件修改父组件传递的数据。
    • 使用provide传过去的值一定要是proxy进行过代理的或者计算属性
      • 例如:provide('listData', computed(() => state.listData))
      • provide('listData', toRef(state.listData))
        在这里插入图片描述
        在这里插入图片描述
  4. ref:ref + defineExpose({})
    在这里插入图片描述
    在这里插入图片描述

  5. eventBus:Vue 3 中移除了 eventBus,但可以借助第三方工具来完成。Vue 官方推荐使用 mitt 或 tiny-emitter,在大多数情况下,不建议使用全局事件总线来实现组件通信。虽然比较简单粗暴,但是维护事件总线从长远来看是个大问题,这里就不解释了。
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
6. vuex / pinia:全局数据共享

猜你喜欢

转载自blog.csdn.net/du_aitiantian/article/details/128846763