目录
计算属性
计算属性缓存vs方法
计算属性vs侦听属性
getter和setter
计算属性和监听器
前端调用api实现问答
侦听器
计算属性
鉴于能在插值表达式中写js表达式;这样做也一定程度上违背了设计插值表达式的初衷;特别是:
其实就相当于不建议你在html标签里写css属性这一类规范;因为实在是不好维护
计算属性缓存vs方法
总结来说,主要区别是计算属性会缓存结果,方法每次调用都会重新计算。
当你有两个插值表达式,其中一个依赖另一个(比如一个变化,另一个有函数关系也跟着变)
而是否设置缓存,和缓存清理在生命周期的阶段,就是我们在设计性能时要考虑的方案
例如:
html <div id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> </div> js var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } } })
这里 reversedMessage
是计算属性,它依赖 message
,并且结果会被缓存。之后当 message
变化时,reversedMessage
才会重新计算。而如果我们用方法来实现,每次读取 reversedMessage
时,函数内的逻辑都会被执行。
js methods: { reversedMessage: function () { return this.message.split('').reverse().join('') } }
所以总结来说,计算属性的优势在于缓存,在多次读取时只计算一次,而方法每次读取都要计算,性能上计算属性更优。
计算属性vs侦听属性
到这里我才明白文档时在做比较,告诉你我这么做的好处
以下是原文内容;我现在还不能完全理解,但我觉得这博大精深,总有一天会理解。所以放在这里了
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch
——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch
回调。细想一下这个例子:
<div id="demo">{{ fullName }}</div> var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar', fullName: 'Foo Bar' }, watch: { firstName: function (val) { this.fullName = val + ' ' + this.lastName }, lastName: function (val) { this.fullName = this.firstName + ' ' + val } } })
上面代码是命令式且重复的。将它与计算属性的版本进行比较:
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar' }, computed: { fullName: function () { return this.firstName + ' ' + this.lastName } } })
好得多了,不是吗?
然后我问了下ai
vue2中计算属性 vs 侦听属性,计算属性好在哪里;减少重复?具体呢
计算属性和侦听属性(watch)的区别主要在于:计算属性:- 依赖其中的数据,并在相关数据发生变化时重新计算 - 结果会被缓存,除非依赖的响应式属性变化才会重新计算 - 应该只用于简单的运算侦听属性(watch):- 每次都会运行函数内的代码 - 没有缓存结果 - 可以用于任意复杂逻辑 - 监听数据的变化计算属性的优势:1. 缓存结果,多次读取只执行一次计算,提高性能。2. 简单逻辑,简洁表达。计算属性的 getter 函数里面应该只包含简单运算,复杂逻辑应该放在方法中。3. 减少重复。例如有两个指令都需要用到某个值,那么可以定义成计算属性,两个指令都读取这个属性就可以了,不需要各自去计算一次。例如:
html <div>{{ fullName }}</div> <div>{{ fullName }}</div>
使用计算属性:
js computed: { fullName: function () { return this.firstName + ' ' + this.lastName } }
没有计算属性,每个 div 都需要执行一次字符串拼接运算,效率较低。使用计算属性能够确保 fullName 只被计算一次,并且在 firstName 或 lastName 变化时重新计算。所以,总结来说,计算属性的好处就是性能更优、 expressions 更简洁,适用于高频计算且结果依赖于其它数据的场景。
我注意到这里也加了‘’,大概是和react的jsx思想,你也许要看一看
getter和setter
这里为什么这么区分,get是做什么的,set又弥补了get哪些不能做的
总结,一个读取计算属性,一个计算计算属性
在计算属性中,getter和setter有不同的作用:getter:- 用于读取计算属性的值 - 依赖的响应式数据发生变化时会重新计算值 - 结果会被缓存,除非依赖的数据变化才会重新计算 - 应该是一个无副作用的运算setter:- 用于写入计算属性的值 - 当设置新值时,可以对依赖的数据进行操作 - 会触发重新渲染,重新计算计算属性的值所以getter和setter分工如下:getter主要用于获取计算属性的值,防止重复计算,提高性能。但只能用于简单的无副作用运算。setter允许我们在更新计算属性时操作依赖的数据,并触发重新渲染和重新计算。这弥补了getter无法进行数据变更和触发重新渲染的缺点。举个例子:
js computed: { fullName: { get() { return this.firstName + ' ' + this.lastName }, set(newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } }
这里的getter用于获取fullName的值,防止每次读取都重新拼接字符串。而setter在更新fullName时,会同时更新firstName和lastName,并触发fullName的重新计算,从而更新fullName的值。所以总结来说:- getter实现高效读取 - setter实现更新依赖数据和触发重新计算 - 两者结合可以实现数据的双向绑定效果
计算属性和监听器
计算属性和监听器什么关系,是底层封装代码用了监听吗?
总结:计算属性加了缓存成为了更高级的监听
计算属性和侦听器(watch)都是 Vue 中用于响应数据变化的功能,但有以下区别:计算属性:- 依赖其中的数据,并在相关数据发生变化时重新计算 - 结果会被缓存,除非依赖的响应式属性变化才会重新计算 - 应该只用于简单的运算侦听属性(watch):- 每次都会运行函数内的代码 - 没有缓存结果 - 可以用于任意复杂逻辑 - 监听数据的变化计算属性内部是基于侦听器来实现的。Vue 会在组件渲染时注册计算属性对应的 watcher,用来更新计算属性的值。当计算属性依赖的数据发生变化时,对应的 watcher 会被触发,从而调用计算属性 getter 重新计算值并更新缓存。所以可以说,计算属性是基于侦听器来实现的一种更为高级的功能 - 具有缓存的值,只在相关依赖变化时重新计算。举个例子:
html <div>{{ fullName }}</div> js data: { firstName: 'John', lastName: 'Doe' }, computed: { fullName() { return this.firstName + ' ' + this.lastName } }
这里 fullName 计算属性内部会有一个 watcher,依赖于 firstName 和 lastName。当 firstName 或 lastName 变化时,fullName 的 watcher 会被触发,从而重新调用 fullName 计算属性 getter 计算最新的值,并触发 fullName 所在组件的重新渲染。而如果直接使用侦听器:
js watch: { firstName(newVal) { this.fullName = newVal + ' ' + this.lastName }, lastName(newVal) { this.fullName = this.firstName + ' ' + newVal } }
每次 firstName 或 lastName 变化,侦听器对应的函数都会被执行,这比计算属性的缓存机制效率会差很多。所以总结来说,计算属性底层是通过侦听器来实现的,但相比直接使用侦听器,计算属性具有更高的性能和更友好的语法。
侦听器这里,写密码验证效果好
前端调用api实现问答
或许你要反复熟系一下,或者在你第一次要做些有趣的东西时要用到
以下是官方文档内容
侦听器
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch
选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
例如:
<div id="watch-example"> <p> Ask a yes/no question: <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: 'I cannot give you an answer until you ask a question!' }, watch: { // 如果 `question` 发生改变,这个函数就会运行 question: function (newQuestion, oldQuestion) { this.answer = 'Waiting for you to stop typing...' this.debouncedGetAnswer() } }, created: function () { // `_.debounce` 是一个通过 Lodash 限制操作频率的函数。 // 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率 // AJAX 请求直到用户输入完毕才会发出。想要了解更多关于 // `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识, // 请参考:https://lodash.com/docs#debounce this.debouncedGetAnswer = _.debounce(this.getAnswer, 500) }, methods: { getAnswer: function () { if (this.question.indexOf('?') === -1) { this.answer = 'Questions usually contain a question mark. ;-)' return } this.answer = 'Thinking...' var vm = this axios.get('https://yesno.wtf/api') .then(function (response) { vm.answer = _.capitalize(response.data.answer) }) .catch(function (error) { vm.answer = 'Error! Could not reach the API. ' + error }) } } }) </script>
结果:
Ask a yes/no question:
Questions usually contain a question mark. ;-)
在这个示例中,使用 watch
选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
除了 watch
选项之外,您还可以使用命令式的 vm.$watch API。