视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
VUE的计算属性和侦听器使用案例
2020-11-27 20:01:29 责编:小采
文档

这次给大家带来VUE的计算属性和侦听器使用案例,使用VUE计算属性和侦听器注意事项有哪些,下面就是实战案例,一起来看一下。

写在最前面

上篇的vue的使用 说了vue生命周期、vue实例、模板语法。这次我们来说vue的计算属性和侦听器

计算属性

在vue里面模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如:

<div id="example">
 {{ message.split('').reverse().join('') }}
</div>

在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里的一串代码到底是要干什么,当你想要在模板中多次引用这里时,就会更加难以处理。
所以,对于任何复杂逻辑,你都应当使用计算属性。

比如

<div id="example">
 <p>Original message: "{{ message }}"</p>
 <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
 el: '#example',
 data: {
 message: 'Hello'
 },
 computed: {
 // 计算属性的 getter
 reversedMessage: function () {
 // `this` 指向 vm 实例 return this.message.split('').reverse().join('')
 }
 }
})
Original message: "Hello"
Computed reversed message: "olleH"

这里声明了一个计算属性 reversedMessage。vue提供的函数将用作属性 vm.reversedMessage 的 getter 函数:

console.log(vm.reversedMessage) // => 'olleH'vm.message = 'Goodbye'console.log(vm.reversedMessage) // => 'eybdooG'

你可以像绑定普通属性一样在模板中绑定计算属性。Vue 知道 vm.reversedMessage 依赖于 vm.message,因此当 vm.message 发生改变时,所有依赖 vm.reversedMessage 的绑定也会更新。而且最妙的是vue已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有副作用 (side effect) 的,这使它更易于测试和理解。

计算属性缓存 vs 方法

你可能已经注意到vue可以通过在表达式中调用方法来达到同样的效果:

<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中
methods: {
 reversedMessage: function () { return this.message.split('').reverse().join('')
 }
}

vue可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
这也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:

computed: {
 now: function () { return Date.now()
 }
}

相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

我们为什么需要缓存?假设我们有一个性能开销比较大的的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。

计算属性 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
 }
 }
})

计算属性的 setter

计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :

// ...
computed: {
 fullName: {
 // getter
 get: function () { return this.firstName + ' ' + this.lastName
 },
 // setter
 set: function (newValue) {
 var names = newValue.split(' ')
 this.firstName = names[0]
 this.lastName = names[names.length - 1]
 }
 }
}
// ...

现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstName 和 vm.lastName 也会相应地被更新。

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 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.getAnswer()
 }
 },
 methods: {
 // `_.debounce` 是一个通过 Lodash 操作频率的函数。
 // 在这个例子中,我们希望访问 yesno.wtf/api 的频率
 // AJAX 请求直到用户输入完毕才会发出。想要了解更多关于
 // `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,
 // 请参考:https://lodash.com/docs#debounce
 getAnswer: _.debounce(
 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
 })
 },
 // 这是我们为判定用户停止输入等待的毫秒数 500
 )
 }
})
</script>

结果:

在这个示例中,使用 watch 选项允许我们执行异步操作 (访问一个 API),我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!

相关阅读:

vue生命周期、vue实例、模板语法

前端微信分享jssdk config:invalid signature 签名错误的解决方法

一次前端面试的经历

下载本文
显示全文
专题