Vue3手册译稿 - 基础 - Data属性及方法
Data属性和方法
Data属性
在组件中Data是一个函数,Vue会在创建组件实例时调用它。Data函数应该返回一个对象,Vue会将这个对象包含进它的响应式系统并用$data存储在应用实例中。为了方便,对象中的任何顶级属性都会通过组件直接暴露出来:
const app = Vue.createApp({
data() {
return { count: 4 }
}
})
const vm = app.mount('#app')
console.log(vm.$data.count) // => 4
console.log(vm.count) // => 4
//为vm.count赋值时同时会更新$data.count
vm.count = 5
console.log(vm.$data.count) // => 5
//反之一样
vm.$data.count = 6
console.log(vm.count) // => 6
这些实例属性仅会在当前实例首次创建时加载,所以你要确保它们已在data函数中被定义。如果有必要,对于一些暂时没有值的变量使用null
,undefined
或其他其他占位符赋值。
你也可以直接新增一个属性到data中,但是这个属性没有备份到响应式的$data中,所以它不会自动被Vue响应式系统管理。
Vue使用$前缀通过组件实例暴露内置的API。同时它也为内部属性保留了_
前缀。你要避免在data的顶部属性中使用这两个前缀。
方法
我们使用methods
选项在组件实例中添加方法。它是一个包含一系列方法的对象:
const app = Vue.createApp({
data() {
return { count:4 }
},
methods: {
increment() {
// `this`指向组件实例。
this.count++
}
}
})
const vm = app.mount('#app')
console.log(vm.count) // => 4
vm.increment()
console.log(vm.count) // => 5
Vue自动绑定指向组件实例的this
对象。这可以保证当在方法中使用事件监听或方法回调时在方法有正确的this
值。定义methods
时就避免使用箭头函数,它会阻止Vue绑定正确的this
。
像其他组件实例属性一样,方法在组件模板内部可访问。在组件内部最常用的用法是当作事件监听:
<button @click="increment">投票</button>
上面这个例子,当按钮点击时,increment
方法将被调用。
也可以在方模板中直接调用方法。马上我们会看到,平时我们使用计算属性来代替方法。但在一些计算属性不能使用的场景下直接使用方法还是比较有用的。你可以在模板内任意地方使用JavaScript表达式来调用方法:
<span :title="toTitleDate(date)">
{{ formatDate(date) }}
</span>
如果toTitleDate
或formatDate
访问任意响应式数据定义,它将会被渲染成模板依赖,就像它们直接在模板中使用一样。(如上例子中两个方法的参数:date)
模板中调用方法不应该任何副作用,像更改Data属性或触发异步进程,如果你想这么做,应该使用生命周期勾子代替。
方法 - 防抖动及节流
提示
函数防抖(debounce):
在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时;典型的案例就是输入搜索:输入结束后n秒才进行搜索请求,n秒内又输入的内容,就重新计时。
函数节流(throttle):
规定在一个单位时间内,只能触发一次函数,如果这个单位时间内触发多次函数,只有一次生效; 典型的案例就是鼠标不断点击触发,规定在n秒内多次点击只有一次生效。
Vue没有内置防抖动及节流,但你可以通过如类库Lodash来实现。
下面这个示例组件只会使用一次,在方法
中可以直接使用防抖动:
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>vue demo4</title>
<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/lodash@4.17.20/lodash.min.js"></script>
</head>
<body>
<div id="app">
<input type="text" @input="changing" />
</div>
</body>
<script type="text/javascript">
const app = {
data() {
return {
count: 0
}
},
methods: {
changing: _.debounce(function(){
console.log("输入发生改变:"+ (++this.count) + "次")
},500)
}
}
Vue.createApp(app).mount("#app")
</script>
</html>
看看执行结果:
但在多个组合复用时会产生问题,因为它们共用相同的防抖动函数。为了保持各组件相互独立,我们可以在created
生命周期勾子中进行防抖动处理:
app.component('save-button', {
created() {
// Debouncing with Lodash
this.debouncedClick = _.debounce(this.click, 500)
},
unmounted() {
// Cancel the timer when the component is removed
this.debouncedClick.cancel()
},
methods: {
click() {
// ... respond to click ...
}
},
template: `
<button @click="debouncedClick">
Save
</button>
`
})