1 父组件向子组件传值
1.1 基本用法
- 介绍
-
组件定义时,接收数据
- 接收数据是通过props属性,在组件定义的第二个参数对象中增加props
- props,是一个数组,数组中就是接收的传递过来的值的属性名
- 比如[‘title’],那么title就接收使用组件时的title属性传递的值
- 然后在template中就可以直接把title当成属性使用:{{title}}
-
组件使用时,传递数据,传递有两种方式:
- 第一种:title=“xxx”,值是固定的
- 第二种::title=“title”,属性绑定,title属性绑定数据属性title,数据属性title是变化的
-
理解:父组件向子组件传值?
- 这里其实是,在组件使用时,通过属性,传递给组件定义内
- menu-item就是父组件,而menu-item的模板内容中的div是子组件
-
代码:
<body>
<div id="app">
<div>{{pmsg}}</div><!--差值表达式,直接输出data属性pmsg的值-->
<!--组件使用:传递title数据-->
<menu-item title='来自父组件的值'></menu-item>
<!--传递title=ptitle和content='hello'-->
<menu-item :title='ptitle' content='hello'></menu-item>
<!--title用了属性绑定,是因为ptitle是data的属性。
content并没有用属性绑定,是因为hello就是一个字符串
-->
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/*
父组件向子组件传值-基本使用
*/
Vue.component('menu-item', {
props: ['title', 'content'],//接收title属性值,content属性值
data: function() {
return {
msg: '子组件本身的数据'
}
},
//msg是组件自己的数据,title和content是接收的数据
template: '<div>{{msg + "---" + title + "---" + content}}</div>'
});
var vm = new Vue({
el: '#app',
data: {
pmsg: '父组件中内容',
ptitle: '动态绑定属性'
}
});
</script>
</body>
1.2 分析
- 父组件向子组件传递数据分析图:
2 子组件向父组件传值
2.1 基本用法
-
介绍:
-
子组件传递信息:触发事件(第一步中的button就是子组件,是menu-item中template的内容)
-
$emit(“自定义事件名”):触发自定义事件($emit是Vue实例的方法)
-
emit:发出,发射,[iˈmɪt]
-
-
父组件接收信息:绑定事件(第二步中的menu-item就是父组件)
- v-on:自定义事件名,绑定事件
- 只要通过v-on绑定一个自定义事件,Vue实例身上就有这个自定义事件,就可以通过$emit触发
-
理解:
- 这里其实并没有传递数据,而是通过子组件触发事件,和父组件绑定事件来间接执行逻辑
- 如果想传递数据,子组件触发事件时需要传递参数(看4.2.2)
- 一句话总结:子组件向父组件传值:是通过由子组件触发父组件绑定的事件来完成的
- 这里其实并没有传递数据,而是通过子组件触发事件,和父组件绑定事件来间接执行逻辑
-
步骤:
- 定义组件时,在子组件中通过点击事件触发父组件绑定的事件
- 通过$emit(‘父组件事件名’)来触发
- 使用组件时,父组件绑定事件
- 组件绑定事件的事件处理程序,可以是vue的methods
- 定义组件时,在子组件中通过点击事件触发父组件绑定的事件
-
案例需求:通过子组件按钮点击之后,通知父组件,让div的文字变大
-
案例代码:关键思路看如下注释中的1,2,3,4,5…
<body>
<div id="app">
<!--5.div样式绑定fontSize(一旦fontSize改变,这里就会改变)-->
<div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div>
<!--6.整个过程:
点击了子组件的按钮之后,触发enlarge-text事件,父组件监听到之后,调用handle方法
handle方法,改变fontSize数据的值,影响到上边div的字体大小
-->
<!--3.父组件绑定事件,触发handle方法-->
<menu-item :parr='parr' @enlarge-text='handle'></menu-item>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/*
子组件向父组件传值-基本用法
props传递数据原则:单向数据流
*/
//1. 定义组件menu-item
Vue.component('menu-item', {
props: ['parr'],
template: `
<div>
<ul>
<li :key='index' v-for='(item,index) in parr'>{{item}}</li>
</ul>
<!--子组件中,可以直接操作父组件menu-item的数据parr-->
<button @click='parr.push("lemon")'>点击增加</button>
<!--2.子组件通过触发父组件绑定的事件,来传递数据-->
<button @click='$emit("enlarge-text")'>扩大父组件中字体大小</button>
</div>
`
});
var vm = new Vue({
el: '#app',
data: {
pmsg: '父组件中内容',
parr: ['apple','orange','banana'],
fontSize: 10
},
methods: {
//4.定义handle方法:改变fontSize大小
handle: function(){
// 扩大字体大小
this.fontSize += 5;
}
}
});
</script>
</body>
- 子组件向父组件传递数据分析
3 兄弟组件之间数据交互
-
介绍:
- 兄弟组件传递数据,不再使用props和自定义事件
- 而是通过事件中心
- 其实类似自定义事件,都是通过触发事件和监听事件来实现
-
上述步骤详述:
-
单独定义一个Vue实例,作为事件中心对象(之前的定义el,data,methods的Vue实例也需要有)
-
在兄弟组件A中:通过$on方法监听事件(添加事件)
<body> <div id="app"> <div>父组件</div> <div> <!--5. 单独定义一个按钮,销毁事件--> <button @click='handle'>销毁事件</button> </div> <test-tom></test-tom> <test-jerry></test-jerry> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> /* 兄弟组件之间数据传递 */ //1.提供事件中心 var hub = new Vue();//专门用于操作事件的Vue实例 //2.定义tom组件:有显示数据的div和按钮 Vue.component('test-tom', { data: function(){ return { num: 0//组件中有自己的数量变量 } }, template: ` <div> <div>TOM:{{num}}</div> <div> <button @click='handle'>点击</button> </div> </div> `, methods: { handle: function(){ hub.$emit('jerry-event', 2);//点击之后,触发jerry-event事件,并传递数据2 } }, //3. 在当前组件挂载之后,给事件中心hub添加事件tom-event mounted: function() { // 监听事件 hub.$on('tom-event', (val) => {//事件是让num值变化 this.num += val; }); } }); //jerry组件:有显示数据的div和按钮 Vue.component('test-jerry', { data: function(){ return { num: 0//组件中有自己的数量变量 } }, template: ` <div> <div>JERRY:{{num}}</div> <div> <button @click='handle'>点击</button> </div> </div> `, methods: { //4. 通过jerry组件中的按钮,触发hanle,然后触发兄弟组件tom的事件,并且传递数据1 handle: function(){ // 触发兄弟组件的事件 hub.$emit('tom-event', 1); } }, mounted: function() { // 监听事件 hub.$on('jerry-event', (val) => { this.num += val; }); } }); var vm = new Vue({//原来的Vue实例 el: '#app', data: { }, methods: { handle: function(){ hub.$off('tom-event');//移除事件 hub.$off('jerry-event'); } } }); </script> </body>
-