美文网首页
关于在Vue生命周期钩子中无法获取数据的一些理解

关于在Vue生命周期钩子中无法获取数据的一些理解

作者: e93a88ffeabd | 来源:发表于2018-03-10 23:15 被阅读0次

    前言

    以前做项目的时候偶然遇到了一个问题,在一个组件中使用vuex更新了一个依赖数组,原本打算在另一个组件中通过监测这个数组的更新去动态的改变一些值,但是在这个组件中通过Vue提供的mounted生命周期并没有直接的获取到这个数组的更新,纠结了很久,当然最后还是完美解决了。具体如何解决的,继续往下看

    问题复现

    自己模拟了一下业务场景,大概就是这样的情况:

    <!-- 在页面中有page1与page2两个兄弟组件 -->
    <template>
      <div id="app">
        <page1></page1>
        <page2></page2>
      </div>
    </template>
    
    <script>
    import page1 from './son/page1.vue'
    import page2 from './son/page2.vue'
    
    export default {
      name: 'app',
      components: {
        page1,
        page2
      }
    }
    </script>
    

    vuex

    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    export default new Vuex.Store({
      state: {
        content: 'initial'
      },
      mutations: {
        sendCon (state, Payload){
          state.content = Payload
        }
      }
    })
    

    page1

    <template>
      <div id="page1" @click="clickMe">{{content}}</div>
    </template>
    
    <script>
    export default {
      name: 'page1',
      data() {
        return {
          content: '点我试试!'
        }
      },
      methods: {
        // 通过对page1执行点击事件,将内容进行更新
        clickMe() {
          this.$store.commit('sendCon', 'change')
        }
      }
    }
    </script>
    

    page2

    <template>
      <div id="page2"></div>
    </template>
    <script>
    
    export default {
      name: 'page2',
      mounted() {
        // 在page2的mounted阶段进行打印,发现控制台打印出来的是"initial"
        // 但在vue的调试工具中可以看到,this.$store.state.content这个值却是"change"
        console.log(this.$store.state.content)
      }
    }
    </script>
    
    控制台为空
    devtool却有值

    原因

    那么,为什么会出现这样的原因呢?
    先上一张生命周期的图例


    vue生命周期
    • vue的生命周期大致分三个阶段,分别是creatmountdestroy
    • 在我们遇到的mount阶段,mounted钩子在整个生命周期中只会触发一次而beforeUpdateupdated函数是在与dom绑定的数据发生变动后才会触发的函数

    所以,我们一开始打印的时候出来的是initial,而将state.content改变后确实无法再次打印出新的值

    验证

    将page2的代码进行更改:

    <template>
      <div id="page2" @click="changeCon">{{store}}</div>
    </template>
    
    <script>
    export default {
      name: 'page2',
      computed: {
        store() {
          return this.$store.state.content
        }
      },
      created() {
        console.group('created!')
        console.log('store:', this.store)
      },
      beforeMount() {
        console.group('beforeMount!')
        console.log('store:', this.store)
      },
      mounted() {
        console.group('mounted!')
        console.log('store:', this.store)
      },
      beforeUpdate() {
        console.group('beforeUpdate!')
        console.log('store:', this.store)
      },
      updated() {
        console.group('updated!')
        console.log('store:', this.store)
      }
    }
    </script>
    
    初始状态
    数据变化触发函数

    但是如果我们将store这个值从dom的绑定上取消,再次执行代码会发现:


    检测不到数据变化

    如何解决

    vue提供了watch方法监听组件内数据的变化,其使用的是ES6提供的Object.defineProperty方法,将vue的data全部转化成Object.defineProperty,当data中的属性被修改后,会触发set函数,从而达到监听数据的目的
    再次修改data2的代码:

    watch: {
      store() {
        console.log('store:', this.store)
      }
    }
    
    watch监测到数据变化

    相关文章

      网友评论

          本文标题:关于在Vue生命周期钩子中无法获取数据的一些理解

          本文链接:https://www.haomeiwen.com/subject/hflyfftx.html