【问题标题】:How can I pass data from a component to another component on vue?如何将数据从组件传递到 vue 上的另一个组件?
【发布时间】:2019-02-20 11:48:36
【问题描述】:

我有 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'
  • @Phil 我会试试你的方法

标签: vue.js vuejs2 vue-component emit


【解决方案1】:

从此代码...

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 定义为字符串 prop(并将其从 data 中删除)

props: {
  keyword: String
}

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

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

【讨论】:

  • 如果我点击搜索按钮,它会调用 url http://localhost:8080/#/products/products?keyword=test。在我的第二个组件中,我添加了props: { keyword: String }。在getItems 方法中,我添加console.log(this.keyword),结果:undefined
  • @SuccessMan 你的路由器怎么样,即我回答中的第一段代码?如果我的回答不适合您,请更新您的问题
  • 我更新了我的问题。我在我的路线中添加了你的答案中的脚本
  • @SuccessMan 我并不是说你只是复制/粘贴我的代码。该示例是如何将查询参数添加到props 处理到您现有的路由之一,即处理/products/products URL 的路由
【解决方案2】:

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

  1. 像您一样使用带有 $emit 的 EventBus;

事件总线.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 商店,可以在任何组件、任何页面访问; (我最喜欢的方式)

存储/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 所说的道具。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-14
    • 2018-02-19
    • 2019-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多