双向绑定
双向绑定:当数据变化之后,视图会同步更新,通过v-model实现
v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件
比如:text和textarea元素使用value属性和input事件
demo:
html部分:
<input :value="message" @input="handleChange" /> <p>{{ message }}</p>
方法部分:
handleChange(e) {
this.message = e.target.value;
console.log("test:", this.message);
},
数据驱动
数据来源:来自父元素的属性,来自组件自身的状态data,来自状态管理器
状态data VS 属性props
- 状态是组件自身的数据
- 属性是来自父组件的数据
- 状态的改变未必会触发更新
- 属性的改变未必会触发更新
vue如何做响应式更新:
data中的属性,被用到的会被放在watch中,这部分属性更新时,会触发更新,当没有被用到的属性更新时,不会触发更新
计算属性computed,只会在数据变化时才会计算,提高效率
- 减少模板中计算逻辑
- 数据缓存
- 依赖固定的数据类型(只能是响应式数据)
demo:
<template> <div id="computed"> <!-- computed计算属性,只有当message改变时,才会重新计算 --> <p>message1:"{{ reverseMessage1 }}"</p> <!-- 页面刷新时就会重新计算 --> <p>message1:"{{ reverseMessage2() }}"</p> <p>{{ now }}</p> <button @click="() => $forceUpdate()">forceUpdate</button> <input v-model="message" /> </div> </template> <script> export default { name: "computed", data() { return { message: "hello world", }; }, // 计算属性 computed: { reverseMessage1: function () { console.log("执行reverseMessage1"); return this.message.split("").reverse().join(""); }, now: function () { return Date.now(); }, }, methods: { reverseMessage2: function () { console.log("执行reverseMessage2"); return this.message.split("").reverse().join(""); }, }, }; </script>
监听器watch
更加灵活通用,watch中可以执行任何逻辑,如函数节流,ajax异步获取数据,甚至操作dom
demo:
<template> <div id="watch"> <p>{{ a }}</p> <p>{{ b.c }}</p> <button @click="addCount">update</button> </div> </template> <script> export default { name: "watch", data() { return { a: 10, b: { c: 20, d: 20, }, }; }, watch: { a: function (val, oldval) { console.log("a新:", val, "旧:", oldval); this.b.c += 11; }, "b.c": function (val, oldval) { console.log("b.c 新:", val, "旧:", oldval); }, }, methods: { addCount() { this.a += 10; }, }, }; </script>
computed VS watch:
computed能做的,watch都能做,反之则不行
能用computed就用computed