vue3 基础概念 (含与 vue2.6 的对比)

vue3 特点

  1. vue3 支持 vue2 的大多数特性
  2. 性能提升:
    打包大小减少41%
    初次渲染快55%,更新快133%
    内存使用减少54%
  3. Composition API
    ref 和 reactive
    computed 和 watch
    新的生命周期函数
    自定义函数——Hooks 函数
  4. 其他新增特性
    Teleport——瞬移组建的位置
    Suspense——异步加载组件的新福音
    全局 API 的修改和优化
    更多的试验性特性
  5. 更好的 Typescript 支持

为什么要有 vue3

  1. vue2 遇到的难题:同一逻辑分类的代码分散,不利于维护。
  2. mixins 难点:命名冲突、不清楚暴露出来变量的作用、组件复用时会遇到问题
  3. vue2 对于 typescript 的支持非常有限

应用和组件

  • 创建应用:

    • vue3:
    const app = Vue.createApp({})
    app.component('SearchInput', SearchInputComponent)
    app.directive('focus', FocusDirective)
    app.use(LocalePlugin)
    app.mount('#app')
    
    // 或
    Vue.createApp({})
     .component('SearchInput', SearchInputComponent)
     .directive('focus', FocusDirective)
     .use(LocalePlugin)
     .mount('#app')
    
    • vue2:
    new Vue({
      el: '#app',
      data: obj
    })
    
  • 组件是可复用的 Vue 实例,且带有一个名字,如 。我们可以在一个通过 new Vue 创建的 Vue 根实例中,把这个组件作为自定义元素来使用。

生命周期钩子函数

vue3 基础概念 (含与 vue2.6 的对比)_第1张图片
vue3 Lifecycle Hooks
vue3 基础概念 (含与 vue2.6 的对比)_第2张图片
vue2 Lifecycle Hooks
// 主要区别在于销毁时
beforeCreate() { console.log('实例刚刚被创建') },
created() { console.log('实例创建完成') },
beforeMount() { console.log('实例挂载之前') },
// 请求数据,操作dom , 放在这个里面
mounted() { console.log('实例挂载完成') },
// 数据更新时,虚拟 DOM 变化之前调用,这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
beforeUpdate() { console.log('数据更新之前') },
// 数据更新和虚拟 DOM 变化之后调用。请不要在此函数中更改状态,否则会触发死循环。
updated() { console.log('数据更新完毕') },

// vue3:
// 实例销毁之前调用,在这一步,实例仍然完全可用。一般在这里移除事件监听器、定时器等,避免内存泄漏
beforeUnmount() { console.log('实例销毁之前') },
// Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑,所有的事件监听器会被移除,所有的子实例也会被销毁。
unmounted() { console.log('实例销毁完成') },

// vue2:
beforeDestroy() { console.log('实例销毁之前') },
destroyed() { console.log('实例销毁完成') },

不要在选项 property 、回调上或生命周期函数上使用箭头函数,比如 created: () => console.log(this.a)vm.$watch('a', newValue => this.myMethod())
因为箭头函数并没有 thisthis 会作为变量一直向上级词法作用域查找,直至找到为止。经常导致 Uncaught TypeError: Cannot read property of undefinedUncaught TypeError: this.myMethod is not a function 之类的错误。

不常用模板语法

  • v-once 指令:执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定:

  • 动态参数(2.6.0 新增):
    ...
    ...

    • 对动态参数表达式的约束:
      1、动态参数表达式有一些语法约束,因为某些字符,如空格和引号,放在 HTML attribute 名里是无效的。例如:

      
       ... 
      

      变通的办法是使用没有空格或引号的表达式,或用计算属性替代这种复杂表达式。

      2、在 DOM 中使用模板时 (直接在一个 HTML 文件里撰写模板),还需要避免使用大写字符来命名键名,因为浏览器会把 attribute 名全部强制转为小写:

      
       ... 
      

      动态参数预期会求出一个字符串,异常情况下值为 null。这个特殊的 null 值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告。

计算属性和侦听器

计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
通常更好的做法是使用计算属性而不是命令式的 watch 回调。

Class 与 Style 绑定

  • 自动添加前缀
    v-bind:style 使用需要添加浏览器引擎前缀的 CSS property 时,如 transformVue.js 会自动侦测并添加相应的前缀。

  • 多重值
    2.3.0 起你可以为 style 绑定中的 property 提供一个包含多个值的数组,常用于提供多个带前缀的值,如:


    这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex

条件渲染

  • key 管理可复用的元素
    Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。
    这样也不总是符合实际需求,所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key 即可。

  • v-if vs v-show
    1、v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
    2、v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
    3、相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
    4、一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

    注意,v-show 不支持