这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战
静态节点标记
vue2.0:编译模板阶段的时候对静态节点进行标记,diff算法虚拟DOM和真实DOM进行对比时也过滤静态节点。
vue3.0:编译模板阶段将静态节点和动态节点分开存放,diff算法数据变更时只需要对比动态节点。
另:
1. Vue 3 的 Template 支持多个根标签,Vue 2 不支持
2. Vue 3 有 createApp(),而 Vue 2 的是 new Vue()\
createApp(组件),new Vue({template, render})
3. v-model代替以前的v-model和.sync\
vue3中v-model的用法:
3.1. props属性名任意,假设为x\
3.2. 事件名必须为"update:x"\
示例:
<Switch :value="y" @update:value="y=$event"/>
vue2中的写法
<Switch :value.sync="y"/>
vue3中的写法
<Switch v-model:value="y"/>
4. context.emit
vue3新增了context.emit,和vue2中的this.$emit(但是vue3中只能在methods里使用)作用相同 示例:
import {SetupContext } from 'vue'
setup(props: Prop, context: SetupContext) {
const toggle = () => { context.emit('input', !props.value) } return {toggle} }
5. Vue3中的属性绑定
默认所有属性都绑定到根元素
使用inheritAttrs: false可以取消默认绑定
使用attrs或者context.attrs获取所有属性
使用v-bing="$attrs"批量绑定属性
使用 const {size, level, ...rest} = context.attrs 将属性分开
5.1 使用场景
在vue2中我们在父组件绑定click事件,子组件必须内部触发click,而vue3中在父组件绑定子组件的根元素上也会跟着绑定
- ButtonDemo.vues示例:
<div>
<Button @click="onClick" @focus="onClick" size="small">你好</Button>
</div>
setup() {
const onClick = () => {
console.log("aaa")
}
return {onClick}
}
- Button.vue
<template>
<div>
<button>
<slot/>
</button>
</div>
</template>
上面的代码Button的click事件会在根元素div上绑定,如果我们要指定click的区域为button元素的话我们就需要使用inheritAttrs
- Button.vue
<template>
<div>
<button v-bind="$attrs">
<slot/>
</button>
</div>
</template>
<script lang="ts">
export default {
inheritAttrs: false
}
</script>
如果想要一部分属性绑定在button上一部分在div上就需要在setup里
- Button.vue
<template>
<div :size="size"> <button v-bind="rest">
<slot/>
</button>
</div>
</template>
<script lang="ts">
import {SetupContext} from 'vue'
export default {
inheritAttrs: false,
setup(props: any, context:SetupContext ) {
const {size, ...rest} = context.attrs
return {size, rest} }
}
</script>
5.2. props和context.attrs的区别
- props要现在当前组件props属性里声明才能取值,attrs不用先声明
①:
expory default {
inheritAttrs: false,
setup(props:amy, context:SetupContext){
** console.log({...props})**
const{size,...rest} = context.attrs
return {size, rest}
}
}
②:
export default {
inheritAttrs: false,
props:{
**size: String**
}
}
①中因为没有声明props所以是空对象,②中声明了size,所以只得到了size
- props不包含事件,attrs包含
我们没有办法在props里声明click这一类的事件 - props没有声明的属性,会跑到attrs里
props:{
size:String
}
setup(props:any,context:SetupComntext){
console.log({...props},'props')
console.log({...context.attrs},'attr')
const {size,...rest} = context.attrs
return {size,rest}
}
上面,我们在props里声明了size,所以attrs里就没有size了
当我们在html标签中只写属性而不赋值的时候,props支持string以外的类型,attrs只有string类型
6.slot具名插槽的使用
vue2中的用法
子组件
<slot name="title">
父组件
<template slot="title">
<h1>哈哈哈</h1>
</template>
vue3中子组件用法不变,父组件需要使用
v-slot:插槽名
父组件
<template v-slot:title>
<h1>哈哈哈</h1>
</template>