天天看点

(二)计算属性、侦听器、过滤器和生命周期

上一文简单介绍了vue的结构和一些核心概念,本文接着介绍计算属性、侦听器、过滤器以及生命周期函数。

上一篇链接:

VUE简单入门(一)

计算属性

我们继续从简单的vue应用入手,如果我们需要在模板中放入很多逻辑,那么模板就会足够复杂且难以维护,如下图:

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

为了解决这个问题,对于任何复杂的逻辑,都应当使用计算属性:computed

看下图这个栗子:

<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('')
    }
  }
})
           

在这里我们就声明了一个计算属性 reversedMessage,把复杂的计算逻放在 reversedMessage里了。这里有几点概念需要拓展说明一下:

  1. 每一个计算属性都包含一个getter 和一个setter ,我们上面的示例都是计算属性的默认用法,只是利用了getter 来读取(当然,getter也是最常用的)
  2. 计算属性是基于它们的依赖进行缓存的。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。(这里多学一个methods方法,方法methods类似computed,不同的是每当触发重新渲染时,调用methods方法总会再次执行函数)
  3. 注意computed里面的this,指向的是vm实例,我们在计算属性computed里不应该使用箭头函数来定义计算属性,因为箭头函数会绑定父级作用域的上下文,所以 this 将不会按照期望指向Vue

参考文献:

https://www.cnblogs.com/8023-CHD/p/11166151.html

https://cn.vuejs.org/v2/guide/computed.html

侦听器watch

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。首先说说什么应用场景适合watch:

  • 使用watch来响应数据的变化,一般用于异步或者开销较大的操作
  • watch 中的属性一定是data中已经存在的数据
  • 当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听(这部分可以看拓展阅读内容)

拓展阅读

https://blog.csdn.net/qq_36688143/article/details/81287535

watch举栗说明

<div id="app">
        <div>
            <span>名:</span>
            <span>
        <input type="text" v-model='firstName'>
      </span>
        </div>
        <div>
            <span>姓:</span>
            <span>
        <input type="text" v-model='lastName'>
      </span>
        </div>
        <div>{{fullName}}</div>
    </div>

  <script type="text/javascript">
        /*侦听器*/
        var vm = new Vue({
            el: '#app',
            data: {
                firstName: 'Jim',
                lastName: 'Green',
                // fullName: 'Jim Green'
            },
             //watch属性定义和data和methods平级 
            watch: {
                //   注意:这里 firstName 对应着 data 中的 firstName 
                //   当 firstName 值改变的时候会自动触发 watch
                firstName: function(val) {
                    this.fullName = val + ' ' + this.lastName;
                },
                //   注意:这里lastName 对应着 data 中的 lastName 
                lastName: function(val) {
                    this.fullName = this.firstName + ' ' + val;
                }
            }
        });
    </script>
           

过滤器filters

接着我们说过滤器,过滤器的本质是一个有参数,有返回值的方法。Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。

栗子一:普通用法,用在{{}} 和 在v-bind

<!-- 在双花括号中 -->
{{ message | capitalize }}

<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>
           
filters: {
  capitalize: function (value) {
    if (!value) return ''
    value = value.toString()
    //   输入内容首字母大写
    return value.charAt(0).toUpperCase() + value.slice(1)
  }
}
           

栗子二:支持级联操作

栗子三:过滤器中传递参数

<div id="box">
        <!--
            filterA 被定义为接收三个参数的过滤器函数。
            其中 message 的值作为第一个参数,
            普通字符串 'arg1' 作为第二个参数,表达式 arg2 的值作为第三个参数。
        -->
        {{ message | filterA('arg1', 'arg2') }}
    </div>
           
<script>
        // 在过滤器中 第一个参数 对应的是  管道符前面的数据n此时对应 message
        // 第2个参数  a 对应 实参  arg1 字符串
        // 第3个参数  b 对应 实参  arg2 字符串
        Vue.filter('filterA',function(n,a,b){
            if(n<10){
                return n+a;
            }else{
                return n+b;
            }
        });
        
        new Vue({
            el:"#box",
            data:{
                message: "哈哈哈"
            }
        })

    </script>
           

注意两点:

  • 过滤器不改变真正的data,而只是改变渲染的结果,并返回过滤后的版本
  • 全局注册时是filter,没有s的。而局部过滤器是filters,是有s的(全局和局部后面我们会细说)

总结一下 computed、watch、filter

computed watch filter
有返回值 不需要返回值、通常是改变值 有返回值
不可以传参 有参数 有多个参数
有缓存 无缓存 无缓存
可以访问this 可以访问this 可以全局/局部定义
一般是需要针对多个数据进行操作 多用于异步 多用于数据格式化

生命周期(勾子函数)

之所以把生命周期归到一起说,一个原因是生命周期和computed、watch在一个层级,另外一方面是理解生命周期有助于理解这几个常用的API的执行顺序。

Vue实例从创建 、运行到销毁的过程 ,这些过程中会伴随着一些函数的自调用。我们称这些函数为钩子函数。

周期函数 对应场景
beforeCreate 在实例初始化之后,数据观测和事件配置之前被调用 此时data 和 methods 以及页面的DOM结构都没有初始化 什么都做不了
created 在实例创建完成后被立即调用此时data 和 methods已经可以使用 但是页面还没有渲染出来
beforeMount 在挂载开始之前被调用 此时页面上还看不到真实数据 只是一个模板页面而已
mounted el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。 数据已经真实渲染到页面上 在这个钩子函数里面我们可以使用一些第三方的插件
beforeUpdate 数据更新时调用,发生在虚拟DOM打补丁之前。 页面上数据还是旧的
updated 由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。 页面上数据已经替换成最新的
beforeDestroy 实例销毁之前调用
destroyed 实例销毁后调用

这里有个非常详细的过程说明,文件来源:

https://blog.csdn.net/mqingo/article/details/86031260
(二)计算属性、侦听器、过滤器和生命周期

继续阅读