跳到主要内容

ref

2023年05月03日
柏拉文
越努力,越幸运

一、认识


ref 接受一个内部值,返回一个响应式的、可更改的 ref 对象,此对象只有一个指向其内部值的属性 .value

ref 对象是可更改的,也就是说你可以为 .value 赋予新的值。它也是响应式的,即所有对 .value 的操作都将被追踪,并且写操作会触发与之相关的副作用。如果将一个对象赋值给 ref,那么这个对象将通过 reactive() 转为具有深层次响应式的对象。这也意味着如果对象中包含了嵌套的 ref,它们将被深层地解包。若要避免这种深层次的转换,请使用 shallowRef() 来替代。

二、语法


2.1 绑定数据

<template>
<div>
{{ a }}
<button @click="onChangeA">按钮</button>
</div>
</template>

<script setup lang="ts">
import { ref, type Ref } from 'vue'

const a: Ref<string> = ref('哈哈哈')

const onChangeA = () => {
a.value += '修改'
}
</script>

2.2 静态绑定组件

<template>
<Child ref="childRef" />
</template>

<script setup>
import { ref, onMounted } from 'vue';
import Child from './components/Child.vue';

const childRef = ref(null);

onMounted(()=>{
console.log(childRef.value)
});
</script>

2.3 动态绑定组件

<template>
<Child :ref="comp => setRef(comp, 'childRef')" />
</template>

<script setup>
import { reactive, onMounted } from 'vue';
import Child from './components/Child.vue';

const compRefMap = reactive({});

const setRef = (comp,key)=>{
compRefMap[key] = comp;
console.log(compRefMap)
}
</script>

2.4 静态绑定DOM

<template>
<div ref="divRef"></div>
</template>

<script setup>
import { ref, onMounted } from 'vue';

const divRef = ref(null);

onMounted(()=>{
console.log(divRef.value)
});
</script>

2.5 动态绑定DOM

<template>
<div :ref="(el)=> setRef(el, 'divRef')"></div>
</template>

<script setup>
import { reactive, onMounted } from 'vue';

const divRefMap = reactive({});

const setRef = (el,key)=>{
divRefMap[key] = el;
console.log(divRefMap);
};
</script>

三、查看


当我们在控制台打印一个 ref 数据时:

const count = ref(0);
console.log(count)

打印的结果如下所示:

Preview

可以发现, 打印的数据非常不直观。其实 Vue.js 3.0 中已经定义好了 initCustomFormatter 函数, 这个函数用来在开发环境下初始化自定义的 formatter 。我们以 Chorme 为例, 开启 custom formatter

Preview
Preview

勾选 Enable custom formatters 之后, 刷新浏览器并查看控制台, 会发现输出内容变得非常直观

Preview

四、问题