我来详细讲解一下“until封装watch常用逻辑简化代码写法”的攻略。
什么是until
until
是Vue.js中一个常用的指令修饰符,它用于监听数据变化直到满足条件才执行操作。常用语法如下:
<!-- 监听value值变化,直到其等于一个值为9的时候才执行alert方法 -->
<div v-on:click="alert('clicked')" v-on:click.until="value === 9">{{ value }}</div>
watch的常用逻辑
Vue.js中的watch
是非常常用的一种数据监听方式,通过监听指定数据的变化来触发特定的逻辑。常见的有以下几种:
对象监听
watch: {
'person.name': function (newName, oldName) {
console.log(`姓名从 ${oldName} 改为了 ${newName}`);
}
}
数组监听
watch: {
'list': function (newList, oldList) {
console.log(`列表从 ${oldList} 改为了 ${newList}`);
}
}
immediate
watch: {
'person.name': {
immediate: true,
handler (newName, oldName) {
console.log(`姓名从 ${oldName} 改为了 ${newName}`);
}
}
}
until封装watch常用逻辑
使用until
指令可以简化watch
中的常用逻辑代码。我们可以将unil
封装进去,使watch
的逻辑更加清晰简洁。封装方法如下:
Vue.directive('until', {
bind (el, binding, vnode) {
const { expression, value } = binding
const newValue = typeof value === 'function' ? value() : value
let isReady = false
function watchHandler (newVal, oldVal) {
if (isReady) return
if (!expression) {
isReady = true
vnode.context.$forceUpdate()
return newValue
}
const [left, right] = expression.split('==')
const leftValue = vnode.context(left.trim())
const rightValue = Number(right.trim())
if (leftValue === rightValue) {
isReady = true
vnode.context.$forceUpdate()
return newValue
}
}
vnode.context.$watch(expression, watchHandler)
}
})
现在我们可以使用until
简化watch
中的常用逻辑,示例如下:
watch: {
'person.name': {
until: 'age == 18',
handler (newName, oldName) {
console.log(`姓名从 ${oldName} 改为了 ${newName}`);
}
}
}
上述代码中,handler
函数只有在age
等于18时才会被触发。另外,我们还可以像之前那样,使用function
方式指定一个具体的值,用于提高代码的可维护性和阅读性。
示例1
现在我们有一个需求,就是监听vm.person.name
和vm.person.age
的变化,只有当name
为'小明'
而age
为18
的时候才触发回调函数,否则不做任何操作。
使用until
封装的代码如下:
Vue.directive('until', {
bind (el, binding, vnode) {
const { expression, value } = binding
const newValue = typeof value === 'function' ? value() : value
let isReady = false
function watchHandler (newVal, oldVal) {
if (isReady) return
if (!expression) {
isReady = true
vnode.context.$forceUpdate()
return newValue
}
const [left, right] = expression.split('==')
const leftValue = vnode.context(left.trim())
const rightValue = Number(right.trim())
if (leftValue === rightValue) {
isReady = true
vnode.context.$forceUpdate()
return newValue
}
}
vnode.context.$watch(expression, watchHandler)
}
})
var vm = new Vue({
el: '#app',
data: {
person: {
name: '',
age: null
}
},
watch: {
'person.name': {
until: "person.name == '小明' && person.age == 18",
handler (newName, oldName) {
console.log(`姓名从 ${oldName} 改为了 ${newName}`);
}
},
'person.age': {
until: "person.name == '小明' && person.age == 18",
handler (newAge, oldAge) {
console.log(`年龄从 ${oldAge} 改为了 ${newAge}`);
}
}
}
})
示例2
假设我们有一个需求,我们需要监听数据变化,当数据变化的时候,会发起一个请求。这个请求是需要缓冲的,也就是说,如果100ms内又有数据变化,那么上一次的请求就会被覆盖,只保留最后一次的变化触发的请求。如何实现这个需求呢?
我们使用until
封装watch的代码可以实现这个需求:
Vue.directive('until', {
bind (el, binding, vnode) {
const { expression, value } = binding
const newValue = typeof value === 'function' ? value() : value
let isReady = false
function watchHandler (newVal, oldVal) {
if (!expression) {
vnode.context.$forceUpdate()
return newValue
}
const [left, right] = expression.split('==')
const leftValue = vnode.context(left.trim())
const rightValue = Number(right.trim())
if (leftValue === rightValue) {
isReady = true
setTimeout(() => {
vnode.context.$forceUpdate()
isReady = false
}, 100)
return newValue
}
}
vnode.context.$watch(expression, watchHandler)
}
})
var vm = new Vue({
el: '#app',
data: {
list: []
},
watch: {
'list': {
until: "true",
handler (newList, oldList) {
console.log('数据发生了变化,并发起了请求');
}
}
}
})
在这个示例中,我们将until
指令的条件设为true
,这样就会直接触发回调函数。如果在100ms内有数据变化,那么会将100ms缓冲时间重置,重新计时。这样,就能实现100ms内只能发起一次请求的效果了。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:until封装watch常用逻辑简化代码写法 - Python技术站