注意,你不能使用 v-html
来拼接组合模板,因为 Vue 不是一个基于字符串的模板引擎。在使用 Vue 时,应当使用组件作为 UI 重用和组合的基本单元。
v-bind
指令指示 Vue 将元素的 id
attribute 与组件的 dynamicId
属性保持一致。如果绑定的值是 null
或者 undefined
,那么该 attribute 将会从渲染的元素上移除。
因为 v-bind
非常常用,我们提供了特定的简写语法:
另一个例子是 v-on
指令,它将监听 DOM 事件:
...
...
这里的参数是要监听的事件名称:click
。v-on
有一个相应的缩写,即 @
字符。
当 isButtonDisabled
为真值或一个空字符串 (即 ) 时,元素会包含这个
disabled
attribute。而当其为其他假值时 attribute 将被忽略。
如果你有像这样的一个包含多个 attribute 的 JavaScript 对象:
const objectOfAttrs = {
id: 'container',
class: 'wrapper'
}
通过不带参数的 v-bind
,你可以将它们绑定到单个元素上:
至此,我们仅在模板中绑定了一些简单的属性名。但是 Vue 实际上在所有的数据绑定中都支持完整的 JavaScript 表达式:
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
这些表达式都会被作为 JavaScript ,以当前组件实例为作用域解析执行。
指令是带有 v-
前缀的特殊 attribute。Vue 提供了许多内置指令,包括上面我们所介绍的 v-bind
和 v-html
。
指令 attribute 的期望值为一个 JavaScript 表达式 (除了少数几个例外,即之后要讨论到的 v-for
、v-on
和 v-slot
)。一个指令的任务是在其表达式的值变化时响应式地更新 DOM。以 v-if 为例:
Now you see me
这里,v-if
指令会基于表达式 seen
的值的真假来移除/插入该 元素。
某些指令会需要一个“参数”,在指令名后通过一个冒号隔开做标识。例如用 v-bind
指令来响应式地更新一个 HTML attribute:
...
...
这里 href
就是一个参数,它告诉 v-bind
指令将表达式 url
的值绑定到元素的 href
attribute 上。
同样在指令参数上也可以使用一个 JavaScript 表达式,需要包含在一对方括号内:
...
...
修饰符是以点开头的特殊后缀,表明指令需要以一些特殊的方式被绑定。例如 .prevent
修饰符会告知 v-on
指令对触发的事件调用 event.preventDefault()
:
我们可以使用 reactive() 函数创建一个响应式对象或数组:
import { reactive } from 'vue'
const state = reactive({ count: 0 })
要在组件模板中使用响应式状态,需要在 setup()
函数中定义并返回。
import { reactive } from 'vue'
export default {
// `setup` 是一个专门用于组合式 API 的特殊钩子函数
setup() {
const state = reactive({ count: 0 })
function increment() {
state.count++
}
// 暴露state、 increment 函数到模块
return {
state,
increment
}
}
}
暴露的方法通常会被用作事件监听器:
在 setup()
函数中手动暴露大量的状态和方法非常繁琐。幸运的是,我们可以通过使用构建工具来简化该操作。当使用单文件组件(SFC)时,我们可以使用 来大幅度地简化代码。
reactive()
API 有两条限制:1、仅对对象类型有效(对象、数组和 Map
、Set
这样的集合类型),而对 string
、number
和 boolean
这样的 原始类型 无效。 2、因为 Vue 的响应式系统是通过属性访问进行追踪的,因此我们必须始终保持对该响应式对象的相同引用。这意味着我们不可以随意地“替换”一个响应式对象,因为这将导致对初始引用的响应性连接丢失;
ref()
定义响应式变量ref() 方法来允许我们创建可以使用任何值类型的响应式 ref:
ref()
将传入参数的值包装为一个带 .value
属性的 ref 对象:
const count = ref(0)
console.log(count) // { value: 0 }
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
TypeScript 用户请参阅:为 ref 标注类型
和响应式对象的属性类似,ref 的 .value
属性也是响应式的。同时,当值为对象类型时,会用 reactive()
自动转换它的 .value
。
当 ref 在模板中作为顶层属性被访问时,它们会被自动“解包”,所以不需要使用 .value
。下面是之前的计数器例子,用 ref()
代替:
跟响应式对象不同,当 ref 作为响应式数组或像 Map
这种原生集合类型的元素被访问时,不会进行解包。
const books = reactive([ref('Vue 3 Guide')])
// 这里需要 .value
console.log(books[0].value)
const map = reactive(new Map([['count', ref(0)]]))
// 这里需要 .value
console.log(map.get('count').value)