从另一个组件中的一个Vue单个组件获取数据?

Vic*_*tak 7 vue.js vue-component vuejs2

我使用Vue.js 2.5.13并拥有这种结构:

component-one.vue:

<template>
  <div>
    <input type="text" v-model="input_one">
    <component-two></component-two>
  </div>
</template>

<script>
  import ComponentTwo from 'component-two.vue'

  export default {
    name: "component-one",
    components: {
      ComponentTwo
    },
    data() {
      return {
        input_one: 'Hello from ComponentOne',
        input_two: ... // <-- I want to get value from ComponentTwo input_two (v-model) here
      }
    }
  }
</script>
Run Code Online (Sandbox Code Playgroud)

component-two.vue:

<template>
  <div>
    <input type="text" v-model="input_two">
  </div>
</template>

<script>
  export default {
    name: "component-two",
    data() {
      return {
        input_one: 'Hello from ComponentTwo'
      }
    }
  }
</script>
Run Code Online (Sandbox Code Playgroud)

如何从ComponentTwo组件中获取数据ComponentOne?这对我来说很重要,因为我有许多类似的组件与字段(庞大的注册站点形式),并且不知道在Vue组件之间调用数据.

Luc*_*ina 13

Vuejs 使用"props"进行父/子通信并使用 "emit"事件进行子/父通信

在此处输入图片说明

您必须记住,对于传递给子组件的每个道具,您都应该将这些道具添加到 props 数组中。这同样适用于事件,您发出的每个事件都应该在父组件中捕获,因此:

组件one.vue:

    <template>
      <div>
        <input type="text" v-model="input_one">
        <component-two
            @CustomEventInputChanged="doSomenthing">
        </component-two>
      </div>
    </template>

    <script>
      import ComponentTwo from 'component-two.vue'

      export default {
        name: "component-one",
        components: {
          ComponentTwo
        },
        data() {
          return {
            input_one: 'Hello from ComponentOne',
            input_two: ''
          }
        },
        methods: {
            doSomenthing ( data ) {
                this.input_two = data;
            }
        }
      }
    </script>
Run Code Online (Sandbox Code Playgroud)

组件二.vue:

    <template>
      <div>
        <input type="text" v-model="input_two" @change="emitEventChanged>
      </div>
    </template>

    <script>
      export default {
        name: "component-two",
        data() {
          return {
            input_one: 'Hello from ComponentTwo'
          }
        },
        methods: {
            emitEventChanged () {
                this.$emit('CustomEventInputChanged', this.input_two);
            }
        }

      }
    </script>
Run Code Online (Sandbox Code Playgroud)

这应该工作


小智 9

您可以使用全局事件总线轻松实现此目的.

https://alligator.io/vuejs/global-event-bus/

对于更大,更复杂的应用程序,我建议使用状态管理工具,如vuex.

https://vuex.vuejs.org/en/


Fer*_*big 6

您需要实现一个将 v-model 发送回父级的系统。

这可以通过使用内部的计算属性来完成,该属性component-two在其 set 方法中发出更改。

例子:

Vue.component('component-two', {
  name: 'component-two',
  template: '#component-two-template',
  props: {
    value: {
      required: true,
      type: String,
    },
  },
  computed: {
    message: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit('input', val);
      },
    },
  },
});

var app = new Vue({
  el: '#app',
  data: {
    message1: 'm1',
    message2: 'm2',
  },
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/vue@2.0.1/dist/vue.js"></script>
<script type="text/x-template" id="component-two-template">
  <input type="text" v-model="message"/>
</script>
<div id="app">
  <input type="text" v-model="message1"/>
  <component-two v-model="message2"></component-two>
  <p>Output</p>
  <pre>{{message1}}</pre>
  <pre>{{message2}}</pre>
</div>
Run Code Online (Sandbox Code Playgroud)


San*_*Ben 6

有这样做的几种方法,有些是在其他的答案中提到:
排名不分先后,阅读下面的详细信息部分获取更多信息)

  1. 使用全局事件总线
  2. 在组件上使用props
  3. 使用v-model 属性
  4. 使用同步修饰符
  5. 使用Vuex

对于双向绑定,请记住,它会导致一系列难以维护的突变,引用自文档:

不幸的是,真正的双向绑定会产生维护问题,因为子组件可以对父组件进行变异,而该变异的来源在父组件和子组件中都不明显。

以下是可用方法的一些详细信息:

1.) 使用全局事件总线

强烈建议不要将这种方法用于组件之间的任何类型的通用通信,正如在很多地方都讨论过的,比如这里

2.) 在组件上使用 props

道具易于使用,是解决大多数常见问题的理想方式。
由于Vue 观察变化的方式,对象上的所有属性都需要可用,否则它们将不会是响应式的。如果在 Vue 完成使它们成为可观察的'set'之后添加了任何属性,则必须使用它们。

 //Normal usage
 Vue.set(aVariable, 'aNewProp', 42);
 //This is how to use it in Nuxt
 this.$set(this.historyEntry, 'date', new Date());
Run Code Online (Sandbox Code Playgroud)

该对象将对组件和父级都是反应式的:

我将一个对象/数组作为道具传递,它自动双向同步 - 更改子项中的数据,更改父项中的数据。

如果通过 props 传递简单的值(字符串、数字),则必须显式使用.sync 修饰符

引自--> /sf/answers/2500672191/

3.) 使用 v-model 属性

v-model 属性是一种语法糖,可以在父子之间轻松进行双向绑定。它与同步修饰符的作用相同,只是它使用特定的道具和特定的事件进行绑定

这个:

 <input v-model="searchText">
Run Code Online (Sandbox Code Playgroud)

与此相同:

 <input
   v-bind:value="searchText"
   v-on:input="searchText = $event.target.value"
 >
Run Code Online (Sandbox Code Playgroud)

其中 prop 必须是value并且 event 必须是input

4.) 使用同步修饰符

sync 修饰符也是语法糖,与 v-model 的作用相同,只是 prop 和 event 名称由正在使用的任何内容设置。

在父级中,它可以按如下方式使用:

 <text-document v-bind:title.sync="doc.title"></text-document>
Run Code Online (Sandbox Code Playgroud)

可以从子进程发出一个事件以通知父进程任何更改:

 this.$emit('update:title', newTitle)
Run Code Online (Sandbox Code Playgroud)

5.) 使用 Vuex

Vuex 是一个可以从每个组件访问的数据存储。可以订阅更改。

通过使用 Vuex 存储,可以更容易地查看数据突变的流程,并且它们是明确定义的。通过使用vue 开发人员工具,可以轻松调试和回滚所做的更改。

这种方法需要更多的样板文件,但如果在整个项目中使用,它就会成为一种更清晰的方式来定义如何进行更改以及从何处进行更改。

请参阅入门指南