【问题标题】:Update a component from another component in Vue2从 Vue2 中的另一个组件更新一个组件
【发布时间】:2021-07-23 16:17:32
【问题描述】:

我有 2 个组件。标题和登录。

在标题中

<a v-if="isLoggedIn" href="/#/insurance">
 <img src="@/assets/images/user.svg" class="profile_img">
 </a>
 <a v-else href="/#/login">
 <img src="@/assets/images/login.svg" class="profile_img">
 </a>

我想在header 处切换isLoggedIn truefalse,同时在login 处调用方法

我试过在登录时输入这个

var userState = new Vue();
 userState.$emit('userState', true)

这个在标题上

updated(){
    userState.$on('userState', function(state) {
      this.isLoggedIn = state
    })

但它不起作用。你能帮我么?谢谢

【问题讨论】:

  • 如果您需要两个不相关的组件进行对话,请使用带有 props/emit 或 vuex 存储的公共父组件(app.vue 或布局组件)。将 Vue 用作 EventBus(当您想升级到 Vue3 时,不推荐使用 var userState。

标签: vue.js vuejs2 vue-component vuex


【解决方案1】:

典型的解决方案是使用 Vuex(它是一个状态管理模块)。我不会在我的回答中介绍 Vuex。我只推荐它。它很强大,您最终会比您想象的更快地需要它。使用Vue.observable(如下所示)仅在简单情况下有用。当您开始需要 async 行为时,可能是时候开始使用 Vuex。


这是更简单的解决方案:Vue.observable():

声明一个Vue.observable(),其中包含您想在两个组件之间共享的任何内容。将其放在文件中并导出:例如:

export default Vue.observable({
  isLoggedIn: false
})

在您想要读取或写入该状态对象的任何组件中,将其导入:

import userState from '../path/to/userState.js'

如果您只想从中读取,请将其用作简单的计算:

computed: {
  isLoggedIn() { return userState.isLoggedIn }
}

如果你也想写入它,请将其用作 setter + getter 计算:

computed: {
  isLoggedIn: {
    get() { return userState.isLoggedIn; } 
    set(value) { userState.isLoggedIn = value; }
  }
}

就是这样,真的。工作示例:

const userState = Vue.observable({
  isLoggedIn: false
});

Vue.component('header-component', {
  template: `
<label>
  <input type="checkbox" v-model="isLoggedIn">
  Logged in
</label>
  `,
  computed: {
    isLoggedIn: {
      get() {
        return userState.isLoggedIn
      },
      set(value) {
        userState.isLoggedIn = value
      }
    }
  }
});

Vue.component('footer-component', {
  template: `<pre v-text="{ isLoggedIn }"></pre>`,
  computed: {
    isLoggedIn() {
      return userState.isLoggedIn
    }
  }
});

new Vue({
  el: '#app'
})
body {
  margin: 0;
}

#app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

#app>* {
  padding: 1rem;
  border: 1px solid #eee;
}

#app main {
  flex-grow: 1;
}

#app pre {
  margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<div id="app">
  <header-component></header-component>
  <main>main content here...</main>
  <footer-component></footer-component>
</div>

注意:Vue.observable() 是在 Vue 中引入的 2.6
如果你想在之前的版本中使用这个功能,你可以使用 Vue 实例而不是 observable。
当您想要访问 Vue 实例必须提供的所有内容时,使用成熟的 Vue 实例而不是 Vue.observable 也很有用:观察者、计算、方法 - 可能是异步等......

const userState = new Vue({
  data: () => ({
    isLoggedIn: false
  })
});

看看它是否正常工作(2.5):

const userState = new Vue({
  data: () => ({
    isLoggedIn: false
  })
});

Vue.component('header-component', {
  template: `
<label>
  <input type="checkbox" v-model="isLoggedIn">
  Logged in
</label>
  `,
  computed: {
    isLoggedIn: {
      get() {
        return userState.isLoggedIn
      },
      set(value) {
        userState.isLoggedIn = value
      }
    }
  }
});

Vue.component('footer-component', {
  template: `<pre v-text="{ isLoggedIn }"></pre>`,
  computed: {
    isLoggedIn() {
      return userState.isLoggedIn
    }
  }
});

new Vue({
  el: '#app'
})
body {
  margin: 0;
}

#app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

#app>* {
  padding: 1rem;
  border: 1px solid #eee;
}

#app main {
  flex-grow: 1;
}


#app pre {
  margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17"></script>
<div id="app">
  <header-component></header-component>
  <main>main content here...</main>
  <footer-component></footer-component>
</div>

【讨论】:

    猜你喜欢
    • 2020-07-01
    • 2017-06-12
    • 2018-08-23
    • 2019-03-08
    • 2018-03-01
    • 1970-01-01
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多