Computed 计算属性
被计算出来的属性就是计算属性,被当做属性来使用
实例1:用户名展示
import Vue from "vue/dist/vue.js";
Vue.config.productionTip = false;
new Vue({
data:{
user:{
email:"shuaige@qq.com",
nickname:"帅哥",
phone:"13012341234"
}
},
computed:{
displayName:{
get(){
const user = this.user;
return user.nickname || user.email || user.phone;
},
set(value){
this.user.nickname = value;
}
},
template:`
<div>
{{displayName}}
<div>
{{displayName}}
<button @click="add">set</button>
</div>
</div>
`
methods:{
add(){
this.displayName ='我真帅'
}
}
}).$mount("#app");
实例2:列表展示(不用computed写法)
import Vue from "vue/dist/vue.js";
Vue.config.productionTip = false;
let id = 0;
const createUser = (name, gender) =>{
id += 1;
return {id: id, name: name, gender: gender};
};
new Vue({
data(){
return{
users:[
createUser("方方", "男"),
createUser("圆圆", "女"),
createUser("小明", "男"),
createUser("小红", "女")
],
displayUsers:[]
};
},
created(){
this.displayUsers = this.user;
},
methods:{
showMale(){
this.displayUsers = this.users.filter(u => u.gender === "男");
},
showFemale(){
this.displayUsers = this.users.filter(u => u.gender === "女");
},
showAll(){
this.displayUsers = this.users;
}
},
template:`
<div>
<div>
<button @click="showAll">全部</button>
<button @click="showMale">男</button>
<button @click="showFemale">女</button></div>
<ul>
<li v-for="(u,index) in displayUsers" :key="index">{{u.name}} - {{u.genter}}
</ul>
</div>`
}).$mount("#app");
所有的v-for后面必须接一个key
<li v-for="(u,index) in displayUsers" :key="index">{{u.name}} - {{u.genter}}
filter 不会修改原数组,得到新数组把地址传给displayUsers
computed写法
import Vue from "vue/dist/vue.js";
Vue.config.productionTip = false;
let id = 0;
const createUser = (name, gender) =>{
id += 1;
return {id: id, name: name, gender: gender};
};
new Vue({
data(){
return{
users:[
createUser("方方", "男"),
createUser("圆圆", "女"),
createUser("小明", "男"),
createUser("小红", "女")
],
gender: ""
};
},
computed:{
displayUsers(){
const hash = {
male: "男",
female: "女"
};
const {user, gender} = this;
if(gender === ""){
return users;
}else if(typeof gender === "string"){
return users.filter(u => u.gender === hash[gender]);
}eles{
throw new Error("gender 的值是意外的值");
}
}
},
methods:{
setGender(string){
this.gender = string;
}
},
template:`
<div>
<div>
<button @click="setGender('')">全部</button>
<button @click="setGender('male')">男</button>
<button @click="setGender('female')">女</button></div>
<ul>
<li v-for="(u,index) in displayUsers" :key="index">{{u.name}} - {{u.genter}}
</ul>
</div>`
}).$mount("#app");
缓存
如果依赖的属性没有变化,就不会从新计算
getter和setter 默认不会做缓存,Vue做了特殊处理
watch 监听
当数据变化时,执行一个函数
实例1:撤销
import Vue from "vue/dist/vue.js";
Vue.config.productionTip = false;
new Vue({
data:{
n:0,
history:[],
inUndoMode:false
},
watch:{
n(newValue, oldValue){
if(!this.inUndoMode){
this.history.push({from: oldValue, to: newVlue});
}
}
},
templaye:`
<div>
{{n}}
<hr />
<button @click="add1">+1</button>
<button @click="add2">+2</button>
<button @click="minus1">-1</button>
<button @click="minus2">-2</button>
<hr/>
<button @click="undo">撤销</button>
<hr/>
{{history}}
</div>`
methods:{
add1(){
this.n += 1;
},
add2(){
this.n += 2;
},
minus1(){
this.n -= 1;
},
minus2(){
this.n -=2;
},
undo(){
const last = this.history.pop();
console.log(last);
const old = last.from;
this.inUndoMode = true;
this.n = old;
this.$nextTick(()=>{
this.inUnodMode = false;
},0)
}
}
}).$mount("#app");
实例2:模拟computed,但不好用,优先使用computed
import Vue from "vue/dist/vue.js";
Vue.config.productionTip = false;
new Vue({
data:{
user:{
email: "shuaige@qq.com",
nickname:"帅哥",
phone:"13012341234"
},
displayName:""
},
watch:{
'user.email':{
handler(){
const {user: {email, nickname, phone}} = this
this.displayName = nickname || email || phone
},
immediate: true
},
'user.phone':{
handler(){
const {user: {email, nickname, phone}} = this
this.displayName = nickname || email || phone
},
immediate: true
},
'user.nickname':{
handler(){
const {user: {email, nickname, phone}} = this
this.displayName = nickname || email || phone
},
immediate: true
},
}
template:`
<div>
{{displayName}}
<button @click="user.nickname=undefined">remove nickname</button>
</div>
`,
methods:{
changed(){
console.log(arguments);
const user = this.user;
this.displayName = user.nickname || user.email || user.phone;
}
}
}).$mount("#app");
match 数据变化
在vue里
如果把简单的数据类型的值变了,那它就变了
如果对象里的简单数据类型的值变了,对象不变,修改的数据变了,只做值的对比
如果一个对象的地址变了,vue才会认为对象变了
obj:{
handler(){
console.log('obj 变了')
},
deep: true
}
deep(深入进去看)不光比较obj的地址,任何东西都比较,任何东西变了,obj就变了
import Vue from "vue/dist/vue.js";
Vue.config.productionTip = false;
new Vue({
data:{
n:0,
obj:{
a:"a"
}
},
template:`
<div>
<button @click="n += 1">n+1</button>
<button @click="obj.a += 'hi'">obj.a + 'hi'</button>
<button @click="obj = {a:'a'}">obj = 新对象</button>
`,
watch:{
n(){
console.log("n 变了");
},
obj:{
handler(){
console.log("obj 变了");
},
deep: true
},
"obj.a":function(){
console.log("obj.n 变了");
}
}
}).$mount("#app");
vm.$watch('n', function(){
console.log('n 变了')
},{immdeiate: true})
watch 语法1
watch 不能使用箭头函数,没有this
new Vue({
data:n,
watch:{
n:()=>{ //箭头函数没有this
this.xxx //this是window全局的
}
}
})
watch:{
o2: function(value, oldValue){},
o3:(){}, o2的缩写
o4:[f1,f2], 在o4变化时,按顺序执行f1,f2函数
o5:'methodName', 去methods里找对应名字的函数
o6:{handler:fn, deep:true, immediate:true},'object.a':function(){}
}
语法2
vm.$watch('xxx', fn, {deep: ..., immediate: ..}
在vue外面使用
或者在vue里使用钩子
creatde(){
this.$watch('n',function(){
console.log('n 变了'),
{immediate: true}
})
}
computed 和 watch 的区别
computed 和 watch 的区别
commputed计算属性,是用来计算出一个值的,这个值被调用时
(1)不需要加括号,像属性一样
(2)根据依赖自动缓存,如果依赖不变,computed就不用从新计算
watch监听的意思
如果某个属性变化了,就去执行一个函数,有2个选项
(1)immediate 表示第一次渲染时是否执行这个函数
(2)deep 监听一个对象,是否看里面的属性变化
详细资料点击:Vue 计算属性