声明响应式状态
ref()
在组合式 API 中,推荐使用 ref() 函数来声明响应式状态: ref() 接收参数,并将其包裹在一个带有 .value 属性的 ref 对象中返回:
import { ref } from 'vue'
const count = ref(0)
console.log(count) // { value: 0 }
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
形式1 setup() 函数
-
要在组件模板中访问 ref,请从组件的 setup() 函数中声明并返回它们:
<script lang="ts" >
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
function increment() {
// 在 JavaScript 中需要 .value
count.value++
}
// 不要忘记同时暴露 increment 函数
return {
count,
increment
}
}
}
</script>
<template>
<div class="container">
<div>{{ count }}</div>
<button @click="count++">
{{ count }}
</button>
</div>
</template>
<style scoped>
.container {}
</style>
-
注意,在模板中使用 ref 时,我们不需要附加 .value。为了方便起见,当在模板中使用时,ref 会自动解包 (有一些注意事项)。
在模板渲染上下文中,只有顶级的 ref 属性才会被解包。
在下面的例子中,count 和 object 是顶级属性,但 object.id 不是:
const count = ref(0)
const object = { id: ref(1) }
//模版正常渲染执行
{{ count + 1 }}
//模版不会正常渲染非顶级不会被解包仍然是一个ref
{{ object.id + 1 }} 对象
//我们可以将 id 解构为一个顶级属性
const { id } = object
{{ id + 1 }} //模版正常渲染并执行
//模版自动解包
{{ object.id }}
该特性仅仅是文本插值的一个便利特性,等价于 {{ object.id.value }}
形式2 <script setup>
-
在 setup() 函数中手动暴露大量的状态和方法非常繁琐。
-
幸运的是,我们可以通过使用单文件组件 (SFC) 来避免这种情况。我们可以使用 <script setup> 来大幅度地简化代码:
<script setup lang="ts">
import { ref } from 'vue'
const count = ref(0)
function increment() {
count.value++
}
</script>
<template>
<button @click="increment">
{{ count }}
</button>
</template>
深层响应性
-
Ref 可以持有任何类型的值,包括深层嵌套的对象、数组或者 JavaScript 内置的数据结构,比如 Map。
-
Ref 会使它的值具有深层响应性。这意味着即使改变嵌套对象或数组时,变化也会被检测到:
<script setup lang="ts">
import { ref } from 'vue'
const count = ref(0)
const obj = ref({
nested: { count: 0 },
arr: ['foo', 'bar']
})
function mutateDeeply() {
// 以下都会按照期望工作
obj.value.nested.count++
obj.value.arr.push('baz')
}
function increment() {
count.value++
}
</script>
<template>
{{ obj.arr }}
<button @click="mutateDeeply">
{{ obj.nested.count + 1 }}
</button>
</template>
shallow ref
可以通过 shallow ref 来放弃深层响应性
-
减少大型不可变数据的响应性开销
-
与外部状态系统集成
DOM 更新时机
-
当你修改了响应式状态时,DOM 会被自动更新。但是需要注意的是,DOM 更新不是同步的。
-
Vue 会在“next tick”更新周期中缓冲所有状态的修改,以确保不管你进行了多少次状态修改,每个组件都只会被更新一次。文章来源:https://www.toymoban.com/news/detail-802606.html
要等待 DOM 更新完成后再执行额外的代码,可以使用 nextTick() 全局 API:文章来源地址https://www.toymoban.com/news/detail-802606.html
<script setup lang="ts">
import { ref } from 'vue'
import { nextTick } from 'vue'
const count = ref(0)
async function increment() {
count.value++
console.log(document.querySelector('button')?.textContent);
// 这里会立即打印 '0'
await nextTick()
// 现在 DOM 已经更新了
console.log(document.querySelector('button')?.textContent);
// 这里会立即打印 '1'
}
</script>
<template>
<button @click="increment">
{{ count }}
</button>
</template>
到了这里,关于vue3-响应式基础之ref的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!