Vue computed watch

  • 计算属性 computed
    不需要加括号
    会根据依赖是否变化来缓存

  • watch 侦听
    一旦data发生变化,就执行的函数
    options.watch用法
    this.$watch用法
    deep,immediate含义

data 变化的时候除了更新UI 还能做点啥?

计算属性 computed

用途:
被计算出来的属性就是计算属性

需求1 div中展示用户的名字,点击会更set
new Vue({
  data: {
    user: {
      email: "fangyinghang@qq.com",
      nickname: "方方",
      phone: "13812312312"
    }
  },
  template: `
    <div>//没有名称就展示email,再没有就展示phone
       {{user.nickname || user.email || user.phone}}   
     <div>
//但是我可能多个地方展示,难道要一直复制这一堆吗? 
       {{user.nickname || user.email || user.phone}}
     </div>
    </div>
  `
}).$mount("#app");

如果有一天要优先展示phone 那要把每个地方都改掉?
使用计算属性computed 来计算 displayName
computed
  computed: { 
//    displayName() {两种写法 函数写法和对象写法
 //       const user = this.user;
 //       return user.nickname || user.email || user.phone;
 //   }
    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"></button>
      </div>
    </div>
  `,
  methods: {
    add() {
      console.log("add");
      this.displayName = "圆圆"; //set的使用
    }
  } 点击按钮变成圆圆
这样即可。改了需求只需要改displayName
计算属性可以让 某些根据其他属性计算而来的属性变成一个属性displayName是个方法,可以当作属性来用默认读取返回值

两种写法,第一种函数写法就是默认的get.


1
需求二 展示列表 点击男 展示男 点击女 展示女
2

1、不使用计算属性:需求二

注:
User不能改 删了不好弄回来,所以复制一份 到 displayUsers
filter 不会修改原数组而是得到一个新的数组
v-for 后面必须要有key

2、使用计算属性
思路: 如何计算出来呢?
result = f(user,gender) 就是一个函数传入两者得到结果
通过 uesr(列表) 和 gender(筛选的性别) 计算出来

const { users, gender } = this;
解构赋值
const users = this.users
const gender = this.gender
U})2P0)W09SIQOG`41`_SL6.png

简化版:

需求二

computed 特性
默认有缓存:如果我依赖的属性没有变化,我的计算属性就不会再算一次
就如需求二
我进页面 计算一次
点男 计算一次 此时我再点男他就不计算了,因为没有变

Watch 监听

当数据变化时,执行一个函数

computed也是数据变了 计算出一个新的属性
所以面试常问他俩的区别

示例1 撤销
https://codesandbox.io/s/lucid-shamir-cpcw3

new Vue({
  data: {
    n: 0,
    history: [],
    inUndoMode: false  //由于撤销的时候也会触发watch 所以用它来控制
  },
  watch: { 当n变化的时候执行这个函数,记录 n从什么变为什么
    n: function(newValue, oldValue) {
      console.log(this.inUndoMode);
      if (!this.inUndoMode) {
        this.history.push({ from: oldValue, to: newValue });
      }
    }
  },

  template: `
    <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();
      this.inUndoMode = true;
      console.log("ha" + this.inUndoMode);
      const old = last.from;
      this.n = old; 

      this.$nextTick(() => {  这里必须要这样写 
        this.inUndoMode = false;
      });
    }
  }
}).$mount("#app");

如果这样写不行this.inUndoMode = false;
watch n 的函数会异步调用,写完之后不会立即执行上面的代码,因为watch是异步的,所有代码执行完了才会去执行,所有代码执行完了 ,它还是false还是会触发push
所以 就再异步一下 setTimeOut也行
this.nextTick(() => { 这里必须要这样写 this.inUndoMode = false; }); this.n = old; 会触发异步操作 this.nextTick也会触发
由于this.n = old在上面所以肯定时它的异步先执行

示例2 模拟computed
https://codesandbox.io/s/objective-star-vu2h3

注:
handler 就是如何处理他的变化
immediate: true就是让 第一次渲染是也触发 watch(本来watch 在进入页面第一次渲染的时候你没有变化就不会触发它 但是不触发它就显示不了我的内容)

什么叫做数据变化

对watch 来说 或者对vue的所有监听器来说 什么叫做变化
https://codesandbox.io/s/still-snowflake-m62t1?file=/src/main.js:89-540

new Vue({
  data: {
    n: 0,
    obj: {
      a: "a"
    }
  },
  template: `
    <div>
      <button @click="n += 1">n+1</button>
       <button @click="obj = {a:'a'}">obj = 新对象</button>//此时 obj 变了 a还是原来的值就没有变
      <button @click="obj.a += 'hi'">obj.a + 'hi'</button>//注意 此时 obj没变 a变了
    </div>
  `,
  watch: {
    n() {
      console.log("n 变了");
    },
    obj() {
      console.log("obj 变了");
    },
    "obj.a": function() {
      console.log("obj.a 变了");
    }
  }
}).$mount("#app");

总结 如果你把一个简单数据类型变了 那他一定变了
如果你把一个对象里面的简单类型 变了 也是变了 只做值的对比
你把一个对象地址变了 才认为你对象变了 然后依然对里面的a做值的对比

简单类型看值 复杂类型看地址

deep:true

但是 我现在有个需求 就是 只要对象中的一个属性变了 就都算obj变了 行不行 ? 行 使用 deep:true

obj:{
  handler(){   console.log("obj 变了");},
  deep:true  
}

那就不用监听 a b啥的了 监听obj就行了
deep就是往深了看

watch的完整语法

接受一个对象[key:string]: value(string|Function|Object|Array)


WIL2BQ{WE52VIU09~16G@%J.png

function(value,oldValue){}
两个参数 vue传给你的  第一个最新的值  第二个之前的值
(){}缩写
[ f1,f2]
'methodName' 在methods中去找对应的函数
{handler:fn(触发后要执行的函数),deep:true,immediate:true}

或者在 vm(外面)/this(里面).$watch('n',function(){console.log('n变化了')},{deep:true,immediate:true})

不要使用箭头函数
箭头函数中的this是全局对象(window)
箭头函数里是没有this的,只能继承外面的this 外面没有函数
箭头函数的this是他外面函数的this

function x (){
 ()=>{}
}

new Vue() 只是调用 不是它外面的函数

const vm = new Vue({
  watch:{
    n:function(){
      this === vm
    }
  }
})

面试题:两者的区别
1、 英译汉 
computed就是计算属性的意思 watch就是监听的意思
2、各自描述 可以代码举例子
computed是用来计算出一个值的
里面的函数调用的时候不需要加()可以当属性一样用
根据依赖自动缓存  如果依赖的值不变呢 就不会重新计算
watch是用来监听的
如果某个属性变化了就会执行一个函数
有两个选项 
第一个就是immediate 表示是否再第一次渲染时执行这个函数
第二个时deep 就是我们监听一个对象是否要看对象里面属性的变化

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容