如何将状态映射回 Vue.js AWS Amplify 授权页面中的组件

How to map state back to component in Vue.js AWS Amplify auth page

我正在使用 Vue.js、Vuex 和 AWS Amplify 构建身份验证页面。

此授权页面基于 Erik Hanchett 的 AWS 授权示例 (https://github.com/ErikCH/Aws-auth-example/blob/master/src/components/HelloWorld.vue)。 Erik 的原始演示使用 Vuex 进行状态管理,但为了简单起见,仅使用 store.js 文件中的 state 处理程序。

我正在尝试重新配置此演示,以便设置 HelloWorld.vue 中的各种方法和挂钩,以分派操作和提交变更。

到目前为止,我已经成功地在HelloWorld.vue中设置了findUser()方法来调度动作,将usersignedIn作为负载传递给它们各自的action 处理程序,然后提交突变。

但是,我的问题现在与 HelloWorld 组件中的 computed 属性 有关。

Erik 的原始演示 return 使用 return this.$store.state.signedIn 将状态直接发送到组件,如 computed 属性 中所示。根据我在其他项目中使用 Vuex 的经验,我通常会使用 mapState 助手直接映射到状态。

在这个项目中使用this.$store.state.signedIn到return状态是否正确?或者我应该使用 mapState?如果是这样,我如何重新配置​​此 computed 属性 以便使用 mapState 直接映射到 signedIn

我的代码如下:

HelloWorld.vue

<template>
  <div class="hello">
    <div v-if="!signedIn">
      <amplify-authenticator></amplify-authenticator>
    </div>
    <div v-if="signedIn">
      <Home></Home>
    </div>
  </div>
</template>

<script>
import { Auth } from 'aws-amplify'
import { AmplifyEventBus } from 'aws-amplify-vue';
import { mapState } from 'vuex'
import Home from '../components/Home.vue'
export default {
  name: 'HelloWorld',
  components: {
    Home
  },
  data() {
    return {
      login: '',
      password: ''
    }
  },
  props: {
    msg: String,
  },
  created(){
    this.findUser();
    AmplifyEventBus.$on('authState', info => {
      if(info === "signedIn") {
        this.findUser();
      } else {
        this.$store.state.signedIn = false;
        this.$store.state.user = null;
      }
    });
  },
  computed: {
    signedIn(){
      return this.$store.state.signedIn;
    }
  },
  methods: {
    async findUser() {
      try {
        const user = await Auth.currentAuthenticatedUser();
        let signedIn = true
        this.$store.dispatch('setUser', user)
        this.$store.dispatch('setSignedIn', signedIn)
      }
      catch(err) {
        let signedIn = false
        this.$store.dispatch('setSignedIn', signedIn)
      }
    }
  }
}
</script>

Store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    user: null,
    signedIn: false
  },
  mutations: {
    setUser(state, user) {
      state.user = user
    },
    setSignedIn(state, signedIn) {
      state.signedIn = signedIn
    }
  },
  actions: {
    setUser: (context, user) => {
      context.commit('setUser', user)
    },
    setSignedIn: (context, signedIn) => {
      context.commit('setSignedIn', signedIn)
    }
  }
})

Home.vue

<template>
  <div class="goodbye">
    <h1>HOME</h1><br>
      <amplify-sign-out></amplify-sign-out>
  </div>
</template>

<script>
import { Auth } from 'aws-amplify'
export default {
  name: 'Home',
  data() {
    return {
      login: '',
      password: ''
    }
  },
  props: {
    msg: String,
  },
  methods: {
    signOut() {
      Auth.signOut()
    }
  }
}
</script>

mapState 助手只是糖语法,用于不重复整个 this.$store.state.foo 段代码。

你当然可以像这样使用mapState

import { mapState } from 'vuex'

computed: mapState([
  // map this.signedIn to this.$store.state.signedIn
  'signedIn'
])

或者如果你还想使用 mapState

之外的本地属性
import { mapState } from 'vuex'

computed: 
   localComputed () { /* ... */ },
   ...mapState([
   // map this.signedIn to this.$store.state.signedIn
     'signedIn'
   ])

这里是 docs 以了解更多信息。