Vue3相关学习
创建应用
模版语法
响应式
ref
在组合式 API 中,更应该使用 ref() 函数来声明响应式状态:
1 | import { ref } from 'vue' |
reactive
还有另一种声明响应式状态的方式,即使用reactive()API。与将内部值包装在特殊对象中的ref不同,reactive()将使对象本身具有响应性:
1 | import { reactive } from 'vue' |
为什么要使用 ref?
为什么需要使用带有.value的ref,而不是普通的变量?
当在模板中使用了一个ref,然后改变了这个ref的值时,Vue会自动检测到这个变化,并且相应地更新DOM。这是通过一个基于依赖追踪的响应式系统实现的。当一个组件首次渲染时,Vue 会追踪在渲染过程中使用的每一个 ref。然后,当一个ref被修改时,它会触发追踪它的组件的一次重新渲染。
在标准的JavaScript中,检测普通变量的访问或修改是行不通的。然而,可以通过getter和setter方法来拦截对象属性的get和set操作。
该.value属性给予了Vue一个机会来检测ref何时被访问或修改。在其内部,Vue在它的getter中执行追踪,在它的setter中执行触发。从概念上讲,你可以将ref看作是一个像这样的对象:
1 | const myRef = { |
另一个ref的好处是,与普通变量不同,你可以将ref传递给函数,同时保留对最新值和响应式连接的访问。当将复杂的逻辑重构为可重用的代码时,这将非常有用。
使用场景
优先用 ref 的场景
- 基本数据类型(字符串、数字、布尔等)。
- 需要明确控制响应式的简单数据。
- 可能被解构或重新赋值的变量。
优先用 reactive 的场景:
- 复杂对象或数组(如用户信息、列表数据)。
- 希望直接通过属性访问,保持代码简洁时。
计算属性
方法computed() 期望接收一个getter函数,返回值为一个计算属性 ref。和其他一般的ref类似,可以通过publishedBooksMessage.value访问计算结果。计算属性ref也会在模板中自动解包,因此在模板表达式中引用时无需添加.value。
计算属性还会自动追踪响应式依赖。它会检测到publishedBooksMessage依赖于author.books,所以当author.books改变时,任何依赖于publishedBooksMessage的绑定都会同时更新。
1 | <script setup> |
类与样式绑定
绑定HTML Class
绑定内联Style
条件渲染
v-if
指令v-if用于条件性地渲染一块内容。这块内容只会在指令的表达式返回真值时才被渲染。
1 | <h1 v-if="awesome">Vue is awesome!</h1> |
v-else
也可以使用v-else为v-if添加一个else区块。
1 | <button @click="awesome = !awesome">Toggle</button> |
v-else-if
其实就是ifelse语法
1 | <div v-if="type === 'A'"> |
template 上的 v-if
因为 v-if 是一个指令,必须依附于某个元素。但如果想要切换的不止一个元素,也可以在一个 <template> 元素上使用 v-if,<template>是一个不可见的包装器元素,有点类似React的Fragment标签,最后渲染的结果并不会包含这个 <template> 元素。
1 | <template v-if="ok"> |
指令 v-else 和 v-else-if 也可以在 <template> 上使用。
v-show
另一个可以用来按条件显示一个元素的指令是 v-show。其用法基本一样:
1 | <h1 v-show="ok">Hello!</h1> |
不同之处在于 v-show 会在 DOM 渲染中保留该元素;v-show 仅切换了该元素上名为 display 的 CSS 属性。
指令 v-show 不支持在 <template> 元素上使用,也不能和 v-else 搭配使用。
v-if vs v-show
指令 v-if 是“真实的”按条件渲染,在切换时,条件区块内的事件监听器和子组件都会被销毁与重建。
指令 v-if 也是惰性的:如果在初次渲染时条件值为 false,则不会做任何事。条件区块只有当条件首次变为 true 时才被渲染。
相比之下,v-show 简单许多,元素无论初始条件如何,始终会被渲染,只有 CSS display 属性会被切换。(v-show的隐藏是通过 display: none 实现的)
总的来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要频繁切换,则使用 v-show 较好;如果在运行时绑定条件很少改变,则 v-if 会更合适。
列表渲染
v-for
可以使用 v-for 指令基于一个数组来渲染一个列表。v-for 指令的值需要使用 item in items 形式的特殊语法,其中 items 是源数据的数组,而 item 是迭代项的别名:
1 | const items = ref([{ message: 'Foo' }, { message: 'Bar' }]); |
template 上的 v-for
和模板上的 v-if 类似,也可以在 <template> 标签上使用 v-for 来渲染一个包含多个元素的块。例如:
1 | <ul> |
通过 key 管理状态
和 React Reconcile 阶段类似,列表渲染时 Vue 也要给虚拟 DOM 一个标识
框架 Vue 默认按照“就地更新”的策略来更新通过 v-for 渲染的元素列表。当数据项的顺序改变时,Vue 不会随之移动 DOM 元素的顺序,而是就地更新每个元素,确保它们在原本指定的索引位置上渲染。
默认模式是高效的,但只适用于列表渲染输出的结果不依赖子组件状态或者临时 DOM 状态 (例如表单输入值) 的情况。
为了给 Vue 一个提示,以便它可以跟踪每个节点的标识,从而重用和重新排序现有的元素,需要为每个元素对应的块提供一个唯一的 key attribute:
1 | <div v-for="item in items" :key="item.id"> |
当使用 <template v-for> 时,key 应该被放置在这个 <template> 容器上:
1 | <template v-for="todo in todos" :key="todo.name"> |
事件处理
我们可以使用 v-on 指令 (简写为 @) 来监听 DOM 事件,并在事件触发时执行对应的 JavaScript。用法:v-on:click="handler" 或 @click="handler"。
事件处理器 (handler) 的值可以是:
内联事件处理器(纯纯的糟粕,完全不明白Vue为什么要设计这么复杂的语法)
事件被触发时执行的内联 JavaScript 语句
1 | <button @click="count++">Add 1</button> |
方法事件处理器
一个指向组件上定义的方法的属性名或是路径。
1 | const name = ref('Vue.js') |
侦听器
模版引用
组件
指令
- v-text:会把内容解析成纯文本(会覆盖原标签内容)
- v-html:可以解析标签(会覆盖原标签内容)
- v-if
- v-else
- v-else-if
- v-show
- v-for: