Vue3框架知识

Vue3

1.diff算法,分两类:

  1. 有key的算法分五部:
    1. 前序对比算法
    2. 尾序对比算法(Vue2还会进行头尾和尾头对比)
    3. 新节点多出来就挂载
    4. 旧节点多出来就是卸载
    5. 特殊情况乱序(dom有移动,需要求新旧子树的最长递增子序列)
      1. 给结点的key值重新排序,比如0:1,1:2,2:3;重新排序后就是2:0,1:1,0:2
      2. 如果有多余的旧节点或新结点不包含旧节点;删除
      3. 如果结点出现交叉,就需要求最长递增子序列,做最小的移动步骤
  2. 无key的算法:
    1. patch(渲染)的时候会逐个替换救VNode
    2. 新增
    3. 删除

ps:无key的算法在第一步时多替换了很多重复的结点,有可能只是删除或新增了dom,但要替换很多次。

2.ref响应式

vue3包含ref,Ref,isRef以及,其中Ref是ref的接口,ref()方法返回一个class,修改其值必须使用ref.value的方式修改。

shadowRef和ref不能写在同一个组合式API里面,因为ref会走triggerRefValue方法,导致依赖更新,即更新视图。

  • shallowRef是浅层响应式
  • triggerRef是强制更新收集的依赖。
  • customRef自定义响应式,需要通过track收集依赖,通过 trigger()触发视图 更新

3. Reactive响应式

reactive底层使用了泛型约束,只支持引用类型,比如Array、Object、Map、Set

  • reactive不能直接赋值,否则会覆盖其本身(proxy对象)
// const list = reactive<string[]>([])
// 上述list只能使用push的方式添加值,如果直接赋值[],则会改变其响应式

4.readonly

给响应式reactive对象套一层readonly,则该readonly对象的属性不可以修改,但可以修改原本reactice对象的值;

let obj = reactive({name:'小满'})
const read = readonly(obj)
obj.name = “xxx” //不报错
read.name = "xxx"	//报错

同样的shadowReactive和reactive一起使用,reactive会触发视图更新,导致shadowReactive非浅层响应。

5. toRef,toRefs,toRaw

toRef(object,key),用于将对象中的某个属性变为响应式解构出来;

  • 底层是调用了ObjectRefImpl,用于将响应式对象的属性值直接返回出来,修改属性值会导致reactive底层更新视图,因此该方法不需要再做一遍。而非响应式对象的属性值返回回来,也不会触发视图收集和更新,因为该方法没有track和trigger方法。

toRefs(objcet) 用于将对象中全部属性转为响应式并解构出来。

toRaw(object)用于将一个响应式对象(proxy)变为非响应式。

6.Vue3响应式原理

7. computed

  1. 选项式写法:传入get和set方法,可以去修改计算属性的值
  2. 函数式写法:传入一个回调函数,不允许修改值

8.Watch

  1. ref属性需要手动开启deep监听,reactive不需要
  2. 监听对象的单一值,需要使用回调函数,否则使用数组
watch(()=>message.bar.foo.name,(newVal,oldVal)=>{
	console.log(newVal.oldVal)
},{
	//deep:true;
	//immediate:true	//立即执行callback
	//flush:"pre"	//pre组件更新之前执行,sync组件更新同步执行,post组件更新之后## 执行
})

9.WatchEffect

该方法不需要显示声明需要监听的值,

//返回一个终止函数
const stop = watchEffect((oninvaildate)=>{
	console.log(message.value)
	oninvalidate(()=>{
		console.log("before")	//该方法会首先执行,一般做防抖节流
	})
},{
	flush:"post"	//在渲染Dom之后获取值
	onTrigger(e){
		debugger
	}
})
const stopWatch = ()=> stop()

10. 生命周期钩子

  1. setup(相当于Vue2的beforeCreated和created函数)
  2. onBeforeMounted(获取不到dom元素)
  3. onMounted(可以获取dom)
  4. onBeforeUpdate
  5. onUpdated
  6. onBeforeUnmount
  7. onUnmounted

(8. onRenderTracked((e)=>{})和onRenderTriggered((e)=>{}),这两个钩子可以用来调试,前者执行依赖收集get,后者执行依赖更新set)

11.bem架构

  1. block-element-modify:比如element-ui:块级元素用短横杠-连接,元素里面的内容用下划线__连接,修饰符用两个短横杠–连接
  2. sass语法:
    1. 定义变量: 定义变量: 定义变量:width:5em(less使用@定义变量)
    2. 插值语句:#{$name},可以使用定义的变量
    3. @mixin混入,@include引入

12 BFC

块级格式化上下文,页面中一个隔离的独立容器,容器内的标签不会影响到容器外的标签;使用BFC可以避免margin塌陷;

触发BFC的方式有:

  1. body根元素
  2. 浮动元素:float除None以外的值
  3. 绝对定位元素:position(absolute、fixed)
  4. display:inline-block 、table-cells、flex
  5. overflow 除 visible以外的值(hidden、auto、scroll)

计算BFC高度时,浮动元素也会参与计算:

当container设置为inlined-block时,内部元素设置为float,此时该container才会显示出来。

13.父子组件传参

父组件给子组件传参:父组件通过:绑定参数,子组件

  • 通过props接受传参,并通过.的方式取值。
const props = defineProps({title:{type:String,default:"默认值"}})
console.log(props.title)	//js中需要通过Props取值,模板中不需要
  • ts泛型字面量(ts特有默认值)
const props = defineProps<{
	title:string,
	arr:number[]
}>()
withDefaults(defineProps<{
	title:string,
	arr:number[]
}>(),{
	arr:{}=>[666]	//需要通过函数返回,防止引用?
})

子组件给父组件传参:

<template>
	<button @click="send">父组件传值</button>
</template>
<script setup lang='ts'>
    const emit = defineEmits(['on-click'])
    const send = () => {
        emit('on-click','小满')
    }
</script>

ts特有方式:

const emit = defineEmits<{
	(e:"on-click",name:string):void
}>()
const send = ()=>{
	emit('on-click','小满')
}

父组件主动读取子组件的值

// 子组件
defineExpose({
	name:"小满",
	open:()=>console.log("1")
})
// 父组件
<son ref="Son"></son>
<script setup lang='ts'>
	import son from './componments/son.vue'
	const son = ref<InstanceType<type of son>()
	console.log(son.value?.name)	//或者son.value.open()调用方法
</script>

14. 组件

局部组件:

通过在页面上import的方式引入局部组件;

全局组件:

在main.ts中引入的组件是全局组件,import之后需要在app.component(‘temp’,temp.vue)注册

递归组件:

在App.vue文件内引入递归组件,并定义递归数组data,写上递归组件的组件名;同时在递归组件内部引用自身(Vue3.3+可以使用defineOption({name:“”})的方式定义别名,或者export default{name:“”}的方式定义别名),并传入子数组的值;

举例:
App.vue:

Tree.vue
在这里插入图片描述

15.可选链操作符,双问号表达式

a.children?.length?.xxx	//不管后面带多少属性,没有的话就返回undefined;
a.children?.length?.xxx ?? [] //在undefined或者null的时候会返回双问号后面的值,但0和false不做处理

16. 动态组件

<component :is="comId"></component>	//该方式比v-if来说,会保留之前的渲染状态,而v-if会销毁后重新创建
  1. 使用import引入对象的方式(性能较优)
import Avue from 'xxx'
const comId = shallowRef(AVue)	//只需要跟踪到.vue,不需要劫持组件的其他属性,性能优化
  1. 使用选项式API的方式,此时上述AVue使用字符串的形式即可。
   components:{
   	AVue,BVue,CVue
}

17. 插槽

父组件使用

<template v-slot>	//匿名插槽
	<div>xxx<div>
</template>

<template v-slot:header>	//具名插槽,子组件需要定义name
	<div>header<div>
</template>

<template #default>	//简写形式
	<div>xxx<div>
</template>

<template #header>	//具名插槽简写
	<div>header<div>
</template>

<template v-slot=“{data}”>	//接受子组件传过来的值
	<div>xxx<div>
</template>
--------------------------------------------------------------------
<template #[name]>	//动态插槽
	<div>xxx<div>
</template>

<script>
	let name = ref('header')
</script>

子组件

<slot name="header" :data="data"></slot>

18.顶层await技术

​ ES7之后可以在script的顶层写await,此时下方所有的请求都会变成异步的。

19. 异步组件

异步组件必须在App.vue中使用<Suspense></Suspense>标签去引入,包含default和fallback插槽,后者是加载的时候显示的内容,前者是加载完成后显示的内容。使用该方式的话,异步组件不会被打包进主包里,而是单独一个js和css文件。

异步组件在script标签里使用defineAsyncCompomponent(()=>import(url))的方式去引入,必须使用import函数式的方式去引入。

20.Teleport传送组件

可以把包裹的内容传送到指定标签的位置,比如body,可以让absolute属性相对于Body定位而不是父relative标签

<Teleport to="body">
	<A></A>
</Teleport>

21. keep-alive

包裹在keep-alive中的组件不会被销毁,而是会记录其状态。比如在表单中需要保留用户输入的内容。

  • include属性,接受一个数组,可以只保留某个组件的状态

  • exclude属性,接受一个数组,不保留某个组件的状态

  • max属性,接受一个number,会使用LRU算法剔除不常用的组件

  • 新增两个生命周期onActivated和onDeactivated,分别是keep-alive组件的初始化和卸载

22. transition组件

Vue3内置组件,需写上name属性

  • .name-enter-from:元素开始的状态
  • .name-enter-active:元素变换时的状态,比如transition:all 1.5s ease;
  • .name-enter-to:元素结束的状态
  • .name-leave-from:离开时的状态
  • .name-leave-active
  • .name-leave-to: 元素离开到达的位置

某个组件的状态

  • max属性,接受一个number,会使用LRU算法剔除不常用的组件

  • 新增两个生命周期onActivated和onDeactivated,分别是keep-alive组件的初始化和卸载

22. transition组件

Vue3内置组件,需写上name属性

  • .name-enter-from:元素开始的状态
  • .name-enter-active:元素变换时的状态,比如transition:all 1.5s ease;
  • .name-enter-to:元素结束的状态
  • .name-leave-from:离开时的状态
  • .name-leave-active
  • .name-leave-to: 元素离开到达的位置
  • 50
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值