2021-09-16 vue3文档阅读笔记

今天有空就把vue3文档从头到尾看了一遍。就当做对vue从头开始的学习和补漏,理解了一些用法改变的原理。最明显的地方就是响应式的改变,vue2用的是Object.defineProperty(),vue3用的是Proxy。vue3还新增了组合式API等等。
这次记录主要是记录一些基础的,面试常被问到的,查漏补缺。

应用&组件实例

应用实例

每个 Vue 应用都是通过用 createApp 函数创建一个新的应用实例开始的:

const app = Vue.createApp({ /* 选项 */ })

该应用实例是用来在应用中注册“全局”组件的。我们将在后面的指南中详细讨论,简单的例子:

const app = Vue.createApp({})
app.component('SearchInput', SearchInputComponent)
app.directive('focus', FocusDirective)
app.use(LocalePlugin)

应用实例暴露的大多数方法都会返回该同一实例,允许链式:

Vue.createApp({})
  .component('SearchInput', SearchInputComponent)
  .directive('focus', FocusDirective)
  .use(LocalePlugin)

根组件实例

传递给 createApp 的选项用于配置根组件。当我们挂载应用时,该组件被用作渲染的起点。

一个应用需要被挂载到一个 DOM 元素中。例如,如果我们想把一个 Vue 应用挂载到

,我们应该传递 #app

const RootComponent = { /* 选项 */ }
const app = Vue.createApp(RootComponent)
const vm = app.mount('#app')

与大多数应用方法不同的是,mount 不返回应用本身。相反,它返回的是根组件实例

虽然没有完全遵循 MVVM 模型,但是 Vue 的设计也受到了它的启发。因此在文档中经常会使用 vm (ViewModel 的缩写) 这个变量名表示组件实例。

计算属性&侦听器

计算属性缓存 vs 方法

你可能已经注意到我们可以通过在表达式中调用方法来达到同样的效果:

{{ calculateBooksMessage() }}

// 在组件中
methods: {
  calculateBooksMessage() {
    return this.author.books.length > 0 ? 'Yes' : 'No'
  }
}

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的反应依赖关系缓存的。计算属性只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要author.books 还没有发生改变,多次访问 publishedBookMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

这也同样意味着下面的计算属性将不再更新,因为 Date.now () 不是响应式依赖

computed: {
  now() {
    return Date.now()
  }
}

相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 list,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于
list。如果没有缓存,我们将不可避免的多次执行 list 的 getter!如果你不希望有缓存,请用 method 来替代

计算属性的 Setter

计算属性默认只有 getter,不过在需要时你也可以提供一个 setter:

// ...
computed: {
  fullName: {
    // getter
    get() {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set(newValue) {
      const names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}
// ...

现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstNamevm.lastName 也会相应地被更新。

Class与Style绑定

如果你的组件有多个根元素,你需要定义哪些部分将接收这个类。可以使用 $attrs 组件属性执行此操作:

const app = Vue.createApp({}) app.component('my-component', { template: `

Hi!

This is a child component ` })

条件渲染

v-if vs v-show

v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。

v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好

v-if 与 v-for 一起使用

提示 不推荐同时使用 v-if 和 v-for

v-ifv-for 一起使用时,v-if 具有比 v-for 更高的优先级。请查阅列表渲染指南以获取详细信息。

当它们处于同一节点,v-if 的优先级比 v-for 更高,这意味着 v-if 将没有权限访问 v-for 里的变量:



  • {{ todo }}
  • 可以把 v-for 移动到