Vue.js每天必学之组件与组件间的通信

什么是组件?

组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。

使用组件

注册

之前说过,我们可以用 Vue.extend() 创建一个组件构造器:

var MyComponent = Vue.extend({
 // 选项...
})

要把这个构造器用作组件,需要用 `Vue.component(tag, constructor)` **注册** :

// 全局注册组件,tag 为 my-component
Vue.component('my-component', MyComponent)

<p class="tip">对于自定义标签名字,Vue.js 不强制要求遵循 W3C 规则(小写,并且包含一个短杠),尽管遵循这个规则比较好。

组件在注册之后,便可以在父实例的模块中以自定义元素 <my-component> 的形式使用。要确保在初始化根实例之前注册了组件:

<div id="example">
 <my-component></my-component>
</div>

// 定义
var MyComponent = Vue.extend({
 template: '<div>A custom component!</div>'
})

// 注册
Vue.component('my-component', MyComponent)

// 创建根实例
new Vue({
 el: '#example'
})

渲染为:

<div id="example">
 <div>A custom component!</div>
</div>

注意组件的模板替换了自定义元素,自定义元素的作用只是作为一个挂载点。可以用实例选项 replace 决定是否替换。

局部注册

不需要全局注册每个组件。可以让组件只能用在其它组件内,用实例选项 components 注册:

var Child = Vue.extend({ /* ... */ })

var Parent = Vue.extend({
 template: '...',
 components: {
 // <my-component> 只能用在父组件模板内
 'my-component': Child
 }
})

这种封装也适用于其它资源,如指令、过滤器和过渡。

注册语法糖

为了让事件更简单,可以直接传入选项对象而不是构造器给 Vue.component() 和 component 选项。Vue.js 在背后自动调用 Vue.extend():

// 在一个步骤中扩展与注册
Vue.component('my-component', {
 template: '<div>A custom component!</div>'
})

// 局部注册也可以这么做
var Parent = Vue.extend({
 components: {
 'my-component': {
 template: '<div>A custom component!</div>'
 }
 }
})

组件选项问题

传入 Vue 构造器的多数选项也可以用在 Vue.extend() 中,不过有两个特例: data 和 el。试想如果我们简单地把一个对象作为 data 选项传给 Vue.extend():

var data = { a: 1 }
var MyComponent = Vue.extend({
 data: data
})

这么做的问题是 `MyComponent` 所有的实例将共享同一个 `data` 对象!这基本不是我们想要的,因此我们应当使用一个函数作为 `data` 选项,让这个函数返回一个新对象:

 var MyComponent = Vue.extend({
 data: function () {
 return { a: 1 }
 }
})

同理,`el` 选项用在 `Vue.extend()` 中时也须是一个函数。

模板解析

Vue 的模板是 DOM 模板,使用浏览器原生的解析器而不是自己实现一个。相比字符串模板,DOM 模板有一些好处,但是也有问题,它必须是有效的 HTML 片段。一些 HTML 元素对什么元素可以放在它里面有限制。常见的限制:
 •a 不能包含其它的交互元素(如按钮,链接)
 •ul 和 ol 只能直接包含 li
 •select 只能包含 option 和 optgroup
 •table 只能直接包含 thead, tbody, tfoot, tr, caption, col, colgroup
 •tr 只能直接包含 th 和 td

在实际中,这些限制会导致意外的结果。尽管在简单的情况下它可能可以工作,但是你不能依赖自定义组件在浏览器验证之前的展开结果。例如 <my-select><option>...</option></my-select> 不是有效的模板,即使 my-select 组件最终展开为 <select>...</select>。

另一个结果是,自定义标签(包括自定义元素和特殊标签,如 <component>、<template>、 <partial> )不能用在 ul, select, table 等对内部元素有限制的标签内。放在这些元素内部的自定义标签将被提到元素的外面,因而渲染不正确。

对于自定义元素,应当使用 is 特性:

<table>
 <tr is="my-component"></tr>
</table>

`` 不能用在 `` 内,这时应使用 ``,`
` 可以有多个 ``:

<table>
 <tbody v-for="item in items">
 <tr>Even row</tr>
 <tr>Odd row</tr>
 </tbody>
</table>

Props

使用 Props 传递数据

组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 props 把数据传给子组件。

“prop” 是组件数据的一个字段,期望从父组件传下来。子组件需要显式地用 props 选项 声明 props:

Vue.component('child', {
 // 声明 props
 props: ['msg'],
 // prop 可以用在模板内
 // 可以用 `this.msg` 设置
 template: '<span>{{ msg }}</span>'
})

然后向它传入一个普通字符串:
<child msg="hello!"></child>

驼峰式vs.横杠式

HTML 特性不区分大小写。名字形式为 camelCase 的 prop 用作特性时,需要转为 kebab-case(短横线隔开):

Vue.component('child', {
 // camelCase in JavaScript
 props: ['myMessage'],
 template: '<span>{{ myMessage }}</span>'
})

<!-- kebab-case in HTML -->
<child my-message="hello!"></child>

动态 Props

类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 绑定动态 Props 到父组件的数据。每当父组件的数据变化时,也会传导给子组件:

<div>
 <input v-model="parentMsg">
 <br>
 <child v-bind:my-message="parentMsg"></child>
</div>

使用 `v-bind` 的缩写语法通常更简单:
<child :my-message="parentMsg"></child>

字面量语法 vs. 动态语法

初学者常犯的一个错误是使用字面量语法传递数值:

<!-- 传递了一个字符串 "1" -->
<comp some-prop="1"></comp>
因为它是一个字面 prop,它的值以字符串 `”1”` 而不是以实际的数字传下去。如果想传递一个实际的 JavaScript 数字,需要使用动态语法,从而让它的值被当作 JavaScript 表达式计算:
 <!-- 传递实际的数字  -->
<comp :some-prop="1"></comp>

Prop 绑定类型

prop 默认是单向绑定:当父组件的属性变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。不过,也可以使用 .sync 或 .once 绑定修饰符显式地强制双向或单次绑定:

比较语法:

<!-- 默认为单向绑定 -->
<child :msg="parentMsg"></child>

<!-- 双向绑定 -->
<child :msg.sync="parentMsg"></child>

<!-- 单次绑定 -->
<child :msg.once="parentMsg"></child>

双向绑定会把子组件的 msg 属性同步回父组件的 parentMsg 属性。单次绑定在建立之后不会同步之后的变化。

注意如果 prop 是一个对象或数组,是按引用传递。在子组件内修改它会影响父组件的状态,不管是使用哪种绑定类型。

Prop 验证

组件可以为 props 指定验证要求。当组件给其他人使用时这很有用,因为这些验证要求构成了组件的 API,确保其他人正确地使用组件。此时 props 的值是一个对象,包含验证要求:

Vue.component('example', {
 props: {
 // 基础类型检测 (`null` 意思是任何类型都可以)
 propA: Number,
 // 多种类型 (1.0.21+)
 propM: [String, Number],
 // 必需且是字符串
 propB: {
 type: String,
 required: true
 },
 // 数字,有默认值
 propC: {
 type: Number,
 default: 100
 },
 // 对象/数组的默认值应当由一个函数返回
 propD: {
 type: Object,
 default: function () {
 return { msg: 'hello' }
 }
 },
 // 指定这个 prop 为双向绑定
 // 如果绑定类型不对将抛出一条警告
 propE: {
 twoWay: true
 },
 // 自定义验证函数
 propF: {
 validator: function (value) {
 return value > 10
 }
 },
 // 转换函数(1.0.12 新增)
 // 在设置值之前转换值
 propG: {
 coerce: function (val) {
 return val + '' // 将值转换为字符串
 }
 },
 propH: {
 coerce: function (val) {
 return JSON.parse(val) // 将 JSON 字符串转换为对象
 }
 }
 }
})

type 可以是下面原生构造器:
 •String
 •Number
 •Boolean
 •Function
 •Object
 •Array

type 也可以是一个自定义构造器,使用 instanceof 检测。

当 prop 验证失败了,Vue 将拒绝在子组件上设置此值,如果使用的是开发版本会抛出一条警告。

父子组件通信

父链

子组件可以用 this.$parent 访问它的父组件。根实例的后代可以用 this.$root 访问它。父组件有一个数组 this.$children,包含它所有的子元素。

尽管可以访问父链上任意的实例,不过子组件应当避免直接依赖父组件的数据,尽量显式地使用 props 传递数据。另外,在子组件中修改父组件的状态是非常糟糕的做法,因为:
 1.这让父组件与子组件紧密地耦合;

2.只看父组件,很难理解父组件的状态。因为它可能被任意子组件修改!理想情况下,只有组件自己能修改它的状态。

自定义事件

Vue 实例实现了一个自定义事件接口,用于在组件树中通信。这个事件系统独立于原生 DOM 事件,用法也不同。

每个 Vue 实例都是一个事件触发器:
 •使用 $on() 监听事件;

•使用 $emit() 在它上面触发事件;

•使用 $dispatch() 派发事件,事件沿着父链冒泡;

•使用 $broadcast() 广播事件,事件向下传导给所有的后代。

不同于 DOM 事件,Vue 事件在冒泡过程中第一次触发回调之后自动停止冒泡,除非回调明确返回 true。

简单例子:

<!-- 子组件模板 -->
<template id="child-template">
 <input v-model="msg">
 <button v-on:click="notify">Dispatch Event</button>
</template>

<!-- 父组件模板 -->
<div id="events-example">
 <p>Messages: {{ messages | json }}</p>
 <child></child>
</div>

// 注册子组件
// 将当前消息派发出去
Vue.component('child', {
 template: '#child-template',
 data: function () {
 return { msg: 'hello' }
 },
 methods: {
 notify: function () {
 if (this.msg.trim()) {
 this.$dispatch('child-msg', this.msg)
 this.msg = ''
 }
 }
 }
})

// 初始化父组件
// 将收到消息时将事件推入一个数组
var parent = new Vue({
 el: '#events-example',
 data: {
 messages: []
 },
 // 在创建实例时 `events` 选项简单地调用 `$on`
 events: {
 'child-msg': function (msg) {
 // 事件回调内的 `this` 自动绑定到注册它的实例上
 this.messages.push(msg)
 }
 }
})

使用 v-on 绑定自定义事件

上例非常好,不过从父组件的代码中不能直观的看到 "child-msg" 事件来自哪里。如果我们在模板中子组件用到的地方声明事件处理器会更好。为此子组件可以用 v-on 监听自定义事件:

<child v-on:child-msg="handleIt"></child>
这样就很清楚了:当子组件触发了 `”child-msg”` 事件,父组件的 `handleIt` 方法将被调用。所有影响父组件状态的代码放到父组件的 `handleIt` 方法中;子组件只关注触发事件。
 子组件索引

尽管有 props 和 events,但是有时仍然需要在 JavaScript 中直接访问子组件。为此可以使用 v-ref 为子组件指定一个索引 ID。例如:

<div id="parent">
 <user-profile v-ref:profile></user-profile>
</div>

var parent = new Vue({ el: '#parent' })
// 访问子组件
var child = parent.$refs.profile

v-ref 和 v-for 一起用时,ref 是一个数组或对象,包含相应的子组件。

使用 Slot 分发内容

在使用组件时,常常要像这样组合它们:

<app>
 <app-header></app-header>
 <app-footer></app-footer>
</app>

注意两点:
 1.<app> 组件不知道它的挂载点会有什么内容,挂载点的内容是由 <app> 的父组件决定的。

2.<app> 组件很可能有它自己的模板。

为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个处理称为内容分发(或 “transclusion”,如果你熟悉 Angular)。Vue.js 实现了一个内容分发 API,参照了当前 Web 组件规范草稿,使用特殊的 <slot> 元素作为原始内容的插槽。

编译作用域

在深入内容分发 API 之前,我们先明确内容的编译作用域。假定模板为:

<child-component>
  {{ msg }}
</child-component>

msg 应该绑定到父组件的数据,还是绑定到子组件的数据?答案是父组件。组件作用域简单地说是:

父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译
一个常见错误是试图在父组件模板内将一个指令绑定到子组件的属性/方法:

<!-- 无效 -->
<child-component v-show="someChildProperty"></child-component>

假定 someChildProperty 是子组件的属性,上例不会如预期那样工作。父组件模板不应该知道子组件的状态。

如果要绑定子组件内的指令到一个组件的根节点,应当在它的模板内这么做:

Vue.component('child-component', {
 // 有效,因为是在正确的作用域内
 template: '<div v-show="someChildProperty">Child</div>',
 data: function () {
 return {
 someChildProperty: true
 }
 }
})

类似地,分发内容是在父组件作用域内编译。

单个 Slot

父组件的内容将被抛弃,除非子组件模板包含 <slot>。如果子组件模板只有一个没有特性的 slot,父组件的整个内容将插到 slot 所在的地方并替换它。

<slot> 标签的内容视为回退内容。回退内容在子组件的作用域内编译,当宿主元素为空并且没有内容供插入时显示这个回退内容。

假定 my-component 组件有下面模板:

<div>
 <h1>This is my component!</h1>
 <slot>
 如果没有分发内容则显示我。
 </slot>
</div>

父组件模板:
<my-component>
  <p>This is some original content</p>
  <p>This is some more original content</p>
</my-component>
渲染结果:

<div>
 <h1>This is my component!</h1>
 <p>This is some original content</p>
 <p>This is some more original content</p>
</div>

具名 Slot

<slot> 元素可以用一个特殊特性 name 配置如何分发内容。多个 slot 可以有不同的名字。具名 slot 将匹配内容片段中有对应 slot 特性的元素。

仍然可以有一个匿名 slot,它是默认 slot,作为找不到匹配的内容片段的回退插槽。如果没有默认的 slot,这些找不到匹配的内容片段将被抛弃。

例如,假定我们有一个 multi-insertion 组件,它的模板为:

<div>
 <slot name="one"></slot>
 <slot></slot>
 <slot name="two"></slot>
</div>

父组件模板:

<multi-insertion>
 <p slot="one">One</p>
 <p slot="two">Two</p>
 <p>Default A</p>
</multi-insertion>

渲染结果为:

<div>
 <p slot="one">One</p>
 <p>Default A</p>
 <p slot="two">Two</p>
</div>

在组合组件时,内容分发 API 是非常有用的机制。

动态组件

多个组件可以使用同一个挂载点,然后动态地在它们之间切换。使用保留的 <component> 元素,动态地绑定到它的 is 特性:

new Vue({
 el: 'body',
 data: {
 currentView: 'home'
 },
 components: {
 home: { /* ... */ },
 posts: { /* ... */ },
 archive: { /* ... */ }
 }
})

<component :is="currentView">
 <!-- 组件在 vm.currentview 变化时改变 -->
</component>

keep-alive

如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数:

<component :is="currentView" keep-alive>
  <!-- 非活动组件将被缓存 -->
</component>

activate 钩子

在切换组件时,切入组件在切入前可能需要进行一些异步操作。为了控制组件切换时长,给切入组件添加 activate 钩子:

Vue.component('activate-example', {
 activate: function (done) {
 var self = this
 loadDataAsync(function (data) {
 self.someData = data
 done()
 })
 }
})

注意 `activate` 钩子只作用于动态组件切换或静态组件初始化渲染的过程中,不作用于使用实例方法手工插入的过程中。
transition-mode

transition-mode 特性用于指定两个动态组件之间如何过渡。

在默认情况下,进入与离开平滑地过渡。这个特性可以指定另外两种模式:
 •in-out:新组件先过渡进入,等它的过渡完成之后当前组件过渡出去。

•out-in:当前组件先过渡出去,等它的过渡完成之后新组件过渡进入。

示例:

<!-- 先淡出再淡入 -->
<component
 :is="view"
 transition="fade"
 transition-mode="out-in">
</component>

.fade-transition {
 transition: opacity .3s ease;
}
.fade-enter, .fade-leave {
 opacity: 0;
}

杂项

组件和 v-for

自定义组件可以像普通元素一样直接使用 v-for:

<my-component v-for="item in items"></my-component>

但是,不能传递数据给组件,因为组件的作用域是孤立的。为了传递数据给组件,应当使用 props:

<my-component
  v-for="item in items"
  :item="item"
  :index="$index">
</my-component>

不自动把 item 注入组件的原因是这会导致组件跟当前 v-for 紧密耦合。显式声明数据来自哪里可以让组件复用在其它地方。

编写可复用组件

在编写组件时,记住是否要复用组件有好处。一次性组件跟其它组件紧密耦合没关系,但是可复用组件应当定义一个清晰的公开接口。

Vue.js 组件 API 来自三部分——prop,事件和 slot:
 •prop 允许外部环境传递数据给组件;

•事件 允许组件触发外部环境的 action;

•slot 允许外部环境插入内容到组件的视图结构内。

使用 v-bind 和 v-on 的简写语法,模板的缩进清楚且简洁:

<my-component
  :foo="baz"
  :bar="qux"
  @event-a="doThis"
  @event-b="doThat">
  <!-- content -->
  <img slot="icon" src="...">
  <p slot="main-text">Hello!</p>
</my-component>

异步组件

在大型应用中,我们可能需要将应用拆分为小块,只在需要时才从服务器下载。为了让事情更简单,Vue.js 允许将组件定义为一个工厂函数,动态地解析组件的定义。Vue.js 只在组件需要渲染时触发工厂函数,并且把结果缓存起来,用于后面的再次渲染。例如:

Vue.component('async-example', function (resolve, reject) {
 setTimeout(function () {
 resolve({
 template: '<div>I am async!</div>'
 })
 }, 1000)
})

工厂函数接收一个 resolve 回调,在收到从服务器下载的组件定义时调用。也可以调用 reject(reason) 指示加载失败。这里 setTimeout 只是为了演示。怎么获取组件完全由你决定。推荐配合使用 Webpack 的代码分割功能:

Vue.component('async-webpack-example', function (resolve) {
 // 这个特殊的 require 语法告诉 webpack
 // 自动将编译后的代码分割成不同的块,
 // 这些块将通过 ajax 请求自动下载。
 require(['./my-async-component'], resolve)
})

资源命名约定

一些资源,如组件和指令,是以 HTML 特性或 HTML 自定义元素的形式出现在模板中。因为 HTML 特性的名字和标签的名字不区分大小写,所以资源的名字通常需使用 kebab-case 而不是 camelCase 的形式,这不大方便。

Vue.js 支持资源的名字使用 camelCase 或 PascalCase 的形式,并且在模板中自动将它们转为 kebab-case(类似于 prop 的命名约定):

// 在组件定义中
components: {
 // 使用 camelCase 形式注册
 myComponent: { /*... */ }
}

<!-- 在模板中使用 kebab-case 形式 -->
<my-component></my-component>

ES6 对象字面量缩写 也没问题:

// PascalCase
import TextBox from './components/text-box';
import DropdownMenu from './components/dropdown-menu';

export default {
 components: {
 // 在模板中写作 <text-box> 和 <dropdown-menu>
 TextBox,
 DropdownMenu
 }
}

递归组件

组件在它的模板内可以递归地调用自己,不过,只有当它有 name 选项时才可以:

var StackOverflow = Vue.extend({
 name: 'stack-overflow',
 template:
 '<div>' +
 // 递归地调用它自己
 '<stack-overflow></stack-overflow>' +
 '</div>'
})

上面组件会导致一个错误 “max stack size exceeded”,所以要确保递归调用有终止条件。当使用 Vue.component() 全局注册一个组件时,组件 ID 自动设置为组件的 name 选项。

片断实例

在使用 template 选项时,模板的内容将替换实例的挂载元素。因而推荐模板的顶级元素始终是单个元素。

不这么写模板:

<div>root node 1</div>
<div>root node 2</div>

推荐这么写:

<div>
  I have a single root node!
  <div>node 1</div>
  <div>node 2</div>
</div>

下面几种情况会让实例变成一个片断实例:
 1.模板包含多个顶级元素。
 2.模板只包含普通文本。
 3.模板只包含其它组件(其它组件可能是一个片段实例)。
 4.模板只包含一个元素指令,如 <partial> 或 vue-router 的 <router-view>。
 5.模板根节点有一个流程控制指令,如 v-if 或 v-for。

这些情况让实例有未知数量的顶级元素,它将把它的 DOM 内容当作片断。片断实例仍然会正确地渲染内容。不过,它没有一个根节点,它的 $el 指向一个锚节点,即一个空的文本节点(在开发模式下是一个注释节点)。

但是更重要的是,组件元素上的非流程控制指令,非 prop 特性和过渡将被忽略,因为没有根元素供绑定:

<!-- 不可以,因为没有根元素 -->
<example v-show="ok" transition="fade"></example>

<!-- props 可以 -->
<example :prop="someData"></example>

<!-- 流程控制可以,但是不能有过渡 -->
<example v-if="ok"></example>

当然片断实例有它的用处,不过通常给组件一个根节点比较好。它会保证组件元素上的指令和特性能正确地转换,同时性能也稍微好些。

内联模板

如果子组件有 inline-template 特性,组件将把它的内容当作它的模板,而不是把它当作分发内容。这让模板更灵活。

<my-component inline-template>
  <p>These are compiled as the component's own template</p>
  <p>Not parent's transclusion content.</p>
</my-component>

但是 inline-template 让模板的作用域难以理解,并且不能缓存模板编译结果。最佳实践是使用 template 选项在组件内定义模板。

本文已被整理到了《Vue.js前端组件学习教程》,欢迎大家学习阅读。

关于vue.js组件的教程,请大家点击专题vue.js组件学习教程进行学习。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2016-09-07

vue组件父与子通信详解(一)

本文实例为大家分享了vue组件父与子通信的具体代码,供大家参考,具体内容如下 一.组件间通信(父组件    -->  子组件) 步骤: ①父组件在调用子组件 传值 <child-component myValue="123"> </child-component> ②在子组件中 获取父组件传来的值 Vue.component('child-component',{ props:['myValue'], template:'' }) 代码1: <!do

深入探讨Vue.js组件和组件通信

基本是按照官网的 Guide 全部梳理了一遍:http://vuejs.org/guide/index.html 这里我们以一个 Todo List 应用为例来把相关的只是都串起来,这篇里面的全部代码都在github上 https://github.com/lihongxun945/vue-todolist  Vue 实例 一个 Vue 应用是由一个 root vue instance 引导启动的,而 Vue instance 是这么创建的: var vm = new Vue({ // opti

vue组件间通信子与父详解(二)

接着vue组件父与子通信详解继续学习. 二.组件间通信(子组件传值给父组件) 通过事件的方式来完成数据的传输. ①在父组件中 定义一个方法,用来接收子组件所通过事件传来的值 methods:{ recvMsg:function(msg){ //参数msg就是子组件通过事件出来的数据 } } ②绑定事件处理函数 事件一般情况 都是自定义事件 <child-component @myEvent="recvMsg"></child-component> ③在子组件触发

vue.js入门(3)——详解组件通信

本文介绍vue.js组件,具体如下: 5.2 组件通信 尽管子组件可以用this.$parent访问它的父组件及其父链上任意的实例,不过子组件应当避免直接依赖父组件的数据,尽量显式地使用 props 传递数据.另外,在子组件中修改父组件的状态是非常糟糕的做法,因为: 1.这让父组件与子组件紧密地耦合: 2.只看父组件,很难理解父组件的状态.因为它可能被任意子组件修改!理想情况下,只有组件自己能修改它的状态. 每个Vue实例都是一个事件触发器: $on()--监听事件. $emit()--把事件沿

vue综合组件间的通信详解

本文实例为大家分享了vue综合组件间的通信,供大家参考,具体内容如下 实现一个ToDoList. ①完成所有的组件的创建和使用 ②add 点击add按钮时候,将用户输入的内容(todoinput),显示在(todolist) 核心代码:兄弟组件间通信 步骤1:var bus = new Vue() 步骤2:在准备接受数据的组件 bus.$on('addEvent',function(){ }) 步骤3:触发事件 bus.$emit('addEvent',123) 将todolist中数组的元素

vue2.0父子组件及非父子组件之间的通信方法

1.父组件传递数据给子组件 父组件数据如何传递给子组件呢?可以通过props属性来实现 父组件: <parent> <child :child-msg="msg"></child>//这里必须要用 - 代替驼峰 </parent> data(){ return { msg: [1,2,3] }; } 子组件通过props来接收数据: 方式1: props: ['childMsg'] 方式2 : props: { childMsg: Arr

Vuejs 用$emit与$on来进行兄弟组件之间的数据传输通信

最近在学习vue组件鸡组件之前通信问题,正好看到,以此来留作笔记. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Vue2-单一事件管理组件通信</title> <script src="vue.js"></script> <script type=

Vuejs第十篇之vuejs父子组件通信

本篇文章是小编结合官方文档整理的一套更加细致,代码更多更全的教程,非常不错,比较适合新手阅读. 本篇资料来于官方文档: http://cn.vuejs.org/guide/components.html#u7236_u5B50_u7EC4_u4EF6_u901A_u4FE1 父子组件通信 ①访问子组件.父组件.根组件: this.$parent 访问父组件 this.$children 访问子组件(是一个数组) this.$root 根实例的后代访问根实例 示例代码: <div id="a

vue组件父子间通信之综合练习(聊天室)

本文实例为大家分享了vue组件父子间通信之聊天室的具体代码,供大家参考,具体内容如下 <!doctype html> <html> <head> <meta charset="UTF-8"> <title>组件父子间通信之综合练习</title> <script src="js/vue.js"></script> </head> <body> &l

vue中的event bus非父子组件通信解析

有时候非父子关系的组件也需要通信.在简单的场景下,使用一个空的Vue实例作为中央事件总线: var bus = new Vue() // 触发组件 A 中的事件 bus.$emit('id-selected', 1) // 在组件 B 创建的钩子中监听事件 bus.$on('id-selected', function (id) { // ... }) 在更多复杂的情况下,你应该考虑使用专门的 状态管理模式.就是用到了vuex eventBus是作为兄弟关系的组件之间的通讯中介. 代码示例: <

详解Vue 非父子组件通信方法(非Vuex)

一提到两个非父子组件通信方法,有经验的 coder 肯定会说用 Vuex 啊,我个人建议不要为了用 Vuex 而用 Vuex,除非你的项目很大,耦合度很高,需要大量的储存一些 data,组件之间通信频繁.当然还是要根据自己的业务场景的来决定,总之还是那句话,不要为了用 Vuex 而用 Vuex! Vue 官网介绍了非父子组件通信方法: 不过官网说的太简单了,新手看完估计还是一脸懵逼.还有这个空的 Vue 实例放到哪里合适也值得商榷. 这篇文章的目的就是用一个简单的例子让你明白如何用 Bus

vue非父子组件通信问题及解决方法

问题描述: 最近在做登录部分时遇到一个场景,当点击 "用户"按钮时,首先渲染login组件,在用户登录后直接跳转到用户信息界面(user组件).这里遇到了需要将login组件通过异步请求获得的用户信息传向 user组件,但是login和login组件不是父子组件,就暂称为兄弟组件吧. 简而言之,我要解决的就是兄弟组件之间的信息传递问题. //位于login.vue 中 export default { methods:{ login(){ this.$axios({ method: '

Vue非父子组件通信详解

组件是Vue核心的一块内容,组件之间的通信也是很基本的开发需求.组件通信又包括父组件向子组件传数据,子组件向父组件传数据,非父子组件间的通信.前两种通信Vue的文档都说的很清楚,但是第三种文档上确只有下面的几句 具体如何去实现却没有很详细的说明,于是自己试着进行了实现.先看下简单的通信效果: 就是点击了一个组件,另一个组件的数字递加. html如下: <div id="app"> <component-a></component-a> <com

Vue 中的受控与非受控组件的实现

受控组件 什么是受控组件? 其值由React控制的输入表单元素称为"受控组件". 受控组件有两个特点:1. 设置value值,value由state控制,2. value值一般在onChange事件中通过setState进行修改 什么时候使用受控组件? 需要对组件的value值进行修改时,使用受控组件.比如:页面中有一个按钮,每点击一次按钮受控组件的值加1. 非受控组件 什么是非受控组件? 表单数据由 DOM 处理的组件非受控组件. 非受控组件有两个特点:1. 不设置value值,2.

vue中的$emit 与$on父子组件与兄弟组件的之间通信方式

本文主要对vue 用$emit 与 $on 来进行组件之间的数据传输. 主要的传输方式有三种: 1.父组件到子组件通信 2.子组件到父组件的通信 3.兄弟组件之间的通信 一.父组件传值给子组件 父组件给子组件传子,使用props //父组件:parent.vue <template> <div> <child :vals = "msg"></child> </div> </template> <script&

vue2利用Bus.js如何实现非父子组件通信详解

前言 大家应该都知道,vue2中废弃了$dispatch和$broadcast广播和分发事件的方法.父子组件中可以用props和$emit().如何实现非父子组件间的通信,可以通过实例一个vue实例Bus作为媒介,要相互通信的兄弟组件之中,都引入Bus,然后通过分别调用Bus事件触发和监听来实现通信和参数传递.下面话不多说了,来一起看看详细的介绍吧. Bus.js可以是这样 import Vue from 'vue' export default new Vue() 在需要通信的组件都引入Bus

浅谈Vue父子组件和非父子组件传值问题

本文介绍了浅谈Vue父子组件和非父子组件传值问题,分享给大家,具体如下: 1.如何创建组件 1.新建一个组件,如:在goods文件夹下新建goodsList.vue <template> <div class='tmpl'> goodsList组件 </div> </template> <style> </style> <script> export default { data() { return{} }, creat

Vue2.0中三种常用传值方式(父传子、子传父、非父子组件传值)

Vue2.0 传值方式: 在Vue的框架开发的项目过程中,经常会用到组件来管理不同的功能,有一些公共的组件会被提取出来.这时必然会产生一些疑问和需求?比如一个组件调用另一个组件作为自己的子组件,那么我们如何进行给子组件进行传值呢?如果是电商网站系统的开发,还会涉及到购物车的选项,这时候就会涉及到非父子组件传值的情况.当然你也可以用Vuex状态管理工具来实现,这部分我们后续会单独介绍.我先给大家介绍Vue开发中常用的三种传值方式. Vue常用的三种传值方式有: •父传子 •子传父 •非父子传值 引