vue2.0与3.0的差异(2)

555 阅读2分钟

这是我参与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>