数据,方法,计算属性和侦听器
如果我们在click
方法中使用箭头函数,因为this
会一层一层往上找,那么此时的this
执行的是window
<body>
<div id="root">
</div>
<script>
// this = window
// data & methods & computed & watcher
const app = Vue.createApp({
data () {
return {
tip: 'vue3学习',
}
},
methods: {
alertClick: () => {
console.log('click', this)
}
},
template: `
<div @click="alertClick">{{tip}}</div>
`
})
const vm = app.mount('#root')
</script>
</body>
控制台显示结果:
结论: 所以在Vue中我们最好定义方法的时候不要用箭头函数去写,可以采用下面的代码方法
<body>
<div id="root">
</div>
<script>
// data & methods & computed & watcher
const app = Vue.createApp({
data () {
return {
tip: 'vue3学习',
}
},
methods: {
alertClick() {
console.log('click', this)
}
},
template: `
<div @click="alertClick">{{tip}}</div>
`
})
const vm = app.mount('#root')
</script>
</body>
控制台显示结果:
结论: 这样写的话,Vue会自动将this
绑定到vue的实例
上面
除了上面这样用,我们还可以在插值表达式
中使用方法
<body>
<div id="root">
</div>
<script>
// data & methods & computed & watcher
const app = Vue.createApp({
data () {
return {
tip: 'VUE',
}
},
methods: {
formatString(value) {
return value.toLowerCase()
}
},
template: `
<div>{{formatString(tip)}}</div>
`
})
const vm = app.mount('#root')
</script>
</body>
这样控制台输出的结果就会将大写的VUE
都转成小写的vue
computed的使用
<body>
<div id="root">
</div>
<script>
// data & methods & computed & watcher
const app = Vue.createApp({
data () {
return {
tip: 'VUE',
num: 4,
price: 10,
}
},
computed: {
totalPrice() {
return this.num * this.price
}
},
methods: {
},
template: `
<div>{{totalPrice}}</div>
`
})
const vm = app.mount('#root')
</script>
</body>
当我们代码中需要计算一个总价,为了更加语义化,我们可以使用computed
方法,这样当我们中totalPrice
依赖的num
和price
发生变化时,vue会自动计算totalPrice
的值。
第二种,我们也可以通过methods
的方法去计算总价,看下methods
中的方法和computed
有什么不同?
<body>
<div id="root">
</div>
<script>
// data & methods & computed & watcher
const app = Vue.createApp({
data () {
return {
tip: 'VUE',
num: 4,
price: 10,
}
},
computed: {
totalPrice() {
return this.num * this.price
}
},
methods: {
getTotalPrice() {
return this.num * this.price
}
},
template: `
<div>{{getTotalPrice()}}</div>
`
})
const vm = app.mount('#root')
</script>
</body>
当我们在methods
中写了一个getTotalPrice
方法,在控制台中通过vm.$data.price
修改值,发现总价也会自动变化,这样看起来二者没有区别,但是如果仔细研究会发现二者还是有差异的?
当我们把代码这样写,如下
<body>
<div id="root">
</div>
<script>
// data & methods & computed & watcher
const app = Vue.createApp({
data () {
return {
tip: 'VUE',
num: 4,
price: 10,
}
},
computed: {
totalPrice() {
return Date.now()
}
},
methods: {
getTotalPrice() {
return Date.now()
}
},
template: `
<div>{{tip}} -- {{totalPrice}} --- "你好我是computed中的"</div>
<div>{{tip}} -- {{getTotalPrice()}}--- "你好我是methods中的"</div>
`
})
const vm = app.mount('#root')
</script>
</body>
控制台输出结果:
当我们在控制台通过vm.$data.tip
修改为110,看看控制台的变化?
下面说下computed和methods的区别?
computed
: 当计算属性依赖的内容发生变化时,才会重新执行计算,如果依赖的内容没有发生变化,会有缓存的。
mehtods
:只要页面重新渲染,才会重新计算
虽然computed
和methods
都能实现相同的效果,但是computed
内存带有缓存的效果,所以computed
在做页面渲染的时候会更高效一些,一般来说我们能既能采用methods
又能采用computed
,一般我们会采用computed
watch的使用
实现效果:当price发生变化时,等几秒钟打印"price change"这个字符串,可以使用watch做一些异步操作
<body>
<div id="root">
</div>
<script>
// data & methods & computed & watcher
const app = Vue.createApp({
data () {
return {
tip: 'VUE',
num: 4,
price: 10,
}
},
watch: {
price() {
setTimeout(() => {
console.log('price change')
}, 3000)
}
},
computed: {
totalPrice() {
return Date.now()
}
},
methods: {
getTotalPrice() {
return Date.now()
}
},
template: `
<div>{{tip}} -- {{totalPrice}} --- "你好我是computed中的"</div>
<div>{{tip}} -- {{getTotalPrice()}}--- "你好我是methods中的"</div>
`
})
const vm = app.mount('#root')
</script>
</body>
当我们在控制台输入vm.$data.price = 500
, 等3s控制台会打印出"price change"字符串
我们用watch仿造computed做一下计算
<body>
<div id="root">
</div>
<script>
// data & methods & computed & watcher
const app = Vue.createApp({
data () {
return {
tip: 'VUE',
num: 4,
price: 10,
totalPrice: 40
}
},
watch: {
price(newValue, oldValue) {
this.totalPrice = newValue * this.num
}
},
computed: {
// totalPrice() {
// return Date.now()
// }
},
methods: {
// getTotalPrice() {
// return Date.now()
// }
},
template: `
<div>{{totalPrice}}</div>
`
})
const vm = app.mount('#root')
</script>
</body>
我们在控制台输入vm.$data.price = "100"
,回车后发现得到的是400,看起来和计算属性computed实现的效果是一样的。
控制台输出结果:
结论:但是我们发现,如果使用watch我们在data中需要再定义一个变量。所以一个同步功能可以用watch
和computed
同时实现,我们用computed
会更加简洁一些,如果是异步功能使用watch
会更好一些。