美文网首页
Vue.js破冰系列-4计算属性、监视器与过滤器

Vue.js破冰系列-4计算属性、监视器与过滤器

作者: 书上得来终觉浅 | 来源:发表于2019-09-25 15:08 被阅读0次

1 computed计算属性

上一章我们提到指令的一般格式是:

指令名name[:参数arg][.修饰符modifiers][=表达式expression]

其中表达式expression会在其所属实例作用域下作为js代码被解析。前面我在v-on事件监听时,也提到过事件的处理有3种方式:

  • 将js代码加在指令的表达式中
  • 将事件的处理逻辑封装到方法中,把方法与事件绑定起来
  • 在表达式中使用内敛语句调用方法

这3种方式会在绑定元素所属的实例作用域下,会被当做js代码执行。当表达式中js代码的逻辑过于复杂的时候,前面的处理方式是使用方法引用的方式,这里我们再介绍一种方式,用计算属性作为表达式的内容。

1.1 计算属性的定义

计算属性放在computed选项中,既然是属性,那就存在getter和setter方法,所以正常的定义方式如下:

<div id="app">
  <!-- 使用js语句和计算属性作为指令表达式 -->
  <h4 v-text='`${this.firstName} ${this.lastName}`'></h4>
  <h4 v-text='fullName'></h4>
</div>
<script>
var vm = new Vue({
  el:"#app",
  data:{
    firstName:"Michael",
    lastName:"Jackson",
  },
  computed:{
    fullName:{
      get:function(){
        return `${this.firstName} ${this.lastName}`;
      },
      set:function(name){
        let tmp = name.split(' ');
        this.firstName = tmp[0];
        this.lastName = tmp[1];
      }
    }
  }
});
</script>

上面定义了fullName这个计算属性,并定义了其getter和setter方法。在指令的表达式中直接调用计算属性,它会调用fullName的getter方法。当为fullName赋值时,vue会调用其setter方法。通常,setter方法很少用到,所以vue为我们提供了只有getter方法的计算属性的简写形式。

var vm = new Vue({
  computed:{
    fullName:function(){
       return `${this.firstName} ${this.lastName}`;
    }
  }
});

简写方式是属性名后直接跟匿名函数,这个函数就是getter函数。也可以在属性名后接对象,在对象中定义getter函数,不定义setter函数,该方式不常用,所以这里不做代码演示。

1.2 计算属性与方法的区别

如上面的例子,如果我们也可以定义一个getFullName()方法,返回同样的字符格式,然后在指令的表达式中使用该方法,同样能够达到目的。这样看来,计算属性比起方法,其定义反而麻烦了许多。

其实不然,计算属性与方法的最大的区别在于,计算属性有缓存功能,使用方法时,每次都会计算并返回结果,而计算属性只有当其内部的依懒项发生变化时才会重新计算,返回并缓存结果,当内部依赖项没有发生变化时,属性会直接返回缓存结果,所以计算属性要比方法的效率稍高。这里的内部依懒项就是firstName和lastName两个数据项。

2 watch监听器

2.1 监视器的定义

Vue使用watch来监听数据的变化,这里的“数据”指代的范围比较广,它可以是data选项中的值,也可以是props选项的值,还可以是第三方插件的值(比如路由插件vue-route的中路由的变化)。

Vue使用watch选项来定义监听器,watch后接对象,这个对象的键是需要观察的数据或表达式,而其值是当该键发生变化后的处理逻辑,这个处理逻辑的形式包括以下几种:

  • 函数形式,该函数也叫回调函数,当监听的键发生变化后,vue会调用该函数,回调函数有2个参数,分别是变化之后的值(新值)和变化之前的值(旧值)
  • 方法名形式,在watch选项之外定义了一个处理方法,在watch中通过字符串的形式指定方法
  • 对象形式,对象形式除了指定回调函数外,还可以使用其他选项,以这种形式定义监听器,功能是最全的。对象的键包括:
    • handler键:指定回调函数
    • deep键:bool值,表示是否深度监听,当deep为true时,如果watch监听的是一个对象,那么这个对象的任何属性发生变化时(不管这个属性嵌套了多少层),该handler回调函数都会被调用。
    • immediate键:表示该监听是否立即被调用,正常情况,监听对象应先有一个值,当这个值发生变化后,在触发watch。但是,当设置immediate后,该对象在第一次赋值时,这个监听回调也会被触发。
  • 数组形式,上面所说的,不管是函数形式,方法名形式还是对象形式,他们都只能定义一个回调函数,而数组形式,是将上面的形式封装到数组中,这样,当值发生变化后,可以有多个回调函数。
<script>
    var vm = new Vue({
    el:"#app",
    data:{
        a: 1,
        b: 2,
        c: {
        c1: 3
        },
      d:4
    },
    watch:{
      //函数形式
      a:function(newValue,oldValue){},
      //方法名形式
      b:"callback",
      //对象形式
      c:{
        handler:function(newValue,oldValue){},
        deep:true,//可选
        immediate:true,//可选
      },
      //数组形式,可定义多个回调函数
      d:[
        //函数形式
        function(newValue,oldValue){},
        //方法名形式
        "callback",
        {
          //对象中使用方法名形式
          handler:"callback",
          deep:true,
          immediate:true,
        }
      ]
    },
    methods:{
      callback(newValue,oldValue){}
    }
  });
</script>

2.2 监视器实例

在使用vue-route插件做前端路由时,可以在面包屑组件中监听路由变化,改变面包屑的值。通过vue的插件功能将vue-route注入,注入后vue-route为我们提供了两个对象$router$route,我们可以在任何组件内通过 this.$router 访问路由器,通过 this.$route访问当前路由,后续章节会介绍route。

我们需要监听$route对象,当路由发生变化后做响应的改变即可:

var vm = new Vue({
  watch:{
   '$route':function(to, from) {
      // 对路由变化作出响应...
    }
  }
});

3 filters过滤器

过滤器常常用来做显示格式化,比如,我们从服务器上获取用户信息时,gender字段表示用户性别,0表示女,1表示男,2表示未知。如果直接将012的值显示在界面上,用户会不知这些数字代表的含义,这时,我们就可以使用过滤器来做显示格式化。

3.1 过滤器的定义

vue使用filters选项定义过滤器,filters选项后接对象,在对象中定义过滤器函数。在HTML模板中,在js表达式中使用管道符|添加过滤器。注意,在定义过滤器函数时,该函数的第一个参数为管道符前的表达式的计算结果值。

<body>
  <div id="app">
    <!-- 表达式 管道符 过滤器 -->
    <span>{{gender | genderFilter}}</span>
  </div>
  <script>
    var vm = new Vue({
      el:"#app",
      data:{
        gender:0,
      },
      filters:{
        //定义过滤器,value为管道符前的表达式的计算结果
        genderFilter:function(value){
          let strGender = "";
          switch(value){
            case 0:
              strGender = "女";
              break;
            case 1:
              strGender = "男";
              break;
            default:
              strGender = "未知";
              break;
          }
        }
      }
    });
  </script>
</body>

过滤器函数可以设置任意多参数,但第一个参数必须为管道前的表达式的计算结果,如下,我们定义了一个过滤器A,他有2个参数,在调用时,第一个参数是隐形传递的。

<body>
  <div id="app">
    <!-- 过滤器定义了两个参数,第一个为参数为隐式传递,第二个显示传递,所以这里的foo为第二个参数 -->
    <span>{{gender | genderFilter("foo")}}</span>
  </div>
  <script>
    var vm = new Vue({
      el:"#app",
      data:{
        gender:0,
      },
      filters:{
        //过滤器可以定义多个参数,但第一个必须为管道符之前表达式的计算结果
        filterA:function(value,arg1){}
      }
    });
  </script>
</body>

过滤器后还可以接过滤器,这里不再深入。

3.2 过滤器实例

枚举过滤器

在实际开发中,我们可以使用枚举过滤器来简化过滤器的使用,这里我们定义一个bool类型的枚举,js中没有枚举,我们使用的数组来定义:

//enums.js
export const BoolEnum = [
  {key:0,value:"否"},
  {key:1,value:"是"},
]

定义过滤器函数

//filters.js
export const enumFilter function(value,enums){
  for (let i = 0; i < enums.length; i++) {
        let item = enums[i];
        if (item.key == key) {
            return item.value;
        }
    }
    return "N/A";
}

在HTML模板中使用

<body>
  <div id="app">
    <span>是否启用:{{isActive | enumFilter(boolEnum)}}</span>
  </div>
  <script>
    import {BoolEnum as boolEnum} from 'enums.js'
    import {enumFilter} from 'filters.js'
    var vm = new Vue({
      el:"#app",
      data:{
        isActive:0,
      },
      filters: {
            enumFilter
        },
    });
  </script>
</body>

格式化货币过滤器

前面我们将自定义指令时,介绍了通过指令的方式格式化数字,现在我们使用过滤器的方式来实现该功能:

//filters.js
export const moneyFilter function(value){
  value = value + "";
  let hasDot = /\./g;
  let patt = /\B(?=(\d{3})+\.)/g
  if (!hasDot.test(value)) {
    //没有小数点的正则表达式
    patt = /\B(?=(\d{3})+$)/g
  }
  return value.replace(patt, ",");
}

在HTML模板中使用

<body>
  <div id="app">
    <input type="text" v-model="total">
    <br>
    <span>总价:{{total | moneyFilter}}</span>
  </div>
  
  <script>
    import {moneyFilter} from 'filters.js'
    var vm = new Vue({
      el: "#app",
      data: {
        total: 1234567890,
      },
      filters:{
        moneyFilter,
      }
    });
  </script>
</body>

相关文章

  • Vue.js破冰系列-4计算属性、监视器与过滤器

    1 computed计算属性 上一章我们提到指令的一般格式是: 其中表达式expression会在其所属实例作用域...

  • 2018-09-17 vue.js

    vue.js 全局过滤器 局部过滤器 计算属性 1.过滤器 : 让要显示在页面上的内容进行重新筛选 全局过...

  • 过滤器、计算属性

    全局过滤器 局部过滤器 计算属性

  • 过滤器和计算属性

    过滤器:让要显示在页面上的内容进行重新筛选 全局过滤器: 局部过滤: 过滤器日期: 计算属性: 计算属性 求和:

  • vue.js 核心知识点五

    目录 - 5.1 常用自定义过滤器定义与使用 - 5.2 vue的计算属性 - 5.3 计算属性的缓存和方法调用...

  • vue入门基础(2)

    1.vue中的过滤器 定义:让要显示在页面上的内容进行重新筛选 全局过滤器: 局部过滤器: 2.计算属性 计算属性...

  • 使用Vue.js和Axios进行即时搜索

    从Web API提取数据并添加具有计算属性的动态过滤器 Vue.js是一个潜力巨大的框架。它很容易学习,快速且轻巧...

  • vue.js filter过滤器 计算属性

    1.过滤器 过滤器是让要显示在页面上的内容进行重新筛选把要显示在页面上的数据进行筛选或重新操作,分为全局过滤和局部...

  • Vue.js:计算属性和过滤器

    计算属性(computed),主要用于处理一些复杂逻辑。 基础例子 computed vs methods 我们可...

  • Vue 新特性

    1.计算属性 indexOf reduce详细说明 2.过滤器 3.实例属性和方法 4.$set 5.$dele...

网友评论

      本文标题:Vue.js破冰系列-4计算属性、监视器与过滤器

      本文链接:https://www.haomeiwen.com/subject/nkbqyctx.html