vue 如何将数据从一个组件传递到另一个组件?

How can I pass data from a component to another component on vue?

我有 2 个组件

我的第一个组件是这样的:

<template>
    ...
        <b-form-input type="text" class="rounded-0" v-model="keyword"></b-form-input>
        <b-btn variant="warning" @click="search"><i class="fa fa-search text-white mr-1"></i>Search</b-btn>
    ...
</template>
<script>
    export default {
        data () {
            return {
                keyword: ''
            }
        },
        methods: {
            search() {
                this.$root.$emit('keywordEvent', this.keyword)
                location.href = '/#/products/products'
            }
        }
    }
</script>

我的第二个组件是这样的:

<template>
    ...
</template>
<script>
    export default {
        data () {
          return{
              keyword: ''
          }
        },
        mounted: function () { 
            this.$root.$on('keywordEvent', (keyword) => {
                this.keyword = keyword
            })
            this.getItems()
        },
        methods: {
            getItems() {
                console.log(this.keyword)
                ....
            }
        }
    }
</script>

我使用 emit 在组件之间传递值

我想将 keyword 的值传递给第二个组件

/#/products/products是第二个分量

我在第二个组件中尝试 console.log(this.keyword)。但是没有结果

我该如何解决这个问题?

更新 :

我有 index.js,其中包含这样的 vue 路由器:

import Vue from 'vue'
import Router from 'vue-router'
...
const Products = () => import('@/views/products/Products')
Vue.use(Router)
export default new Router({
  mode: 'hash', // https://router.vuejs.org/api/#mode
  linkActiveClass: 'open active',
  scrollBehavior: () => ({ y: 0 }),
  routes: [
    {
      path: '/',
      redirect: '/pages/login',
      name: 'Home',
      component: DefaultContainer,
      children: [
        {
            path: 'products',
            redirect: '/products/sparepart',
            name: 'Products',
            component: {
                render (c) { return c('router-view') }
            },
            children : [
                ...
                {
                    path: 'products',
                    name: 'products',
                    component: Products,
                    props:true
                }
            ]
        },
      ]
    },
    {
      path: '/products/products',
      name: 'ProductsProducts', // just guessing
      component: {
          render (c) { return c('router-view') }
      },
      props: (route) => ({keyword: route.query.keyword}) // set keyword query param to prop
    }
  ]
})

从这个代码...

location.href = '/#/products/products'

我假设 /#/products/products 通过 vue-router 映射到您的 "second" 组件,我会将 keyword 定义为查询路由参数。例如

{
  path: 'products',
  name: 'products',
  component: Products,
  props: (route) => ({keyword: route.query.keyword}) // set keyword query param to prop
}

然后,在您的组件中,将 keyword 定义为字符串属性(并将其从 data 中删除)

props: {
  keyword: String
}

而不是直接设置 location.href,使用

this.$router.push({name: 'products', query: { keyword: this.keyword }})

在 Vue 中有一些方法可以做到这一点。

  1. 像您一样将 EventBus 与 $emit 一起使用;

事件-bus.js

import Vue from 'vue';
const EventBus = new Vue();
export default EventBus;

component1.vue :

import EventBus from './event-bus';
...
methods: {
    my() {
      this.someData++;
      EventBus.$emit('invoked-event', this.someData);
    }
  }

component2.vue

import EventBus from './event-bus';
...
data(){return {changedValue:""}},
...
mounted(){
    EventBus.$on('invoked-event', payLoad => {
        this.changedValue = payload
    });
}
  1. 使用 Vuex store,可以在任何组件、任何页面访问; (我最喜欢的方式)

store/index.js

import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);

const store = () =>
    new Vuex.Store({
    store: {myStore:{value:0}},
    actions:{["actionName"]:function({commit}, data){commit("actionName", data);}}, // I usualy using special constant for actions/mutations names, so I can use that here in code, and also in components
    mutations:{["actionName"]:function(state, data){state.myStore.value = data;}},
    getters:{myStoreValue: state => !!state.myStore.value}
})

component1.vue

...
methods:{
    change:function(){
        this.$store.dispatch("actionName", this.someData); //nuxt syntax, for simple vue you have to import store from "./../store" also
    }
}

component2.vue

...
data(){return {changedValue:""}},
...
mounted(){
    this.changedValue = this.$store.getters.myStoreValue;
}
  1. 像@Phil 说的那样使用道具。