
监视属性实现

<!DOCTYPE html><html><head><meta charset="utf-8"><title></title></head><body><div id="app"><input type="text" v-model="firstName" /><input type="text" v-model="lastName" /><input type="text" v-model="fullName" /></div></body><script src="js/vue.js" type="text/javascript" charset="utf-8"></script><script type="text/javascript">const app = new Vue({el: "#app",data: {firstName: "A",lastName: "B",fullName: "AB"},// 监视属性watch: {firstName(value) {this.fullName = value + this.lastName},lastName(value) {this.fullName = this.firstName + value}}})</script></html>

运行结果如下


就是三个输入框,前两个可以用户填写内容,最后一个来显示前两个输入框拼接而成的内容,其中就是使用 v-model 实现的一个双向绑定
而计算属性的写法是这样的:
<!DOCTYPE html><html><head><meta charset="utf-8"><title></title></head><body><div id="app"><input type="text" v-model="firstName" /><input type="text" v-model="lastName" /><input type="text" v-model="fullName" /></div></body><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script type="text/javascript">const app = new Vue({el: "#app",data: {firstName: "A",lastName: "B"},computed: {fullName() {return this.firstName + " " + this.lastName;}}})</script></html>
实现的效果相同,看两者的代码,发现我们使用计算属性来说好像更合适,答案也确实是的,无论代码量还是代码格式,计算属性都要更优。

watch选项提供了一个更通用的方法,响应数据的变化。当数据变化时执行异步或开销较大的操作,这个方式是最有用的。
<div id="watch-example"><p>输入一个肯定或者否定的问题:<input v-model="question"></p><p>{{ answer }}</p></div><!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 --><!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。--><script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script><script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script><script>var watchExampleVM = new Vue({el: '#watch-example',data: {question: '',answer: '请提问,否则我无法给出答案!'},watch: {// 如果 `question` 发生改变,这个函数就会运行question: function (newQuestion, oldQuestion) {this.answer = '等你停止打字才可给出答案...'this.debouncedGetAnswer()}},created: function () {// `_.debounce` 是一个通过 Lodash 限制操作频率的函数。// 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率// AJAX 请求直到用户输入完毕才会发出。想要了解更多关于// `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,// 请参考:https://lodash.com/docs#debouncethis.debouncedGetAnswer = _.debounce(this.getAnswer, 500)},methods: {getAnswer: function () {if (this.question.indexOf('?') === -1) {this.answer = '问题是包含?号的. ;-)'return}this.answer = '思考中...'var vm = this// 发送异步请求axios.get('https://yesno.wtf/api').then(function (response) {vm.answer = _.capitalize(response.data.answer)}).catch(function (error) {vm.answer = '错误无法访问接口! ' + error})}}})</script>

PS:这接口竟然不识别中文,怀疑人生一秒钟!



1、当数据变化时执行异步或开销较大的操作时,使用监听属性
2、在这个示例中,使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。



计算属性

支持缓存,只有依赖数据发生改变,才会重新进行计算
不支持异步,当computed内有异步操作时无效,无法监听数据的变化
computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。

监视属性watch

不支持缓存,数据变,直接会触发相应的操作;
watch支持异步;
监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
当一个属性发生变化时,需要执行对应的操作;一对多;
监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,
immediate:组件加载立即触发回调函数执行,
deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。
注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。

END




