import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
<template>
<input type="text" v-model="keyWord">
<h3>{{keyWord}}h3>
template>
<script>
import {ref} from "vue";
export default {
name: 'App',
setup() {
let keyWord = ref("hello");
return {
keyWord
}
}
}
script>
自定义ref,本质是一个函数。
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
<template>
<input type="text" v-model="keyWord">
<h3>{{keyWord}}h3>
template>
<script>
import {customRef} from "vue";
export default {
name: 'App',
setup() {
//自定义ref,本质是一个函数
function myRef(value){
return customRef(() => {
return {
get(){
console.log("正在读取value,当前值为:",value);
return value;
},
set(newValue){
console.log("正在修改value,新值为:",newValue);
value = newValue;
}
}
})
}
let keyWord = myRef("hello");
return {
keyWord
}
}
}
script>
针对以上问题,修改Demo.vue中的myRef
。
<template>
<input type="text" v-model="keyWord">
<h3>{{keyWord}}h3>
template>
<script>
import {customRef} from "vue";
export default {
name: 'App',
setup() {
//自定义ref,本质是一个函数
function myRef(value){
return customRef((track,trigger) => {
return {
get(){
console.log("正在读取value,当前值为:",value);
//通知Vue追踪value的变化
track();
return value;
},
set(newValue){
console.log("正在修改value,新值为:",newValue);
value = newValue;
//通知Vue重新解析模板
trigger();
}
}
})
}
let keyWord = myRef("hello");
return {
keyWord
}
}
}
script>
customRef
的回调中接收两个参数:track
和trigger
,它们都是函数。
调用trigger
函数,通知Vue重新解析模板;调用track
函数,通知Vue追踪目标数据的变化。
在setter中调用trigger
,在getter中调用track
,自定义ref(myRef
)的功能就和ref
类似了。如下图所示。
现在需求是这样的:输入框中的文本发生改变,下面h3标签中的内容延迟500ms更新。
既然已经用customRef
实现了自定义ref,即myRef
,延迟更新就变得很简单了:在setter中加入setTimeout延迟即可,如下。
<template>
<input type="text" v-model="keyWord">
<h3>{{keyWord}}h3>
template>
<script>
import {customRef} from "vue";
export default {
name: 'App',
setup() {
//自定义ref,本质是一个函数
function myRef(value){
return customRef((track,trigger) => {
return {
get(){
console.log("正在读取value,当前值为:",value);
track();
return value;
},
set(newValue){
console.log("正在修改value,新值为:",newValue);
setTimeout(() => {
value = newValue;
trigger();
},500)
}
}
})
}
let keyWord = myRef("hello");
return {
keyWord
}
}
}
script>
但是有一个小问题:当输入框中文本改变过快时,h4标签中内容更新时会出现抖动,见下图。
采用防抖的方式解决以上问题(当然,这是js范畴的知识点哈,并不是Vue的哈)。修改后的Demo.vue如下所示。
<template>
<input type="text" v-model="keyWord">
<h3>{{keyWord}}h3>
template>
<script>
import {customRef} from "vue";
export default {
name: 'App',
setup() {
//自定义ref,本质是一个函数
function myRef(value,delay){
return customRef((track,trigger) => {
let timer;
return {
get(){
console.log("正在读取value,当前值为:",value);
track();
return value;
},
set(newValue){
console.log("正在修改value,新值为:",newValue);
clearTimeout(timer);
timer = setTimeout(() => {
value = newValue;
trigger();
},delay)
}
}
})
}
let keyWord = myRef("hello",500);
return {
keyWord
}
}
}
script>