Vue 简单状态管理Store模式下无法 watch 到改变后的数据

发布于 2022-09-11 20:24:26 字数 3104 浏览 14 评论 0

问题:
使用 Vue 简单状态管理Store模式,组件中可以获取到 store 中的数据,
在组件中通过事件改变 store 中的值,并提交到 store 后,在 store 中可以打印出改变后的值,但在组件中通过 watch 无法监听到最新值的变化

store.js

let store = {
  state: {
    message: 'Hello!'
  },
  setMessageAction(newValue) {
    this.state.message = newValue
    console.log('store.js - newValue:', this.state.message); // 当组件改变数据后这里是可以获取到改变后的最新值的
  },
}
export default store

main.js 中引入 store

// 简单 store 模式
import store from './store'
Vue.prototype.$store = store

组件中使用 store

<template>
  <div>
    <hr>
    <h1>{{message}}</h1>
    <button @click="change">change Store</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: ''
    }
  },
  created() {
    this.message = this.$store.state.message
  },
  watch: {
    '$store.state.message': function (newVal) { // watch 无法获取组件改变后的新值
      console.log(newVal);
      console.log(this.$store.state.message);
    }
  },
  methods: {
    change() {
      this.$store.setMessageAction('change hello world')
    }
  },
}
</script>

============================== 分割线 ===================================

在 asseek 和 夕水 的提示下已经解决问题,下面是我实现的方法,有更好的方法请指出,谢谢:

两种解决方案:

  1. 使用 Vue.observable
    在组件中可以直接调用 state 中的某个值
  2. 引用 store.state 对象
    组件中使用需要先把 state 赋值给组件中 data 选项

解决方案1:

修改 store.js 如下:
state 用 observable 定义来实现响应式

let store = {
  state: Vue.observable({
    message: 'Hello!'
  }),
  setMessageAction(newValue) {
    this.state.message = newValue
    console.log('store.js - newValue:', this.state.message);
  },
}
export default store

组件调用:

<template>
  <div>
    <hr>
    <h1>{{msg}}</h1>
    <button @click="change">change Store</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      num: 0
    }
  },
  computed: {
    msg() {
      return this.$store.state.message;
    }
  },
  methods: {
    change() {
      this.$store.setMessageAction(this.num++)
    }
  },
}
</script>

解决方案2:

store.js

let store = {
  state: {
    message: 'Hello!'
  },
  setMessageAction(newValue) {
    this.state.message = newValue
    console.log('store.js - newValue:', this.state.message);
  },
}
export default store

组件:

<template>
  <div>
    <hr>
    <h1>{{msg}}</h1>
    <button @click="change">change Store</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      state: '',
      num: 0
    }
  },
  created() {
    // 注意:这里需要赋值 state 对象,而不能直接赋值对象中的某个值,否则不能触发响应式
    this.state = this.$store.state 
  },
  computed: {
    msg() {
      return this.$store.state.message;
    }
  },
  methods: {
    change() {
      this.$store.setMessageAction(this.num++)
    }
  },
}
</script>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

涫野音 2022-09-18 20:24:26

你的store.js只是个暴露个普通对象,是什么原因让你认为它是响应式的会被watch
你可以把state的数据用 Vue.observable 来处理一下,应该是可以的,没这么玩过,未实测

疑心病 2022-09-18 20:24:26

不能这样监听,你可以用计算属性来表示,

computed:{
    msg(){
        //msg就是动态的
        return this.$store.state.message;
    }
}
小草泠泠 2022-09-18 20:24:26

没这么玩过 vuex提供的语法糖干嘛不用

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文