1.filters 过滤器
- 如果有两个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>
- 全局过滤器:
- 要公用的话,肯定不能放在实例上,要把它挂在构造函数Vue上,Vue.filter(函数名,函数)
- 放在构造函数上后,new的每个实例,都会有这个方法–这叫:全局过滤器
- 全局过滤器要放在页面的顶部,在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 计算属性
- computed 里面是属性,不是方法
- 方法不会有缓存,computed里的计算属性会根据依赖(归vue管理的数据,可以响应式变化的)的属性进行缓冲,如果依赖的值不变,不会重新计算
- 计算属性有两部分组成:get 和 set (不能只写set),一般情况下通过js赋值影响其他人,或者 表单元素设置值的时候,会调用set方法
- 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 观察
- 观察a的变化,当a改变后做一件事(执行一个函数)
- 只有值变化的时候才会触发,支持异步,其他情况建议我们使用computed
- 可以在得到最终结果前,设置中间状态;
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 选哪个好?
- 如果某个数据的获得用到了异步,就选watch;
- 没有用到异步的话,选computed,例如:一个数据fullName = firstName +secondName + lastName, 数据fullName的得到依赖多个数据,如果用watch的话比较麻烦,要观察多个,而用computed计算的话,只需写一个
面试题:watch,methods和computed的区别?
- methods和computed:计算属性是基于它们的响应式依赖进行缓存的,只有依赖的数据变化时才会重新计算,而方法的话没有缓存,渲染或数据改变都有重新调用方法
- watch 和 computed:watch支持异步,computed不支持异步,但是一个数据的得到依赖多个数据的话用computed比较好