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: