Vuex - 将状态的对象传递到另一个状态的对象

时间:2018-02-17 07:36:44

标签: vue.js state store vuex

在Vuex中我试图将一个状态的对象(在这种情况下是一个字符串)传递给另一个状态的对象,但它返回未定义。

state: {
   notifications: [
      { key: "success",
        notification: "Awesome " + this.theName + "! Success.", 
        redirectPath: "/home"
      },
      { key: "error",
        notification: "Oh no " + this.theName + "... Error.", 
        redirectPath: "/error"
      }
   ],
   theName: 'Ricky Bobby' // this would normally come from a mutation method - see below
}

theName上面的例子只是用于测试的硬编码,但它的值来自变异方法。我知道它进入商店的状态,因为我能够控制登录它。但是notifications对象内的字符串插值不起作用。如何将传入的值传递到notifications.notification值?

我不知道这是否有帮助,但这是变异示例:

mutations: {
   loginSuccess(state, payload){
      state.theName = payload.uName;
   }
}

1 个答案:

答案 0 :(得分:0)

您的代码存在两个问题。首先,this无法按照您尝试的方式运行。在您的问题this中,每个通知中都没有引用state或代码的任何其他部分。它的值是全局窗口对象或undefined,取决于您是否处于严格模式:

const object = {
   propName: this,
};

console.log(object.propName);

其次,您的代码是异步的,因此theName会不时更改,但您实际上从未在通知中重新定义消息字符串。而且它们本身不会“重新计算”:

let surname = 'Whyte';

const object = {
  fullName: 'Pepe ' + surname,
};

console.log(object.fullName);

setTimeout(() => {
  surname = 'White';
  console.log(object.fullName);
  console.log('the value of \'surname\' variable is ' + surname + ' though.');
}, 2000);

在您的情况下,您可以将通知定义为函数:

notification(name) { return "Awesome " + name + "! Success."}

然后编写一个getter用于通知并将名称传递给该函数。

或者作为替代方案,您可以在函数内部引用对象本身。像这样:

let surname = 'Whyte';

const object = {
  person: {
    firstName: 'Pepe ',
    fullName: () => {
      return object.person.firstName + ' ' + surname;
    },
  }
};

console.log(object.person.fullName());
setTimeout(() => {
  object.person.firstName = 'Keke';
  console.log(object.person.fullName());
}, 1000);

UPD:我为你做了另一个例子。很难说出你将如何调用此通知,但这里有两个选项可以按照你想要的方式访问它们(jsfiddle):

const store = new Vuex.Store({
  state: {
    theName: 'Ricky Bobby',
    // accessing `theName` prop inside state (probably won't be possible in the real project or very inconvinient due to modularity)
    successNotificationInState: () => `Awesome ${store.state.theName}! Success.`,
  },
  // accessing the same prop with getter
  getters: {
    successNotification: (state) => `Awesome ${state.theName}! Success.`,
  },
  mutations: {
    loginSuccess(state, payload) {
      state.theName = payload.uName;
    },
  },
  actions: { // let's emulate a login
    login({
      commit
    }) {
      return new Promise(fullfil => {
        setTimeout(function() {
          console.log('logging in')
          const response = {
            uName: 'Keke',
            email: 'keke@gmail.com',
          }
          fullfil(response);
          commit('loginSuccess', response);
        }, 2000);
      });
    },
  },
});

const app = new Vue({
  el: "#app",
  store,
  data: {
    msgGetter: '',
    msgState: '',
  },
  computed: {},
  methods: {
    login() {
      this.$store.dispatch('login').then((response) => {
        console.log(response);
        console.log(this.$store);
        this.msgGetter = this.$store.getters.successNotification;
        this.msgState = this.$store.state.successNotificationInState();
      });
    },
  },
  mounted() {
    this.login();
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.js"></script>
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <p>Message from state: {{msgState}}</p>
  <p>Message from getter: {{msgGetter}}</p>
</div>