# vue2中的过滤器+计算属性+监听

# vue2过滤器filter

过滤器,也是分为全局和组件内的过滤

Vue.filter('formatTime', function (value) {
            Date.prototype.Format = function (fmt) { //author: meizz
                var o = {
                    "M+": this.getMonth() + 1, //月份
                    "d+": this.getDate(), //日
                    "h+": this.getHours(), //小时
                    "m+": this.getMinutes(), //分
                    "s+": this.getSeconds(), //秒
                    "q+": Math.floor((this.getMonth() + 3) / 3), //季度
                    "S": this.getMilliseconds() //毫秒
                };
                if (/(y+)/.test(fmt))
                    fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
                for (var k in o)
                    if (new RegExp("(" + k + ")").test(fmt))
                        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
                return fmt;
            }
            return new Date(value).Format("yyyy-MM-dd hh:mm:ss");
        })

传参写法

<span>
  {{item.startTime|workstart}}-{{item.endurance|workend(item.startTime)}}
 </span>
 <script>
 filters:{
 	workstart(v){
 	   let tem =v;
 	   return tem.substring(tem.indexOf(" ")+1,tem.indexOf(" ")+6)
 	   
 	},
 	workend(v1,v2){
 		// v1 时长
 		// v2 开始时间
 	   let tem =v2;   
 	   ......
 	   return temh+":"+edate.addnumber(temm) 
 	   
 	 
 	}
 }
 </script>

组件内过滤器,获取不到this,如果需要可以把this传给过滤器处理

<template>
  <div>
    <div>
      <el-table> 
        <el-table-column
          prop="name"
          label="状态/启用状态"
          width="120"
          align="center"
        >
          <template slot-scope="scope">{{ scope.row.onlineState | filteronline(that)}}</template>
        </el-table-column>
      </el-table>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      that:this,
      onlinestateoptions: [], // 获取后台返回的具体在线离线状态数组
    }
  },
  filters:{
    //过滤器 在线离线
     filteronline(v,that){
      let tem=""
      that.onlinestateoptions.forEach(el=>{
        if(el.dictKey === v){
         tem= el.name
        }
      })
      return tem
    }
  }
}
</script>

将this传给过滤器,写成 _this 这种形式会报错(属性_this必须用$data._this,访问在Vue实例中不代理以$_开头的属性,以防止与Vue internalsSee冲突)

# vue2之watch

类型:{ [key: string]: string | Function | Object | Array} 可以监听vuex数据的改变,vue组件数据改变,父组件数据改变,如果觉得$store.state.calendarnum这种监听不好看,可以用copmuted返回,然后把computed的值作为监听名。

如果组件被多个父组件引用,那么watch可能同时监听到多个变化!

watch: {
	'$store.state.calendarnum':function(){
		this.lastmonth()
	},	
},
-------------------------
props:['status',"time"],
watch:{
	status(v){		
		......	   
	}
}
----------------------
data(){
	return{
		telephonechecked:false
	}
}
watch:{
	telephonechecked(){
		   ......		   
		},
}

watch默认是浅监听,对对象的监听就需要变成深监听,

data{
	return {
		info:{
			city:1
		},
		name:"xxx"
	}
}
watch:{
	name(newval,old){	
	},
	info:{
		handler(newval,old){
			//old和newval是指向同一个地址,引用类型
		},
		deep:true//深度监听
	}
}

# 立即监听

在初始化值后面添加:this.$watch('a', this.fn),这样首次赋值是不会触发fn的,只有后面的会触发,例如:

created: function() {
	//初始化修改值
	this.$watch('data',this.fn)
}
methods: {
	fn() {
		//触发
	},
}

使用immediate: true;这个属性,默认为false。其值代表是否以当前的初始值执行handler的函数

 watch:{
    // avatar(v,v1){
    //   console.log(v)
    //   this.avatar1=v;
    //   this.imageUrl=v
    // }
    avatar:{
      immediate: true,
      handler(v,v1) {
        console.log(v)
        this.avatar1=v;
        this.imageUrl=v
      }
    }
  },

注意:当变更(不是替换)对象或数组并使用 deep 选项时,旧值将与新值相同,因为它们的引用指向同一个对象/数组。Vue 不会保留变更之前值的副本。

# $watch和解除监听

还有另外一种方式就是使用 $watch 的API:

我们可以在created的生命周期(后续会讲到)中,使用 this.$watchs 来侦听;

  • 第一个参数是要侦听的源;
  • 第二个参数是侦听的回调函数callback;
  • 三个参数是额外的其他选项,比如deep、immediate;

let unwatch =this.$watch(xxx);这样可以解除监听

# 总结

methods中的方法不能使用箭头函数是因为上下文会选择window不是需要的值,而使用普通函数是因为通过bind显示的绑定传输了ctx

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>lesson 8</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  // methods & computed & watcher
  // computed 和 method 都能实现的功能,建议用 computed,因为有缓存
  // computed 和 watcher 都能实现功能,建议用 computed 因为更加简洁
  const app = Vue.createApp({
    data() {
      return {
        message: "hello world",
        count: 2,
        price: 5,
        newTotal: 10,
      }
    },
    watch: {
      // price 发生变化时,函数会执行
      price(current, prev) {
        this.newTotal = current * this.count;
      }
    },
    computed: {
      // 当计算属性依赖的内容发生变更时,才会重新执行计算
      total() {
        return Date.now() + this.count;
        // return this.count * this.price
      }
    },
    methods: {
      formatString(string) {
        return string.toUpperCase();
      },
      // 只要页面重新渲染,就会重新计算
      getTotal() {
        return Date.now();
        // return this.count * this.price;
      },
    },
    template: `
     <div> {{message}} {{newTotal}} </div>
    `
  });
  const vm = app.mount('#root');
</script>
</html>

watcher中可以异步执行,而计算属性则不能!!!

  • 处理数据的场景不同,监听器适合一个数据影响多个数据,计算属性适合一个数据受多个数据影响
  • 计算属性有缓存性,计算所得的值如果没有变化不会重复执行
  • 监听器选项提供了更通用的方法,适合执行异步操作或较大开销操作的情况
最后更新: 8/24/2022, 9:02:07 AM