vue2 和 vue3 使用区别

1,677 阅读3分钟

参考文章:mp.weixin.qq.com/s/B7n_dLC9r…

1、自定义指令

vue2用法

vue2中使用的钩子如下:

  • bind - 指令绑定到元素后发生。只发生一次。
  • inserted - 元素插入父 DOM 后发生。
  • update - 当元素更新,但子元素尚未更新时,将调用此钩子。
  • componentUpdated - 一旦组件和子级被更新,就会调用这个钩子。
  • unbind - 一旦指令被移除,就会调用这个钩子。也只调用一次。
<p v-highlight="'yellow'">高亮显示此文本亮黄色</p>

Vue.directive('highlight', {
  bind(el, binding, vnode) {
    el.style.background = binding.value
  }
})

vue3用法

vue3中使用的钩子如下:

  • created - 新的!在元素的 attribute 或事件侦听器应用之前调用。
  • bind → beforeMount
  • inserted → mounted
  • beforeUpdate:新的!这是在元素本身更新之前调用的,很像组件生命周期钩子。
  • update → 移除!有太多的相似之处要更新,所以这是多余的,请改用 updated。
  • componentUpdated → updated
  • beforeUnmount:新的!与组件生命周期钩子类似,它将在卸载元素之前调用。
  • unbind -> unmounted
<p v-highlight="'yellow'">高亮显示此文本亮黄色</p>

const app = Vue.createApp({})
app.directive('highlight', {
  beforeMount(el, binding, vnode) {
    el.style.background = binding.value
  }
})

2、过滤器

vue2用法

<template>
  <h1>Bank Account Balance</h1>
  <p>{{ accountBalance | currencyUSD }}</p>
</template>

<script>
  export default {
    props: {
      accountBalance: {
        type: Number,
        required: true
      }
    },
    filters: {
      currencyUSD(value) {
        return '$' + value
      }
    }
  }
</script>

vue3用法

在vue3中过滤器已经废弃,建议使用方法调用或计算属性computed

<template>
  <h1>Bank Account Balance</h1>
  <p>{{ accountInUSD }}</p>
</template>

<script>
  export default {
    props: {
      accountBalance: {
        type: Number,
        required: true
      }
    },
    computed: {
      accountInUSD() {
        return '$' + this.accountBalance
      }
    }
  }
</script>

全局属性定义

// main.js
const app = createApp(App)
//定义
app.config.globalProperties.$filters = {
  currencyUSD(value) {
    return '$' + value
  }
}

//使用
<template>
  <h1>Bank Account Balance</h1>
  <p>{{ $filters.currencyUSD(accountBalance) }}</p>
</template>

注意: 这种方式只能用于方法中,不可以在计算属性中使用,因为后者只有在单个组件的上下文中定义时才有意义。

3、片段

vue2用法

vue2中不支持多根节点组件

<template>
  <div>
    <header>...</header>
    <main>...</main>
    <footer>...</footer>
  </div>
</template>

vue3用法

vue3中支持多根节点组件:

<template>
  <header>...</header>
  <main v-bind="$attrs">...</main>
  <footer>...</footer>
</template>

4、v-if 与 v-for 的优先级

vue2中

在一个元素上同时使用 v-if 和 v-for 时,v-for 会优先作用

vue3中

v-if 总是优先于 v-for 生效

5、插槽

子组件

<slot name="content" :data="data"></slot>
export default {
    data(){
        return{
            data:["走过来人来人往","不喜欢也得欣赏","陪伴是最长情的告白"]
        }
    }
}

vue2中

<!-- 父组件中使用 -->
<template slot="content" slot-scope="scoped">
   <div v-for="item in scoped.data">{{item}}</div>
</template>

vue3中

<!-- 父组件中使用 -->
<template v-slot:content="scoped">
   <div v-for="item in scoped.data">{{item}}</div>
</template>

<!-- 也可以简写成: -->
<template #content="{data}">
    <div v-for="item in data">{{item}}</div>
</template>

6、v-model

vue2中

组件上使用 v-model其实就相当于传递了value属性, 并触发了input事件

<search-input v-model="searchValue"><search-input>

<!-- 相当于 -->
<search-input :value="searchValue" @input="searchValue=$event"><search-input>

vue3中

组件上使用 v-model其实就相当于传递一个modelValue 属性, 同时触发一个update:modelValue事件,而且同一个组件可以同时使用多个v-model

<modal v-model:visible="isVisible" v-model:content="content"></modal>

<!-- 相当于 -->
<modal :visible="isVisible" :content="content" @update:visible="isVisible" @update:content="content"/>

7、watch

vue2中

watch:{
    person: {
      handler(newVal,oldVal) {
      // ...
      },
      deep: true,
      immediate: true
    }
}

vue3中

用法:watch(source, callback, [options])

参数说明:

  • source: 可以支持 string,Object,Function,Array; 用于指定要侦听的响应式变量
  • callback: 执行的回调函数
  • options:支持 deep、immediate 和 flush 选项。
watch(
  () => state.person,
  (newVal, oldVal) => {
    console.log("新值:", newVal, "老值:", oldVal);
  },
  { deep: true }
);

8、生命周期

640 (1).png

640.png

9、数据建立 data

vue2中

export default {
  props: {
    strProp: String
  },
  data () {
    return {
      value1: '',
      value2: ''
    }
  }
}

vue3中

import { reactive } from 'vue'

export default {
  props: {
    strProp: String
  },
  setup (props,{emit,attrs,slot}) {
    const state = reactive({
      value1: '',
      value2: ''
    })

    return { state }
  }
}

使用setup时,它接受两个参数:

props: 组件传入的属性

context:包含三个属性attrs、slot 和emit

setup 中接受的props是响应式的, 当传入新的 props 时,会及时被更新。由于是响应式的, 所以 不可以使用 ES6 解构,解决办法就是使用toRefs 。toRefs 用于将一个 reactive 对象转化为属性全部为 ref 对象的普通对象(reactive用于处理对象的双向绑定,ref则既可以处理对象也可以处理基础类型的双向绑定)。setup中不能访问 Vue2 中最常用的this对象,解构会消除它的响应式,所以context中就提供了this中最常用的三个属性: attrs、slot 和emit

ref、toRef、toRefs的区别:

ref 就当作简单的响应式变量 toRef 就是把不是响应式的对象转化成响应式 toRefs 就是把响应式的reactive对象,分解成无数的响应式 ref

 setup() {
    const obj = ref({count:1, name:"张三"});//ref处理对象
    setTimeout(() =>{
        obj.value.count = obj.value.count + 1;
        obj.value.name = "李四";
    }, 1000)
    return{obj}
 }
 
 setup() {
    const year = ref(0);//ref处理基础类型
    const user = reactive({ nickname: "xiaofan", age: 26, gender: "女" });//reactive处理对象
    return {year,user};
  },
  
 // 使用toRefs
 setup() {
    const year = ref(0);
    const user = reactive({ nickname: "xiaofan", age: 26, gender: "女" });
    return {year,...toRefs(user)};//使用toRefs处理reactive对象为 ref 对象
  },