一、父组件向子组件传值
步骤1.父组件通过属性将值传递给子组件
//静态传递
<div 属性名="来自父组件的数据"></div>
//动态绑定获取
<div :属性名="存储父组件传递数据的变量"></div>
步骤2.子组件内部通过props接收父组件传递过来的值
Vue.component(‘子组件名称', {
props: ['属性名'],
template: '<div>{{ 属性名 }}</div>'
})
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<!--父组件使用子组件-->
<!--纯静态可以使用-->
<son-component key1='来自父组件的值1' key2="来自父组件的值2"></son-component>
<!--纯动态可以使用-->
<son-component :key1='infoOne' :key2='infoTwo'></son-component>
<!--动态、静态可以结合使用-->
<son-component key1='来自父组件的值' :key2='infoTwo'></son-component>
</div>
<script type="text/javascript" src="../../js/vue.js"></script>
<script type="text/javascript">
// 定义子组件
// 其中 key1、key2 两个属性为父组件的属性,并且这两个属性的值都会被子组件接收
Vue.component('son-component', {
props: ['key1', 'key2'],
data: function() {
return {
}
},
template: '<div>{{key1 + "-----" + key2}}</div>'
});
// vue 的实例本身就是一个组件,并且是一个根组件,因此它可以使用任何自定义组件
let vm = new Vue({
el: '#app',
data: {
msg: '父组件中内容',
infoOne: '用于给子组件传递数据的绑定变量',
infoTwo: 'this is the result'
}
});
</script>
</body>
</html>
注意事项:
1.在props中使用驼峰形式,模板中需要使用短横线的形式(dom 元素的属性是不区分大小写的);字符串形式的模板中没有这个限制
Vue.component(‘component-a', {
// 在 JavaScript 中是驼峰式的
props: [‘valueData'],
template: '<div>{{ valueData }}</div>'
})
<!– 在html中是短横线方式的 -->
<menu-item value-data=“测试数据"></menu-item>
2.props属性值类型
- 字符串 String
- 数值 Number
- 布尔值 Boolean
- 数组 Array
- 对象 Object
传值的时候,如果采用的是静态传递,则所有的数据都会被当作字符串处理
传值的时候,如果采用的是动态属性绑定,则数据会按照原值类型处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<!--动态属性绑定-->
<component-a :one='one_data' :two='two_data' :three='three_data' :four='four_data' :five='five_data'></component-a>
<!--静态数据传递-->
<component-a one='this is the result' two='100' three='true' four='[1, 2, 3, 4, 5]' five="{'id': 1, 'name': 'lanYue'}"></component-a>
</div>
<script type="text/javascript" src="../../js/vue.js"></script>
<script type="text/javascript">
/*
父组件向子组件传值-props属性值类型
*/
Vue.component('component-a', {
props: ['one', 'two', 'three', 'four', 'five'],
template: `
<div>
<div>{{typeof one}}</div>
<div>{{typeof two}}</div>
<div>{{typeof three}}</div>
<div>{{typeof four}}</div>
<div>{{typeof five}}</div>
</div>
`
});
let vm = new Vue({
el: '#app',
data: {
one_data: 'this is the result',
two_data: 100,
three_data: true,
four_data: [1, 2, 3, 4, 5],
five_data:{'id': 1, 'name': 'lanYue'}
}
});
</script>
</body>
</html>
二、子组件向父组件传值
1.props传递数据原则
单向数据流,只允许父组件向子组件传递数据,而不建议子组件直接操作 props 中的数据(虽然允许,但不推荐)
2.子组件向父组件传递数据方法
(1).子组件通过自定义事件向父组件传递信息
$emit("事件名称")
(2).父组件监听子组件的事件
<子组件名称 v-on:='事件名称'></子组件名称>
(3)举例——子组件向父组件传递已有数据(变更后的)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<div :style='{fontSize: fontSize + "px"}'>{{msg}}</div>
<!--父组件需要监听事件时,只需要使用 @ 符号 加上事件的名称即可,等号右边为处理逻辑或者监听成功后要执行的函数-->
<!--父组件为 key 属性绑定值并且传给子组件-->
<!--父组件监听 enlarge-text 事件-->
<!--子组件通过 my_key 属性绑定 key_data数据-->
<component-a :my_key="key_data" @enlarge-text='handle'></component-a>
</div>
<script type="text/javascript" src="../../js/vue.js"></script>
<script type="text/javascript">
Vue.component('component-a', {
// 子组件监听 key 属性
props: ['my_key'],
// $emit 用于触发自定义事件,参数为事件名称,可以自定义名称
// 子组件自定义事件,用于向父组件传递数据
template: `
<div>
<button @click='$emit("enlarge-text")'>{{my_key}}</button>
</div>
`
});
let vm = new Vue({
el: '#app',
data: {
msg: '测试数据',
key_data: '扩大字体',
fontSize: 10
},
methods: {
handle: function(){
// 扩大字体大小
this.fontSize += 5;
}
}
});
</script>
</body>
</html>
(4)举例——子组件向父组件传递新数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<div :style='{fontSize: fontSize + "px"}'>{{msg}}</div>
<!--父组件通过 $event 获取子组件传递过来的数据-->
<component-a :my_key="key_data" @enlarge-text='handle($event)'></component-a>
</div>
<script type="text/javascript" src="../../js/vue.js"></script>
<script type="text/javascript">
/*
子组件通过 $emit 的第一个参数用于注册事件,第二个参数 用于作为时间的参数向父组件传递数据
*/
Vue.component('component-a', {
props: ['my_key'],
template: `
<div>
<button @click='$emit("enlarge-text", 5)'>{{my_key}}</button>
</div>
`
});
let vm = new Vue({
el: '#app',
data: {
msg: '测试数据',
key_data: '扩大字体',
fontSize: 10
},
methods: {
// 父组件得到子组件传递而来的参数
handle: function(arg){
// 扩大字体大小
this.fontSize += arg;
}
}
});
</script>
</body>
</html>
三、非父子组件间传值
非父子组件(一般指兄弟组件)之间传递数据需要用到事件中心,它们之间的关系如下:
1.具体步骤:
1. 单独的事件中心(由新 new 的 vue 实例对象扮演)管理组件间的通信
let 事件中心变量名 = new Vue()
2. 监听事件与销毁事件
事件中心变量名.$on('自定义事件名称', '事件函数')
事件中心变量名.$off('自定义事件名称')
3. 触发事件
事件中心变量名.$emit(‘自定义事件名称', 携带任意参数)
2.示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<div>
<button @click='handle'>销毁事件</button>
</div>
<one-component></one-component>
<two-component></two-component>
</div>
<script type="text/javascript" src="../../js/vue.js"></script>
<script type="text/javascript">
/*
兄弟组件之间数据传递
*/
// 提供事件中心
let hub = new Vue();
// 注册组件一
Vue.component('one-component', {
data: function () {
return {
num: 1
}
},
template: `
<div>
<div>组件一:{{num}}</div>
<div>
<button @click='handle'>点击加二</button>
</div>
</div>
`,
methods: {
// 组件一自定义 触发组件二变化的 事件二,并传递参数 2
handle: function () {
hub.$emit('two-event', 2);
}
},
mounted: function () {
// 事件中心监听引发 组件一 变动的事件一
hub.$on('one-event', (val) => {
this.num += val;
});
}
});
Vue.component('two-component', {
data: function () {
return {
num: 2
}
},
template: `
<div>
<div>组件二:{{num}}</div>
<div>
<button @click='handle'>点击加二</button>
</div>
</div>
`,
methods: {
handle: function () {
// 组件二自定义 触发组件一变化的 事件一,并传递参数 2
hub.$emit('one-event', 2);
}
},
mounted: function () {
// 事件中心监听引发 组件二 变动的事件一
hub.$on('two-event', (val) => {
this.num += val;
});
}
});
let vm = new Vue({
el: '#app',
data: {},
methods: {
handle: function () {
// 利用事件中心销毁组件一、二的事件
hub.$off('one-event');
hub.$off('two-event');
}
}
});
</script>
</body>
</html>