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

2018-03-10  本文已影响0人  e93a88ffeabd

前言

以前做项目的时候偶然遇到了一个问题,在一个组件中使用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生命周期

所以,我们一开始打印的时候出来的是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监测到数据变化
上一篇 下一篇

猜你喜欢

热点阅读