【问题标题】:Vue Reactivity: Creating reactive data with provide and injectVue 反应性:使用提供和注入创建反应性数据
【发布时间】:2021-03-07 17:52:36
【问题描述】:

我的目标是从 vue 前端验证用户的凭据,获取他们的数据,将数据存储在全局可用的变量中,并在任何组件中使用它们。经过一些工作,我可以将 Vue 的 reactive() 方法与 injectprovide 一起使用。这是我当前的代码:

store/index.js

import { reactive, inject } from 'vue'

// global states
export const stateSymbol = Symbol('state')
export const createState = () => reactive({
    backendRoute: 'http://127.0.0.1:8000/',
    currentUser: {},
    logIn: userData => {
        let user = createState.currentUser
        user = userData
        console.log(user)
    }
})

export const useState = () => inject(stateSymbol)

然后在 ma​​in.js

import { createApp } from 'vue'
import App from './App.vue'
// store modules
import { stateSymbol, createState } from './store'

// create app
const app = createApp(App)
app.provide(stateSymbol, createState())

然后在名为Login.vue

的登录/注册组件中
import { useState } from "../store"
import axios from 'axios'

export default {
    name: 'RegisterLogin',
    setup() {
       let state = useState()
       axios.get(getUser, jwtConfig).then(response => {
                userId = response.data.id
                const currentUser = getUserProfile+userId // URL
                console.log(currentUser)
                const getCurrentUser = axios.get(currentUser, jwtConfig)
                getCurrentUser.then(response => {
                    
                    state.logIn(response.data)
                    console.log(state.currentUser)

                })
            })
    }
}
store/index.js 中的

console.log(user) 按预期记录userData。我相信,createState.currentUser 应该被改变。然而问题是console.log(state.currentUser) 记录了一个空的代理对象。另外,如果我尝试从 Home.vue 等其他组件访问 state.currentUser:

<template>
{{ state.currentUser }}
</template>

<script>
import { useState } from '../store/'

export default {
        name: 'Index',
        setup() {

            return {
                state: useState(),
            }
        },
}
</script>

...即使用户成功登录,也始终显示一个空对象。有什么我做错了吗?感谢您的帮助(提前)。

【问题讨论】:

    标签: vuejs3 vue-composition-api vue-reactivity


    【解决方案1】:

    看来@Daniel 毕竟是对的。我在 store/index.js 中的logIn 方法并没有真正改变currentUser 属性。事实上,我无法从该方法访问该属性。为了解决这个问题,我必须在then 方法中的state.currentUser = response.data 之类的axios 调用之后立即进行突变,然后在所有组件中更新状态!谢谢。

    【讨论】:

      【解决方案2】:

      我正在查看代码,但找不到变量发生变异的任何地方,但我相信我知道发生了什么。

      您正在重新分配 user 对象,而不是将 createState.currentUser 分配给另一个对象。

      import { reactive, inject } from 'vue'
      
      // global states
      export const stateSymbol = Symbol('state')
      export const createState = reactive({
          backendRoute: 'http://127.0.0.1:8000/',
          currentUser: {},
          logIn: userData => {
              // over here you assign user to createState.currentUser
              let user = createState.currentUser; 
      
              // then you reassign user to `user data`
              user = userData
              console.log(user)
          }
      })
      
      export const useState = () => inject(stateSymbol)
      

      你可以试试

      import { reactive, inject } from 'vue'
      
      // global states
      export const stateSymbol = Symbol('state')
      export const createState = () => reactive({
          backendRoute: 'http://127.0.0.1:8000/',
          currentUser: {},
          logIn: userData => {
              createState.currentUser = userData
              console.log(createState.currentUser)
          }
      })
      
      export const useState = () => inject(stateSymbol)
      

      顺便说一句,你为什么使用inject?我不知道你期望它做什么。

      export const useState = () =&gt; stateSymbol 会得到相同的结果,但你甚至不需要传递函数,你可以使用更简洁的东西,比如......

      
      //////// store 
      
      import { reactive } from 'vue'
      
      // global states
      export const store = reactive({
          backendRoute: 'http://127.0.0.1:8000/',
          currentUser: {}
      })
      export const logIn = (userData) => {
          store.currentUser = userData
      }
      
      ////////////////////////////////////////////////
      ////// main
      
      import { store, logIn } from "../store"
      import axios from 'axios'
      
      export default {
          name: 'RegisterLogin',
          setup() {
             axios.get(getUser, jwtConfig).then(response => {
                      userId = response.data.id
                      const currentUser = getUserProfile+userId // URL
                      console.log(currentUser)
                      const getCurrentUser = axios.get(currentUser, jwtConfig)
                      getCurrentUser.then(response => {
                          logIn(response.data)
                          console.log(store.currentUser)
                      })
                  })
          }
      }
      

      【讨论】:

      • 感谢您的帮助。我之前尝试过将userData 分配给createState.currentUser 的方法,我得到了相同的结果。至于我为什么使用inject,我试图在不使用 Vuex 的情况下创建一个集中状态,因为我发现 Vuex 过于复杂。 [v3.vuejs.org/guide/composition-api-provide-inject.html] 根据官方文档,我可以使用injectprovide 在子组件之间共享数据。在我尝试全局变异 state.currentUser 之前,一切似乎都有效。
      • 你不需要provide/inject。它有一些用例,但如果你只是导入商店 (import { store } from "../store"),它可以从任何地方访问。
      • @Daniel 我用你的解释创建了一个全局对象。问题是我必须刷新页面才能获取对象。在此处查看更多详细信息:stackoverflow.com/q/65950533/10123373
      • 我现在也面临着类似的问题。据我所知,我们可以通过提供/注入模式来解决这个问题。但是即使在我的代码中,反应性也没有反映出来。发生了一些奇怪的事情,我无法找到自己。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-11
      • 1970-01-01
      • 2021-10-23
      • 1970-01-01
      • 1970-01-01
      • 2019-10-18
      • 1970-01-01
      相关资源
      最近更新 更多