@Secretmm
2016-07-09T10:54:24.000000Z
字数 16474
阅读 1220
框架
Hello World示例
这段代码在画面上输出"Hello World!"。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<!--这是View-->
<div id="app">
{{ message }}
</div>
</body>
<script src="js/vue.js"></script>
<script>
// 这是Model
var exampleData = {
message: 'Hello World!'
}
// 创建一个 Vue 实例或 "ViewModel"
// 它连接 View 与 Model
new Vue({
el: '#app',
data: exampleData
})
</script>
</html>
使用Vue的过程就是定义MVVM各个组成部分的过程的过程。
1.定义View
2.定义Model
3.创建一个Vue实例或"ViewModel",它用于连接View和Model
在创建Vue实例时,需要传入一个选项对象,选项对象可以包含数据、挂载元素、方法、模生命周期钩子等等。
Vue.js有多种数据绑定的语法,最基础的形式是文本插值,使用一对大括号语法,在运行时{{ message }}会被数据对象的message属性替换,所以页面上会输出"Hello World!"。
MVVM模式本身是实现了双向绑定的,在Vue.js中可以使用v-model指令在表单元素上创建双向数据绑定。
<!--这是我们的View-->
<div id="app">
<p>{{ message }}</p>
<input type="text" v-model="message"/>
</div>
将message绑定到文本框,当更改文本框的值时,<p>{{ message }}</p>
中的内容也会被更新。
反过来,如果改变message的值,文本框的值也会被更新
Vue.js的指令是以v-开头的,它们作用于HTML元素,指令提供了一些特殊的特性,将指令绑定在元素上时,指令会为绑定的目标元素添加一些特殊的行为,我们可以将指令看作特殊的HTML特性(attribute)。
Vue.js提供了一些常用的内置指令:
v-if指令
v-show指令
v-else指令
v-for指令
v-bind指令
v-on指令
v-if
是条件渲染指令,它根据表达式的真假来删除和插入元素,它的基本语法如下:
v-if="expression"
expression
是一个返回bool值的表达式,表达式可以是一个bool属性,也可以是一个返回bool的运算式。例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<h1>Hello, Vue.js!</h1>
<h1 v-if="yes">Yes!</h1>
<h1 v-if="no">No!</h1>
<h1 v-if="age >= 25">Age: {{ age }}</h1>
<h1 v-if="name.indexOf('jack') >= 0">Name: {{ name }}</h1>
</div>
</body>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
yes: true,
no: false,
age: 28,
name: 'keepfool'
}
})
</script>
</html>
注意:yes, no, age, name这4个变量都来源于Vue实例选项对象的data属性。
这段代码使用了4个表达式:
数据的yes属性为true,所以"Yes!"会被输出;
数据的no属性为false,所以"No!"不会被输出;
运算式age >= 25返回true,所以"Age: 28"会被输出;
运算式name.indexOf('jack') >= 0返回false,所以"Name: keepfool"不会被输出。
注意:v-if指令是根据条件表达式的值来执行元素的插入或者删除行为。
这一点可以从渲染的HTML源代码看出来,面上只渲染了3个<h1>
元素,v-if值为false的<h1>
元素没有渲染到HTML。
为了再次验证这一点,可以在Chrome控制台更改age属性,使得表达式age >= 25的值为false,可以看到<h1>Age: 28</h1>
元素被删除了
v-show也是条件渲染指令,和v-if指令不同的是,使用v-show指令的元素始终会被渲染到HTML,它只是简单地为元素设置CSS的style属性。【v-if是false,那是真正的不存在;而 v-show是看起来存在,只是把对应的属性改成disply】
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<h1>Hello, Vue.js!</h1>
<h1 v-show="yes">Yes!</h1>
<h1 v-show="no">No!</h1>
<h1 v-show="age >= 25">Age: {{ age }}</h1>
<h1 v-show="name.indexOf('jack') >= 0">Name: {{ name }}</h1>
</div>
</body>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
yes: true,
no: false,
age: 28,
name: 'keepfool'
}
})
</script>
</html>
在Chrome控制台更改age属性,使得表达式age >= 25
的值为false,可以看到<h1>Age: 24</h1>
元素被设置了style="display:none"
样式。
可以用v-else指令为v-if或v-show添加一个“else块”。v-else元素必须立即跟在v-if或v-show元素的后面——否则它不能被识别。
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<h1 v-if="age >= 25">Age: {{ age }}</h1>
<h1 v-else>Name: {{ name }}</h1>
<h1>---------------------分割线---------------------</h1>
<h1 v-show="name.indexOf('keep') >= 0">Name: {{ name }}</h1>
<h1 v-else>Sex: {{ sex }}</h1>
</div>
</body>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
age: 28,
name: 'keepfool',
sex: 'Male'
}
})
</script>
</html>
v-else
元素是否渲染在HTML中,取决于前面使用的是v-if还是v-show指令。
这段代码中v-if为true,后面的v-else**不会渲染到HTML;**v-show为ture,但是后面的v-else仍然渲染到HTML了。
基本步骤:
调用Vue.extend()
方法创建组件构造器
调用Vue.component()
方注册组件
在Vue
实例的作用范围使用组件
<!DOCTYPE html>
<html>
<body>
<div id="app">
<!-- 3. #app是Vue实例挂载的元素,应该在挂载元素范围内使用组件-->
<my-component></my-component>
</div>
</body>
<script src="js/vue.js"></script>
<script>
// 1.创建一个组件构造器
var myComponent = Vue.extend({
template: '<div>This is my first component!</div>'
})
// 2.注册组件,并指定组件的标签,组件的HTML标签为<my-component>
Vue.component('my-component', myComponent)
new Vue({
el: '#app'
});
</script>
</html>
理解组件的创建和注册
我们用以下几个步骤来理解组件的创建和注册:
Vue.extend()
是Vue构造器的扩展,调用Vue.extend()
创建的是一个组件构造器,而不是一个具体的组件实例。 Vue.extend()
构造器有一个选项对象,选项对象的template
属性用于定义组件要渲染的HTML。 Vue.component()
注册组件时,需要提供2个参数,第1个参数时组件的标签,第2个参数是组件构造器。 <my-component>
标签,但只有#app1和#app2下的标签才起到作用。调用Vue.component()注册组件时,组件的注册是全局的,这意味着该组件可以在任意Vue示例下使用。
如果不需要全局注册,或者是让组件使用在其它组件内,可以用选项对象的components属性实现局部注册。
上面的示例可以改为局部注册的方式:
<!DOCTYPE html>
<html>
<body>
<div id="app">
<!-- 3. my-component只能在#app下使用-->
<my-component></my-component>
</div>
</body>
<script src="js/vue.js"></script>
<script>
// 1.创建一个组件构造器
var myComponent = Vue.extend({
template: '<div>This is my first component!</div>'
})
new Vue({
el: '#app',
components: {
// 2. 将myComponent组件注册到Vue实例下
'my-component' : myComponent
}
});
</script>
</html>
我们可以在组件中定义并使用其他组件,这就构成了父子组件的关系。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 6.在Vue实例作用范围内使用组件 -->
<parent-component>
</parent-component>
</div>
<script type="text/javascript">
//1.创建子组件构造器Child
var Child=Vue.extend({
template:'<p>我差不多已经是个死人了</p>'
})
//2.创建父组件构造器Parent,并将3.Child组件注册到Parent组件下,并将Child组件的标签设置为child-component
var Parent=Vue.extend({
template:'<p>我就是个死人了</p><child-component></child-component>',
//4.在Parent组件内以标签的形式使用Child组件
components:{
'child-component':Child
}
})
//5.全局注册Parent组件,并指定组件的标签,组件的HTML标签为<parent-component>
Vue.component('parent-component',Parent)
new Vue({
el:'#app'
})
</script>
</body>
</html>
我们分几个步骤来理解这段代码:
1. var Child = Vue.extend(...)定义一了个Child组件构造器
2.var Parent = Vue.extend(...)定义一个Parent组件构造器
3. components: { 'child-component': Child },将Child组件注册到Parent组件,并将Child组件的标签设置为child-component。
4. template :'<p>This is a Parent component</p><child-component></child-component>',在Parent组件内以标签的形式使用Child组件。
5.Vue.component('parent-component', Parent) 全局注册Parent组件
6. 在页面中使用<parent-component>标签渲染Parent组件的内容,同时Child组件的内容也被渲染出来
全局注册:
使用Vue.component()
直接创建和注册组件:
// 全局注册,my-component1是标签名称
Vue.component('my-component1',{
template: '<div>This is the first component!</div>'
})
var vm1 = new Vue({
el: '#app1'
})
Vue.component()
的第1个参数是标签名称,第2个参数是一个选项对象,使用选项对象的template
属性定义组件模板。
使用这种方式,Vue
在背后会自动地调用Vue.extend()
。
局部注册:
在选项对象的components
属性中实现局部注册:
var vm2 = new Vue({
el: '#app2',
components: {
// 局部注册,my-component2是标签名称
'my-component2': {
template: '<div>This is the second component!</div>'
},
// 局部注册,my-component3是标签名称
'my-component3': {
template: '<div>This is the third component!</div>'
}
}
})
尽管语法糖简化了组件注册,但在template选项中拼接HTML元素比较麻烦,这也导致了HTML和JavaScript的高耦合性。
庆幸的是,Vue.js提供了两种方式将定义在JavaScript中的HTML模板分离出来。
使用<script>
标签
<!DOCTYPE html>
<html>
<body>
<div id="app">
<my-component></my-component>
</div>
<script type="text/x-template" id="myComponent">
<div>This is a component!</div>
</script>
</body>
<script src="js/vue.js"></script>
<script>
Vue.component('my-component',{
template: '#myComponent'
})
new Vue({
el: '#app'
})
</script>
</html>
使用<template>
标签
如果使用<template>
标签,则不需要指定type
属性。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<my-component></my-component>
</div>
<template id="myComponent">
<div>This is a component!</div>
</template>
</body>
<script src="js/vue.js"></script>
<script>
Vue.component('my-component',{
template: '#myComponent'
})
new Vue({
el: '#app'
})
</script>
</html>
传入Vue构造器的多数选项也可以用在 Vue.extend()
或Vue.component()
中,不过有两个特例: data 和el。
Vue.js规定:在定义组件的选项时,data和el选项必须使用函数。
下面的代码在执行时,浏览器会提出一个错误
Vue.component('my-component', {
data: {
a: 1
}
})
另外,如果data选项指向某个对象,这意味着所有的组件实例共用一个data。
我们应当使用一个函数作为 data 选项,让这个函数返回一个新对象:
Vue.component('my-component', {
data: function(){
return {a : 1}
}
})
组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 props 把父组件的数据传给子组件。
props基础示例
下面的代码定义了一个子组件my-component,在Vue实例中定义了data选项。
var vm = new Vue({
el: '#app',
data: {
name: 'keepfool',
age: 28
},
components: {
'my-component': {
template: '#myComponent',
props: ['myName', 'myAge']
}
}
})
为了便于理解,你可以将这个Vue实例看作my-component的父组件。
如果我们想使父组件的数据,则必须先在子组件中定义props属性,也就是props: ['myName', 'myAge']这行代码。
定义子组件的HTML模板:
<template id="myComponent">
<table>
<tr>
<th colspan="2">
子组件数据
</th>
</tr>
<tr>
<td>my name</td>
<td>{{ myName }}</td>
</tr>
<tr>
<td>my age</td>
<td>{{ myAge }}</td>
</tr>
</table>
</template>
将父组件数据通过已定义好的props属性传递给子组件:
<div id="app">
<my-component v-bind:my-name="name" v-bind:my-age="age"></my-component>
</div>
注意:在子组件中定义prop时,使用了camelCase
命名法。由于HTML特性不区分大小写,camelCase的prop
用于特性时,需要转为 kebab-case(短横线隔开)。例如,在prop中定义的myName
,在用作特性时需要转换为my-name
。
整体代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="styles/demo.css" />
</head>
<body>
<div id="app">
<my-component v-bind:my-name="name" v-bind:my-age="age"></my-component>
</div>
<template id="myComponent">
<table>
<tr>
<th colspan="2">
子组件数据
</th>
</tr>
<tr>
<td>my name</td>
<td>{{ myName }}</td>
</tr>
<tr>
<td>my age</td>
<td>{{ myAge }}</td>
</tr>
</table>
</template>
</body>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
name: 'keepfool',
age: 28
},
components: {
'my-component': {
template: '#myComponent',
props: ['myName', 'myAge']
}
}
})
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="styles/demo.css" />
</head>
<body>
<div id="app">
<table>
<tr>
<th colspan="3">父组件数据</td>
</tr>
<tr>
<td>name</td>
<td>{{ name }}</td>
<td><input type="text" v-model="name" /></td>
</tr>
<tr>
<td>age</td>
<td>{{ age }}</td>
<td><input type="text" v-model="age" /></td>
</tr>
</table>
<my-component v-bind:my-name="name" v-bind:my-age="age"></my-component>
</div>
<template id="myComponent">
<table>
<tr>
<th colspan="3">子组件数据</td>
</tr>
<tr>
<td>my name</td>
<td>{{ myName }}</td>
<td><input type="text" v-model="myName" /></td>
</tr>
<tr>
<td>my age</td>
<td>{{ myAge }}</td>
<td><input type="text" v-model="myAge" /></td>
</tr>
</table>
</template>
</body>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
name: 'keepfool',
age: 28
},
components: {
'my-component': {
template: '#myComponent',
props: ['myName', 'myAge']
}
}
})
</script>
</html>
理解:修改了子组件的数据,没有影响父组件的数据。
修改了父组件的数据,子组件的数据也随之改变。
可以使用.sync
显式地指定双向绑定,这使得彼此之间修改数据,对方的数据都会改变。
<my-component v-bind:my-name.sync="name" v-bind:my-age.sync="age"></my-component>
可以使用.once
显式地指定单次绑定,单次绑定在建立之后不会同步之后的变化,这意味着即使父组件修改了数据,也不会传导给子组件。
<my-component v-bind:my-name.once="name" v-bind:my-age.once="age"></my-component>
为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个处理称为内容分发,Vue.js 实现了一个内容分发 API,使用特殊的 <slot>
元素作为原始内容的插槽。
如果不理解这段话,可以先跳过,你只要知道<slot>
元素是一个内容插槽。
单个Slot
下面的代码在定义my-component组件的模板时,指定了一个<slot></slot>
元素。
<div id="app">
<my-component>
<h1>Hello Vue.js!</h1>
</my-component>
<my-component>
</my-component>
</div>
<template id="myComponent">
<div class="content">
<h2>This is a component!</h2>
<slot>如果没有分发内容,则显示slot中的内容</slot>
<p>Say something...</p>
</div>
</template>
<script src="js/vue.js"></script>
<script>
Vue.component('my-component', {
template: '#myComponent'
})
new Vue({
el: '#app'
})
</script>
第一个<my-component>
标签有一段分发内容<h1>Hello Vue.js!</h1>
,渲染组件时显示了这段内容。image
第二个<my-component>
标签则没有,渲染组件时则显示了slot标签中的内容。
View Demo
指定名称的slot
上面这个示例是一个匿名slot,它只能表示一个插槽。如果需要多个内容插槽,则可以为slot元素指定name属性。
多个slot一起使用时,会非常有用。例如,对话框是HTML常用的一种交互方式。
在不同的运用场景下,对话框的头部、主体内容、底部可能是不一样的。
这时,使用不同名称的slot
就能轻易解决这个问题了。
<template id="dialog-template">
<div class="dialogs">
<div class="dialog" v-bind:class="{ 'dialog-active': show }">
<div class="dialog-content">
<div class="close rotate">
<span class="iconfont icon-close" @click="close"></span>
</div>
<slot name="header"></slot>
<slot name="body"></slot>
<slot name="footer"></slot>
</div>
</div>
<div class="dialog-overlay"></div>
</div>
</template>
<script src="js/vue.js"></script>
<script>
Vue.component('modal-dialog', {
template: '#dialog-template',
props: ['show'],
methods: {
close: function() {
this.show = false
}
}
})
new Vue({
el: '#app',
data: {
show: false
},
methods: {
openDialog: function() {
this.show = true
},
closeDialog: function() {
this.show = false
}
}
})
</script>
在定义modal-dialog
组件的template时,我们使用了3个slot,它们的name特性分别是header、body和footer。
在<modal-dialog>
标签下,分别为三个元素指定slot特性:
<div id="app">
<modal-dialog v-bind:show.sync="show">
<header class="dialog-header" slot="header">
<h1 class="dialog-title">提示信息</h1>
</header>
<div class="dialog-body" slot="body">
<p>你想在对话框中放什么内容都可以!</p>
<p>你可以放一段文字,也可以放一些表单,或者是一些图片。</p>
</div>
<footer class="dialog-footer" slot="footer">
<button class="btn" @click="closeDialog">关闭</button>
</footer>
</modal-dialog>
<button class="btn btn-open" @click="openDialog">打开对话框</button>
</div>
对话框的标题内容、主体内容、底部内容,完全由我们自定义,而且这些内容就是一些简单的HTML元素!
如果需要定制对话框的样式,我们只需要在<modal-dialog>
上追加一个v-bind
指令,让它绑定一个class
。
<modal-dialog v-bind:show.sync="show" v-bind:class="dialogClass">
然后修改一下Vue实例,在data选项中追加一个dialogClass属性,然后修改openDialog()
方法:
new Vue({
el: '#app',
data: {
show: false,
dialogClass: 'dialog-info'
},
methods: {
openDialog: function(dialogClass) {
this.show = true
this.dialogClass = dialogClass
},
closeDialog: function() {
this.show = false
}
}
})
虽然我们在modal-dialog
组件中定义了3个slot
,但是在页面中使用它时,并不用每次都指定这3个slot
。
比如,有时候我们可能只需要header和body:
<modal-dialog v-bind:show.sync="show" v-bind:class="dialogClass">
<header class="dialog-header" slot="header">
<h1 class="dialog-title">提示信息</h1>
</header>
<div class="dialog-body" slot="body">
<p>你想在对话框中放什么内容都可以!</p>
<p>你可以放一段文字,也可以放一些表单,或者是一些图片。</p>
</div>
</modal-dialog>
现在看到的对话框是没有底部的,只有标题和主体内容。
多个slot同时使用的场景还有很多,例如:用户的注册、登录、找回密码等这些表单集合,也可以用一个组件来完成。
有时候我们需要父组件访问子组件,子组件访问父组件,或者是子组件访问根组件。
针对这几种情况,Vue.js都提供了相应的API:
父组件访问子组件:使用$children
或$refs
子组件访问父组件:使用$parent
子组件访问根组件:使用$root
$children
示例
下面这段代码定义了3个组件:父组件parent-component
,两个子组件child-component1
和child-component2
。
在父组件中,通过this.$children
可以访问子组件。
this.$children
是一个数组,它包含所有子组件的实例。
<div id="app">
<parent-component></parent-component>
</div>
<template id="parent-component">
<child-component1></child-component1>
<child-component2></child-component2>
<button v-on:click="showChildComponentData">显示子组件的数据</button>
</template>
<template id="child-component1">
<h2>This is child component 1</h2>
</template>
<template id="child-component2">
<h2>This is child component 2</h2>
</template>
<script src="js/vue.js"></script>
<script>
Vue.component('parent-component', {
template: '#parent-component',
components: {
'child-component1': {
template: '#child-component1',
data: function() {
return {
msg: 'child component 111111'
}
}
},
'child-component2': {
template: '#child-component2',
data: function() {
return {
msg: 'child component 222222'
}
}
}
},
methods: {
showChildComponentData: function() {
for (var i = 0; i < this.$children.length; i++) {
alert(this.$children[i].msg)
}
}
}
})
new Vue({
el: '#app'
})
</script>
组件个数较多时,我们难以记住各个组件的顺序和位置,通过序号访问子组件不是很方便。
在子组件上使用v-ref
指令,可以给子组件指定一个索引ID:
<template id="parent-component">
<child-component1 v-ref:cc1></child-component1>
<child-component2 v-ref:cc2></child-component2>
<button v-on:click="showChildComponentData">显示子组件的数据</button>
</template>
在父组件中,则通过$refs.索引ID访问子组件的实例:
showChildComponentData: function() {
alert(this.$refs.cc1.msg);
alert(this.$refs.cc2.msg);
}
下面这段代码定义了两个组件:child-component和它的父组件parent-component。
在子组件中,通过this.$parent可以访问到父组件的实例。
<div id="app">
<parent-component></parent-component>
</div>
<template id="parent-component">
<child-component></child-component>
</template>
<template id="child-component">
<h2>This is a child component</h2>
<button v-on:click="showParentComponentData">显示父组件的数据</button>
</template>
<script src="js/vue.js"></script>
<script>
Vue.component('parent-component', {
template: '#parent-component',
components: {
'child-component': {
template: '#child-component',
methods: {
showParentComponentData: function() {
alert(this.$parent.msg)
}
}
}
},
data: function() {
return {
msg: 'parent component message'
}
}
})
new Vue({
el: '#app'
})
</script>
有时候我们希望触发父组件的某个事件时,可以通知到子组件;触发子组件的某个事件时,可以通知到父组件。
Vue
实例实现了一个自定义事件接口,用于在组件树中通信。这个事件系统独立于原生 DOM 事件,用法也不同。
每个 Vue
实例都是一个事件触发器:
使用 $on()
监听事件;
使用 $emit()
在它上面触发事件;
使用 $dispatch()
派发事件,事件沿着父链冒泡;
使用 $broadcast()
广播事件,事件向下传导给所有的后代。
派发事件
下面这段代码是一个简单的事件派发处理
<div id="app">
<p>Messages: {{ messages | json }}</p>
<child-component></child-component>
</div>
<template id="child-component">
<input v-model="msg" />
<button v-on:click="notify">Dispatch Event</button>
</template>
<script src="js/vue.js"></script>
<script>
// 注册子组件
Vue.component('child-component', {
template: '#child-component',
data: function() {
return {
msg: ''
}
},
methods: {
notify: function() {
if (this.msg.trim()) {
this.$dispatch('child-msg', this.msg)
this.msg = ''
}
}
}
})
// 初始化父组件
new Vue({
el: '#app',
data: {
messages: []
},
events: {
'child-msg': function(msg) {
this.messages.push(msg)
}
}
})
</script>
我们将这个示例分为几个步骤解读:
子组件的button
元素绑定了click
事件,该事件指向notify
方法
子组件的notify
方法在处理时,调用了$dispatch
,将事件派发到父组件的child-msg
事件,并给该该事件提供了一个msg
参数
父组件的events
选项中定义了child-msg
事件,父组件接收到子组件的派发后,调用child-msg
事件。
下面这段代码是一个简单的事件广播处理
<div id="app">
<input v-model="msg" />
<button v-on:click="notify">Broadcast Event</button>
<child-component></child-component>
</div>
<template id="child-component">
<ul>
<li v-for="item in messages">
父组件录入了信息:{{ item }}
</li>
</ul>
</template>
<script src="js/vue.js"></script>
<script>
// 注册子组件
Vue.component('child-component', {
template: '#child-component',
data: function() {
return {
messages: []
}
},
events: {
'parent-msg': function(msg) {
this.messages.push(msg)
}
}
})
// 初始化父组件
new Vue({
el: '#app',
data: {
msg: ''
},
methods: {
notify: function() {
if (this.msg.trim()) {
this.$broadcast('parent-msg', this.msg)
}
}
}
})
</script>
我们将这个示例分为几个步骤解读:
父组件的button
元素绑定了click
事件,该事件指向notify
方法
父组件的notify
方法在处理时,调用了$broadcast
,将事件派发到子组件的parent-msg
事件,并给该该事件提供了一个msg
参数
子组件的events
选项中定义了parent-msg
事件,子组件接收到父组件的广播后,调用parent-msg
事件。
Vue.js
组件的API来源于三部分——prop,slot
和事件。
prop
允许外部环境传递数据给组件;
事
件 允许组件触发外部环境的 action
;
slot
允许外部环境插入内容到组件的视图结构内。