目录
data(数据)
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue.js -- 数据、方法、计算属性、侦听器</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
data(){
return {
content: 'Hello Vue.js!'
}
},
template: `<div>{{content}}</div>`
})
const vm = app.mount('#root');
</script>
</body>
</html>
页面效果:
在控制台中使用
vm.$data.content = 'hello'
可以修改数据。content是data的根数据(第一层数据)可以直接使用
vm.content = 'hi'
修改数据。
methods(方法)
代码演示:
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
data(){
return {
content: 'Hello Vue.js!'
}
},
methods:{
handleClick(){
console.log('click', this.content);
}
},
template: ` <div @click="handleClick">{{content}}</div>`
})
const vm = app.mount('#root');
</script>
</body>
页面布局:
触发点击事件,成功输出 click Hello Vue.js! ,说明this指向vue实例。
如果将handleClick改写成箭头函数,则this指向vue实例外层,即window
computed(计算属性)
当计算属性所依赖的内容发生变化时,才会重新计算。
代码演示:
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
data(){
return {
count: 6,
price: 3
}
},
computed:{
total(){
return this.count * this.price;
}
},
template: ` <div>{{total}}</div>`
})
const vm = app.mount('#root');
</script>
</body>
页面效果:
页面成功输出18
修改count值后,页面重新渲染出6
methods vs computed
代码演示:
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
data(){
return {
count: 6,
price: 3
}
},
computed:{
total(){
return this.count * this.price;
}
},
methods:{
getTotal(){
return this.count * this.price;
}
},
// template: ` <div>{{total}}</div>`
template: ` <div>{{getTotal()}}</div>`
})
const vm = app.mount('#root');
</script>
</body>
页面效果:
我们发现这两种方式的最终结果完全相同。
但不同的是计算属性是有缓存的。这就意味着只要
count、price没有发生改变,多次访问计算属性会立即返回之前的计算结果,而不必再次执行函数。而
getTotal()
方法,每当触发重新渲染时,getTotal()
方法都会执行。
watch(侦听器)
虽然computed(计算属性)在大多数情况下更合适,但当需要在数据变化时执行异步或开销较大的操作时,watch(侦听器)最有用的。
代码演示:
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
data(){
return {
count: 6,
price: 3
}
},
watch:{
price(oldVal, val){
console.log(oldVal, '修改前的值');
console.log(val, '修改后的值');
setTimeout( () => {
console.log('watch');
},1000);
}
},
computed:{
total(){
return this.count * this.price;
}
},
methods:{
getTotal(){
return this.count * this.price;
}
},
// template: ` <div>{{total}}</div>`
template: ` <div>{{getTotal()}}</div>`
})
const vm = app.mount('#root');
</script>
</body>
页面效果:
修改price值1秒后成功打印watch
computed vs watch
代码演示:
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
data(){
return {
count: 6,
price: 3,
newTotal: 18
}
},
watch:{
price(oldVal, val){
this.newTotal = val * this.count;
}
},
computed:{
total(){
return this.count * this.price;
}
},
template: ` <div>{{newTotal}}</div>`
})
const vm = app.mount('#root');
</script>
</body>
页面显示:
修改price值后成功渲染出30。使用computed和watch效果相同,但如果只执行同步代码推荐使用computed,因为使用computed更简洁。
watch侦听值类型 vs watch侦听引用类型
代码演示:
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
data(){
return {
name: '张三',
info: {
nickName: '法外狂徒'
}
}
},
watch:{
// 值类型
name(oldVal, val){
console.log('name', oldVal, val)
},
// 引用类型
info:{
handler(oldVal, val){
console.log('nickName', oldVal, val)
},
deep: true //深度监听
}
},
})
const vm = app.mount('#root');
</script>
控制台输出:
值类型,可以拿到 oldVal, val
引用类型,拿不到oldVal。因为指针相同,此时指针已经指向新的val。
总结
computed 和 methods 都能实现的功能,建议使用 computed,因为computed有缓存
omputed 和 watch 都能实现的功能,建议使用 watch,因为watch更简洁
watch侦听值类型,可以拿到 oldVal, val
watch侦听引用类型,拿不到oldVal
(完)