Vue:如何在挂载钩子之前使用 mapState 的值?

Vue : How to use the values of mapState earlier than mounted hook?

我想在 mounted hook 之前使用 mapState 的值,这样我就可以使用 'authority' 的值,如果 'authority' 是 1 那么我将使用函数 getUserList, 否则我将使用函数 getUserSingle.

但是我不能这样使用它。我可以通过哪些方式更早地使用 mapState 值?

<template>
  <table v-if="authority==1">
    <tr>
      <th>Number</th>
      <th>Date</th>
      <th>Name</th>
      <th>ID</th>
      <th>Phone</th>
      <th>department</th>
      <th>authority</th>
    </tr>
    <tr v-for="(data, i) in userList" :key="i">
      <td>{{ data.idx }}</td>
      <td>{{ moment(data.create_dt).format('YYYY.MM.DD') }}</td>
      <td>{{ data.username }}</td>
      <td>{{ data.account }}</td>
      <td>{{ data.mobileNo }}</td>
      <td>{{ data.department }}</td>
      <td>{{ data.authority === 1 ? 'admin' : 'user' }}</td>
    </tr>
  </table>
  <table v-else>
    <tr>
      <th>Number</th>
      <th>Date</th>
      <th>Name</th>
      <th>ID</th>
      <th>Phone</th>
      <th>department</th>
      <th>authority</th>
    </tr>
    <tr v-for="(data, i) in userSingle" :key="i">
      <td>{{ data.idx }}</td>
      <td>{{ moment(data.create_dt).format('YYYY.MM.DD') }}</td>
      <td>{{ data.username }}</td>
      <td>{{ data.account }}</td>
      <td>{{ data.mobileNo }}</td>
      <td>{{ data.department }}</td>
      <td>{{ data.authority === 1 ? 'admin' : 'user' }}</td>
      
    </tr>
  </table>
</template>

<script>
import { fetchUserList, fetchUserSingle } from '@/api/index'
export default{
  data() {
    return {
      moment: moment,
      userList: [],
      userSingle: [],
    }
  },
  mounted() {
    this.$bus.$on('closeModal', () => {
      if(this.authority == 1){
        this.getUserList()
      }else{
        this.getUserSingle(this.idx)  // this.idx from mapState
      }
      this.closeModal()
    })
    if(this.authority == 1){
      this.getUserList()
    }else{
      this.getUserSingle(this.idx)  // this.idx from mapState
    }
  },
  computed: {
    ...mapState('store', {
      idx: (state) => state.id,
      authority: (state) => state.authority,
    }),
  },
  methods: {
    getUserList() {
      fetchUserList().then((res) => {
        if (res.status == 200) {
          this.userList = res.data
        } else {
          return alert(res.data.message)
        }
      })
    },
    getUserSingle(idx) {
      fetchUserSingle(idx).then((res) => {
        if (res.status == 200) {
          this.userSingle = res.data
        } else {
          return alert(res.data.message)
        }
      })
    }
  }
}
</script>

你还没有画出从中获取 authority 值的完整图片,但我假设你从 API 中获取它,然后将其存储在 [=13] =](状态,Vuex)。如果是这样,那么它与 mounted hook 本身无关。这实际上取决于您的互联网连接,有时在 mounted 之前,有时在之后。我们永远不会知道。对于这种情况,我能想到的解决办法有两种:

  1. 如果这个组件是另一个组件的子组件,换句话说,不直接附加到当前路由。您可以在父组件中的此组件上放置一个 v-if="authority !== null"。显然你必须在开始时初始化 authority = null

像这样:

<parent-component>
  <this-component v-if="authority !== null" />

</parent-component>

通过这样做,该子组件将仅在 authority 可用时才开始其生命周期(我假设为 0 或 1,而不是 null)。 v-if 会延迟你的组件直到表达式 return true 才被渲染,那么你可以安全地依赖 mounted 钩子,甚至是 created 钩子案例.

  1. 如果此组件不是任何组件的子组件,则必须在 mounted 挂钩(或 created 中使用动态观察器 vm.$watch,此处无关紧要).然后开始watchcomputed属性authority,在第一个运行.
  2. 后拆掉这个watcher

示例:

mounted() {
  this.$bus.$on('closeModal', () => {
      if(this.authority === 1){
        this.getUserList()
      }else{
        this.getUserSingle(this.idx)  // this.idx from mapState
      }
      this.closeModal()
  })

  // sometimes `authority` is available in `mounted`, then do the work

   if(this.authority === 1){
      this.getUserList()
    }else if (this.authority === 0) {
      this.getUserSingle(this.idx)  // this.idx from mapState
    } else { 

      // in case it's not ready yet, set up watcher
      const unwatch = this.$watcher('authority', () => {
      if (this.authority === null) return

      if(this.authority === 1){
        this.getUserList()
      }else{
        this.getUserSingle(this.idx)  // this.idx from mapState
      }

       unwatch() // this is how you tear down this watcher after first run
     })

   }


}

无论如何,看起来您需要就此进行一些代码重构。可能将逻辑包装在一个函数中然后重用它。