toRefs
、ref
、
toRef 响应式
使用一个hooks
做测试, 把数据变为响应式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <template> <h3>toRef</h3> <div> <p>{{person}} </p> <p>{{name}} {{period}} {{infoName}}</p> <button @click="person.name+='!'">点击我name</button> <button @click="person.period+='!'">点击我period</button> <button @click="person.extra.info1.name+='!'">点击我info1.name</button> </div> </template>
<script setup> import {reactive, toRef} from "vue";
const useFei = () => { const person = reactive({ name: "孔丘", period: "春秋末期", extra:{ info1:{ name: '颜回', } } })
// 使用 toRef 后, 值变为响应式,并且值地址引用 return { person, name: toRef(person,'name'), period: toRef(person,'period'), infoName: toRef(person.extra.info1,'name'), } } const {person,name,period,infoName} = useFei();
</script>
|
toRefs 响应式
使用一个hooks
做测试
reactive
对象取出的所有属性值都是非响应式的,
利用toRefs
可以将一个响应式 reactive
对象的所有原始属性转换为响应式的 ref 属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <template> <h3>toRefs</h3> <p> 这个值现在是响应式的 {{firstName}} </p> </template>
<script setup> import {reactive,toRefs} from "vue";
// hooks 测试toRefs 功能 const useFeiHooks = () => { const user = reactive({ firstName: '孔', lastName: '仲尼' })
setInterval(() => { user.firstName += "**" user.lastName += "**" console.log("执行了"); }, 1000)
// return user 这样出去的是非响应式 // 利用 toRefs 可以将一个响应式 reactive 对象的所有原始属性转换为响应式的 ref 属性,并且是地址引用 return toRefs(user) }
const {firstName, lastName} = useFeiHooks(); </script>
|
ref
ref
的另一个作用,获取页面元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <template> <h3>ref</h3> <input type="text" ref="feiRef"> </template>
<script setup> import {ref, onMounted} from "vue";
// 可以获取到页面元素 const feiRef = ref(null);
onMounted(() => { // 光标定位到输入框 feiRef.value && feiRef.value.focus() }) </script>
|
ref
的另一个作用,获取页面元素的innerHTML
获取vue
页面内容转为html
格式
Vue3
如何通过ref
获取真实 DOM
元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <div ref="feiRef" class="print-test"> <p class="title">fei</p> <p class="content">hello 大飞</p> </div>
<script setup> import {getCurrentInstance, ref} from "vue";
const fei = () => {
const feiRef = ref() console.log(feiRef.value.innerHTML) } </script>
|
readonly 只读
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <template> <h3>readonly 只读</h3> <button @click="updateFei">xx</button> </template>
<script setup> import {readonly} from "vue";
const objRead = readonly({ name: '孔丘', period: "春秋末期" })
const updateFei = () => { // waring: 这里会直接报错,不让修改 objRead.name = "xxxxxxxxx"; } </script>
|
toRaw 普通对象
把响应式数据还原为普通对象,只能处理reactive的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <template> <h3>toRaw 把响应式数据还原为普通对象</h3> <p>{{user}}</p> <button @click="handleFei">DaFei</button> </template>
<script setup> import {reactive, toRaw} from "vue";
const user = reactive({ name: '孔丘', period: '春秋时期' }) const handleFei = () => { const newUser = toRaw(user) console.log("newUser 为普通对象",newUser); } </script>
|
customRef
customRef
创建一个自定义的 ref
,并对其依赖项跟踪和更新触发进行显式控制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <template> <h3>customRef 创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制</h3> <p> 输入数字,遇到偶数才显示 </p> <input v-model.number="keyword" placeholder="搜索关键字"/> <p>{{keyword}}</p> </template>
<script setup> import {customRef} from "vue";
const keyword = useDebouncedRef(null) function useDebouncedRef(val) { let timeout return customRef((track, trigger) => { return { get() { track(); // 告诉Vue追踪数据 return val }, set(newValue) { if (newValue % 2 === 0) { // 遇到偶数才触发 val = newValue trigger(); // 告诉Vue去触发界面更新 } } } }) } </script>
|
demo2
自定义一个防抖函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <template> <h3>customRef</h3> <input v-model.number="keyword" placeholder="搜索关键字"/> <p>{{keyword}}</p> </template>
<script setup> import {customRef} from "vue";
const keyword = useDebouncedRef('', 500) function useDebouncedRef(value, delay = 200) { let timeout return customRef((track, trigger) => { return { get() { track() // 告诉Vue追踪数据 return value }, set(newValue) { clearTimeout(timeout) timeout = setTimeout(() => { value = newValue trigger() // 告诉Vue去触发界面更新 }, delay) } } }) } </script>
|