一 、先来复习生命周期

    1. 创建阶段:
      beforeCreat created created 最早可以在这发送请求和调用数据
      beforeMount mounted mounted 创建后最早操作dom元素
    2. 更新阶段:
      Beforeupdate 数据变化视图没变 = 数据驱动
      Updated 数据变化视图(页面)变化
    3. 销毁阶段:销毁之前做些清理工作,清除定时器、清除window所有事件
      beforeDestroy 销毁之前 destroyed 销毁之后
      Activeted Deactived keep alive专属

    二、上代码看执行顺序

    1. <template>
    2. <div>
    3. <p> {{ firstNum }} </p>
    4. <p> {{ secondNum }} </p>
    5. <p> {{ thirdNum }} </p>
    6. </div>
    7. </template>
    8. <script>
    9. export default {
    10. computed: {
    11. secondNum() {
    12. // firstNum 从一开始就与之绑定关联
    13. console.log('secondNum is computing: ' + this.firstNum * 100)
    14. return this.firstNum * 100
    15. }
    16. },
    17. data() {
    18. return {
    19. firstNum: 0,
    20. thirdNum: 0
    21. }
    22. },
    23. watch: {
    24. firstNum(val) {
    25. // firstNum 只有在发生改变时,才会进入该逻辑
    26. console.log('firstNum is watched: ' + val)
    27. this.thirdNum = val * 100
    28. }
    29. },
    30. created() {
    31. console.log('初始化created');
    32. // 该步骤在 data() 数据实例化之前。
    33. // 此时改变 data() 中的数据是不会触发 change 事件的,无法进入 watch 代码部分。
    34. this.firstNum = 1
    35. },
    36. mounted() {
    37. // 该步骤在 data 数据实例化之后。
    38. // 此时改变 data 中的数据是会触发 change 事件的,也就能被 watch 到。
    39. this.firstNum = 2
    40. }
    41. }
    42. </script>

    控制台输出为:
    image.png

    1. 是created先执行;因为created是初始化data中的值。因此最先执行;
    2. 然后是 执行computed中的,因为此时html正在被渲染,computed发生在 beforeCreate 和 created之间;
    3. 是monted()因为这个函数此时已经将页面渲染完成了;
    4. 最后执行watch;
    5. 默认加载的时候先computed再watch,不执行methods;等事件触发或者深度监听后,则是:先methods再watch;
    6. 这里主要用到的是解决mounted加载,缓存赋值,然后进行watch监听触发逻辑,最后异步对特定值进行再次赋值,再次赋值需要深拷贝;

    三、区分data/computed/watch:

    1. data属性的值,不会随赋值变量的变化而变化。如果要改变这个属性的值,则需要直接给data属性赋值,视图上对这个属性的显示才会变。
    2. computed是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。
    3. 如果在某个数据变化时做一些事情,使用watch来监听;用于观察props、$emit或者本组件的值,当数据变化时来执行回调进行后续操作,没有缓存;

    四、watch的使用

    1. 直接监听

      1. watch: {
      2. cityName: 'nameChange'
      3. }
      4. }
    2. 就是当值第一次绑定的时候,不会执行监听函数,只有值发生改变才会执行。如果我们需要在最初绑定值的时候也执行函数,则就需要用到immediate属性,immediate设为true。

      1. watch: {
      2. cityName: {
      3.   handler(newName, oldName) {
      4.   // ...
      5.   },
      6.   immediate: true
      7. }
      8. }
    3. 深度监听
      当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。 ```vue

    new Vue({ el: ‘#root’, data: { cityName: {id: 1, name: ‘shanghai’} }, watch: { cityName: { handler(newName, oldName) { // … }, deep: true, immediate: true } } })

    1. 设置deep: true 则可以监听到cityName.name的变化,此时会给cityName的所有属性都加上这个监听器,当对象属性较多时,每个属性值的变化都会执行handler。如果只需要监听对象中的一个属性值,则可以做以下优化:使用字符串的形式监听对象属性:
    2. ```vue
    3. watch: {
    4. 'cityName.name': {
    5. handler(newName, oldName) {
    6. // ...
    7. },
    8. deep: true,
    9. immediate: true
    10. }
    11. }