1. 父组件向子组件传值——通过props属性实现
默认情况下,子组件不能访问到父组件中的data上的数据和methods方法
例如:
<body>
<div id="app">
<com1 />
</div>
<script>
// 创建Vue实例,得到viemodel
var vm = new Vue({
el:'#app',
data:{
msg:'父组件中的数据!',
},
components:{
com1:{
template:'<h1>这是一个子组件 --- {{msg}}</h1>'
}
}
});
</script>
</body>
在这里,子组件com1中的{{msg}}的值就是获取不到的。
那么怎么才能让子组件获取到父组件的值了?父组件可以在引用子组件的时候,通过属性绑定(v-bind或者 : )的形式,把需要传递给子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用。在在组件内部,通过定义属性数据props接收父组件传递过来的值,在模板对象中引用,例如:
<body>
<div id="app">
<com1 v-bind:parentmsg="msg"/>
</div>
<script>
// 创建Vue实例,得到viemodel
var vm = new Vue({
el:'#app',
data:{
msg:'你好啊世界!世界!',
},
components:{
com1:{
template:'<h1>这是一个子组件 --- {{parentmsg}}</h1>',
props:['parentmsg']
}
}
});
</script>
</body>
注意:
1. 通过自定义绑定变量给子组件传值
2. props:['parentmsg']:先把父组件传递过来的parentmsg属性,在props中定义,这样才能使用该数据。格外需要注意的是,在props数组中的所有的数据,都是通过父组件传递给子组件的。
2. 组件的data与props中数据的区别
<script>
// 创建Vue实例,得到viemodel
var vm = new Vue({
el:'#app',
data:{
msg:'你好啊世界!世界!',
},
components:{
data() {
return {
title:'123',
content:'qq'
};
}
com1:{
template:'<h1>这是一个子组件 --- {{parentmsg}}</h1>',
props:['parentmsg']
}
}
});
</script>
根据上面的例子,我们知道
1. props:为父组件传递过来的数据,为一个数组对象,其数据是只读的,无法重新赋值,如果赋值了,vue会报警告。
2. data:为子组件自身私有的数据,例如:子组件通过ajax请求返回的数据,都可以放到data中。
data为一个方法,返回一个对象。
data中的数据是可读写的
3. 父组件通过事件绑定机制向子组件传递方法
同传值差不多,就是在子组件标签上添加事件绑定,指向父组件函数即可
例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- 1. 导入Vue的包 -->
<script src="./lib/vue_2.6.1.js"></script>
<link rel="stylesheet" href="./lib/bootstrap.css"></link>
</head>
<body>
<div id="app">
<com2 v-on:func="show"/>
</div>
<template id='templ'>
<div>
<input type="button" value="点击" @click="myclick"/>
<h1>我是子组件</h1>
</div>
</template>
<script>
var com2 = {
template:'#templ',
methods:{
myclick(){
this.$emit('func');
}
}
};
// 创建Vue实例,得到viemodel
var vm = new Vue({
el:'#app',
data:{
msg:'你好啊世界!世界!',
},
methods:{
show(){
console.log("我是父组件的方法!")
}
},
components:{
com2
}
});
</script>
</body>
</html>
1. var com2 = { } 表示定义了一个字面量类型的组件模板对象
2. template表示模板对象
3. methods表示组件内部的方法
4. 子组件内部调用父组件方法,用this.$emit('组件绑定的事件');
这里的执行逻辑是,在组件中定义一个事件func,其值为VM对象中叫做show的属性,该属性可以是data域也可以是method,找到之后,将show赋值给func,此时子组件的事件函数func就是父组件的show方法,此时组件模板中有一个点击事件myclik,对应组件模板中的method域中的myclik,通过this.$emit('func') 就可以访问到show方法,emit表示调用触发的意思,参数func就是组件的事件函数。
注意:
1. 这里的show不能写成show(),如果写成show(),就表示将show()函数的返回值给func。
2. emit也可以传递参数,第一个参数为组件的事件函数名,从第二个参数开始,为传递的参数。
4. 子组件通过事件调用向父组件传值
通过上面的例子知道,子组件可以通过事件绑定机制向父组件传递一个函数,同时,emit函数也可以接收参数,所以,这里我们也可以通过相同的原理向父组件传值
步骤方法:
1. 在组件内部定义data域并返回对象数据
2. 在emit函数中传递该对象
3. 在父组件的methods的对应的函数中加入参数,例如:show(data)
4. 在show函数中处理数据的逻辑
例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- 1. 导入Vue的包 -->
<script src="./lib/vue_2.6.1.js"></script>
<link rel="stylesheet" href="./lib/bootstrap.css"></link>
</head>
<body>
<div id="app">
<div><com2 v-on:func="show"/></div>
<div>123--{{msgformson}}</div>
</div>
<template id='templ'>
<div>
<input type="button" value="点击" @click="myclick"/>
<h1>我是子组件</h1>
</div>
</template>
<script>
// 定义了一个字面量类型的模板对象
var com2 = {
template:'#templ',
data(){
return {
sonmsg:{name:'张三',age:21}
};
},
methods:{
myclick(){
this.$emit('func',this.sonmsg);
}
}
};
// 创建Vue实例,得到viemodel
var vm = new Vue({
el:'#app',
data:{
msgformson:null,
},
methods:{
show(data){
this.msgformson = data;
console.log("我是父组件的方法!我的数据来自于子组件,数据为:" + this.msgformson.name + " " + this.msgformson.age)
}
},
components:{
com2
}
});
</script>
</body>
</html>
首先在组件模板com2中定义data,然后在myclick中通过emit调用func,并将参数传递进去,在VM对象(父组件)的data域中定义接收子组件的数据msgformson,并赋值为null,最后在show方法中传入data,并在方法体中,将data赋值给msgformson,这样父组件就具备了子组件的值了。