【Vue】6 - 选项 - filters、computed 、watch

1.filters 过滤器

  1. 如果有两个vue实例,一个实例是获取不到另一个实例里的方法的,如下我们写了2个实例:过滤器myFilter是在实例1中定义的,在实例2中无法使用

定义:过滤器名称fn(要过滤的数据data,参数1,参数2){return 操作}
使用: vue实例中,{{ '数据data' | fn(参数1,参数2)}}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="shortcut icon" href="#" type="image/x-icon">
</head>
<body>
    <div id="app1">   
       {{'hello' | myFilter('lxz')}}
       <!-- 使用: '数据data' | fn(参数1,参数2) -->
    </div>
    <div id="app2">
        {{'hello' | myFilter('lxz123')}}
        <!-- 实例vm2获取不到vm1里的过滤方法 -->
    </div>
    <script src="node_modules/vue/dist/vue.js"></script>
    <script>
        // 这里我们写了2个实例:过滤器myFilter是在实例1中定义的,在实例2中无法使用
    let vm1 = new Vue({ 
        el:'#app1',
        filters:{
            // 定义:过滤器名称fn(要过滤的数据data,参数1,参数2){return  操作}
            myFilter(data,name){
               return data + name;
            }
        }
    })
    let vm2 = new Vue({ 
        el:'#app2',
        
    })
    </script>
</body>
</html>
  1. 全局过滤器:
  1. 要公用的话,肯定不能放在实例上,要把它挂在构造函数Vue上,Vue.filter(函数名,函数)
  2. 放在构造函数上后,new的每个实例,都会有这个方法–这叫:全局过滤器
  3. 全局过滤器要放在页面的顶部,在new之前挂载好
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="shortcut icon" href="#" type="image/x-icon">
</head>
<body>
    <div id="app1">   
       {{'hello' | myFilter1('lxz')}}
    </div>
    <div id="app2">
        {{'hello' | myFilter1('lxz123')}}
    </div>
    <script src="node_modules/vue/dist/vue.js"></script>
    <script>
   /* 
    1. 要公用的话,肯定不能放在实例上,要把它挂在构造函数Vue上,Vue.filter(函数名,函数)
    2. 放在构造函数上后,new的每个实例,都会有这个方法--这叫:全局过滤器
    3. 全局过滤器要放在页面的顶部,在new之前挂载好
    */
    Vue.filter('myFilter1',(data,name)=>{   //filter 没有s,要一个一个的挂载
        return data + name ;
    })
    let vm1 = new Vue({ 
    	el:'#app1',      
    })
    let vm2 = new Vue({ 
        el:'#app2', 
    })
    </script>
</body>
</html>

2. computed 计算属性

  1. computed 里面是属性,不是方法
  2. 方法不会有缓存,computed里的计算属性会根据依赖(归vue管理的数据,可以响应式变化的)的属性进行缓冲,如果依赖的值不变,不会重新计算
  3. 计算属性有两部分组成:get 和 set (不能只写set),一般情况下通过js赋值影响其他人,或者 表单元素设置值的时候,会调用set方法
  4. computed 默认调用get方法,而且get方法必须有return, 但computed 不支持异步,可以用watch来解决
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="shortcut icon" href="#" type="image/x-icon">
</head>
<body>
    <div id="app">   
      全选 <input type="checkbox" v-model='checkAll'>
      <hr>
      <input type="checkbox" v-for='item in lists' v-model='item.isSelected'>
      <br>
      <br>
      <br>
      <hr>
      <input type="text" v-model='a'>{{msg}}
      <!-- 根据输入框的值,算出一个错误信息  -->
      </div>
    <script src="node_modules/vue/dist/vue.js"></script>
    <script>
        let vm = new Vue({ 
        el:'#app',
        computed:{//computed 默认调用get方法,而且get方法必须有return
            // 但computed 不支持异步,可以用watch来解决
            checkAll:{
                get(){
                    return this.lists.every(ele =>{   //return 什么结果,就给checkAll赋值什么
                        return ele.isSelected == true;
                    })
                },set(val){    //val是给checkAll赋值的时候传递过来的
                    this.lists.forEach(ele =>{
                        ele.isSelected = val;
                    })
                }
            },
            msg(){
                if(this.a.length < 3){
                    return '字数需要大于3位';
                }else if(this.a.length >6){
                    return '字数要小于6位';
                }else{
                    return '';
                }
            }
        },
        data:{
            a:'',
            lists:[
                {isSelected: true,name:'书'},
                {isSelected: false,name:'包'},
            ]
        }
    })
    </script>
</body>
</html>

3. watch 观察

  1. 观察a的变化,当a改变后做一件事(执行一个函数)
  2. 只有值变化的时候才会触发,支持异步,其他情况建议我们使用computed
  3. 可以在得到最终结果前,设置中间状态
    4.watch默认只监控一层的数据变化,比如,watch一个"[{a:1,b:2},{a:1,b:2},]"当给数据增加/删除子项的时候可以监听到,但修改数组里对象的属性的时候监听不到;它认为每项的引用地址没变化;所以我们需要 深度监控

普通写法( 一层):

watch:{
    lists(newVal , oldVal){  
    	this.msg = 'waiting......';   //,得到最终结果前,设置中间状态
        setTimeout(()=>{ console.log(newVal) },10)
    }
},

深度监控:以前写成函数,就相当于默认写了个handler方法

watch:{
    lists:{
    	handler(newVal , oldVal){ 
    		console.log(newVal) 
    	},deep:true
    }
},
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="shortcut icon" href="#" type="image/x-icon">
</head>
<body>
    <div id="app">   
      <input type="text" v-model='a'>{{msg}}
      </div>
    <script src="node_modules/vue/dist/vue.js"></script>
    <script>
        let vm = new Vue({ 
        el:'#app',
        computed:{  //computed 默认调用get方法,而且get方法必须有return
            // 但computed 不支持异步,可以用watch来解决

        },
        watch:{  //只有值变化的时候才会触发,支持异步,其他情况建议我们使用computed
            // 观察a的变化,当a改变后做一件事(执行一个函数)
            a(newVal , oldVal){   //watch的属性名要和观察的人的名字一致,一变就执行这个方法
            	this.msg = 'waiting......';   //,得到最终结果前,设置中间状态
                setTimeout(()=>{
                    if(newVal.length < 3 && newVal.length >0){ 
                         this.msg = '字数需要大于3位';   //这个return 不是返回,而是结束往下走,其实这里用的else if  不写return也可以
                    }else if(newVal.length >6){
                        this.msg = '字数要小于6位';
                    }else{
                        this.msg = '';
                    }
                },10)
            }
        },
        data:{
            a:'',
            msg:''   //这个值是页面一开始进入时的值
        }
    })
    </script>
</body>
</html>

除了上面那样写,也可以
vm.$watch(监听的数据 , 函数) $是自己内部的方法;主要==方法内部不能用this了,要用vm ==

vm.$watch('a' , (newVal , oldVal)=>{ xx })

watch 和 computed 选哪个好?

  1. 如果某个数据的获得用到了异步,就选watch;
  2. 没有用到异步的话,选computed,例如:一个数据fullName = firstName +secondName + lastName, 数据fullName的得到依赖多个数据,如果用watch的话比较麻烦,要观察多个,而用computed计算的话,只需写一个

面试题:watch,methods和computed的区别?

  1. methods和computed计算属性是基于它们的响应式依赖进行缓存的,只有依赖的数据变化时才会重新计算,而方法的话没有缓存,渲染或数据改变都有重新调用方法
  2. watch 和 computedwatch支持异步,computed不支持异步,但是一个数据的得到依赖多个数据的话用computed比较好
发布了57 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Eva3288/article/details/104250717