Как я могу передать данные из компонента в другой компонент на VUE? - PullRequest
0 голосов
/ 16 сентября 2018

У меня есть 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 router:

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
    }
  ]
})

Ответы [ 2 ]

0 голосов
/ 16 сентября 2018

Есть несколько способов сделать это в Vue.

  1. Используйте EventBus с $ emit, как вы;

EVENT-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, будет доступно на любом компоненте, на любой странице; (мой любимый способ)

магазин / 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.
0 голосов
/ 16 сентября 2018

Из этого кода ...

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

Я предполагаю, что /#/products/products сопоставляется с вашим "вторым" компонентом через vue-router, я бы определил 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 }})
...