一、父组件向子组件传值
1.子组件内部通过“props”接收父组件传递过来的值
下面展示一个 全局定义的子组件
。
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
Vue.component('menu-item',{
//这里传递了两个属性 accept、content
props:['accept','content'],
//这里的data是一个函数,且数据存必须放到返回值中
data:function () {
return{
childrenMsg:'子组件自己的数据'
}
},
template:'<div>{{childrenMsg+"---"+accept+"---"+content}}</div>'
}
);
2.父组件通过属性将值传递给子组件
<div id="app">
<div>{{parentMsg}}</div>
//静态传递给子组件的值
<menu-item accept="这里传入的是父组件的静态数据"></menu-item>
//通过绑定属性值,动态传递给子组件的数据,这里的parentAcceptMsg是父组件中定义的数据
<menu-item :accept="parentAcceptMsg"></menu-item>
//这里是动态与静态结合传递的数据
<menu-item :accept="parentAcceptMsg" content="静态数据"></menu-item>
</div>
3.Vue实例中的根组件
const vm =new Vue({
el:'#app',
data:{
parentMsg:'父组件的数据',
parentAcceptMsg:'这里是父组件动态绑定的数据'
}
})
4.演示效果
5.props属性命名规则
1.在props中使用驼峰形式,在模板中则需要使用短横线的形式,否则不会显示,并出现警告
。
//这里模板中的accept-content是短横线形式
<menu-item :accept-content="parentAcceptMsg"></menu-item>
Vue.component('menu-item',{
props:['acceptContent'],//驼峰命名法
template:'<div>{{acceptContent}}</div>'
});
2.字符串模板中没有驼峰限制
Vue.component('second-item',{
props:['acceptText'],
template:'<div>{{acceptText}}</div>'
});
Vue.component('menu-item',{
props:['acceptContent'],
//这里的acceptText没有使用短横线的形式
template:'<div>{{acceptContent}}<second-item acceptText="这里是使用驼峰命名的props属性值"></second-item></div>'
});
结论:为了统一书写,最好再模板中都写成短横线的形式,以防混淆。
6.props属性值类型
① 字符串 String
② 数值 Number
③ 布尔值 Boolean
④ 数组 Array
⑤ 对象 Object
注意:当给属性传值时,需要在props中定义的属性前添加冒号,则会保留传递的属性类型,否则,都以字符串的形式传递
<div id="app">
<menu-item :p-string="pString" :p-number="pNumber" :p-boolean="pBoolean" :p-array="pArray" :p-object="pObject"></menu-item>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
Vue.component('menu-item',{
props:['pString','pNumber','pBoolean','pArray','pObject'],
template:`
<div>
<div>{{pString}}</div>
<div>{{pNumber}}</div>
<div>{{pBoolean}}</div>
<ul>
<li :v-key="index" v-for="(item,index) in pArray">{{item}}</li>
</ul>
<div>
<span>{{pObject.name}}</span>
<span>{{pObject.age}}</span>
</div>
</div>
`
}
);
const vm =new Vue({
el:'#app',
data:{
pString:'字符串类型',
pNumber:'18',
pBoolean:true,
pArray:['apple','orange'],
pObject:{
'name':'zhangsan',
'age':20
}
}
})
</script>
7.props传递数据原则
单向数据流,即父组件传递给子组件的数据,子组件只能使用,子组件不能操作父组件中的数据。
二、父组件调用子组件的方法
1.单页面调用
<div id="app">
<parent-item></parent-item>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
const childItem= {
data: function () {
return {
childMsg: '我是子组件中的数据'
}
},
template: '<div>{{childMsg}}</div>',
methods: {
childMethod: function () {
this.childMsg = '父组件调用了子组件的方法改变了子组件中的数据'
}
}
};
Vue.component('parentItem',{
data:function(){
return{
parentMsg:'点击调用子组件的方法'
}
},
template:`<div>
<child-item ref="child"></child-item>
<button @click="parentMethod">{{parentMsg}}</button>
</div>`,
methods:{
parentMethod: function () {
this.$refs.child.childMethod();
}
},
components:{
'child-item': childItem
}
});
const vm =new Vue({
el:'#app',
})
</script>
2.单文件组件的调用
1.父组件 parent.vue
<template>
<div id="app">
<children ref="child"></children>//给子组件添加ref=child标识
<button @click="parentChange">{{pMsg}}</button>
</div>
</template>
<script>
import children from "@/components/children1";
export default {
name: 'App',
data(){
return{
pMsg:'点击按钮实现父组件调用子组件的方法改变子组件中的数据',
}
},
components: {
children
},
methods:{
parentChange:function () {
//引用ref=child标识实现父组件调用子组件的方法
this.$refs.child.childChange();
}
},
}
</script>
<style scoped>
</style>
2.子组件 children.vue
<template>
<div>
{{msg}}
</div>
</template>
<script>
export default {
name: "children",
data() {
return {
msg:'子组件的数据',
cMsg:'父组件调用子组件的方法改变了子组件的数据'
};
},
methods:{
childChange(){
this.msg=this.cMsg;
}
}
}
</script>
<style scoped>
</style>
三、子组件给父组件传值($event)
1.用 $event 来代表传进来的参数
方法一:给自定义事件绑定一个操作(方法),直接用到 $event 来代表传进来的参数
<div id="app">
<div :style='{fontSize:fontSize+"px"}'>{{pMsg}}</div>
<menu-item @enlarge-text="fontSize+=$event"></menu-item>
</div>
2.给绑定的事件用传参( $event)的方式 接收参数
方法二:给子组件绑定的单击事件中添加一个参数,用$event来接收这个参数
<div id="app">
<div :style='{fontSize:fontSize+"px"}'>{{pMsg}}</div>
<menu-item @enlarge-text="handle($event)"></menu-item>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
Vue.component('menu-item',{
template:`
<div>
<button @click='$emit("enlarge-text",5)'>点击扩大父组件中的字体</button>
</div>
`
});
const vm=new Vue({
el:'#app',
data:{
pMsg:'父组件中的数据',
fontSize:10
},
methods:{
handle(data){
this.fontSize+=data;
}
}
})
</script>
四、子组件调用父组件的方法 ( $emit / $parent)
情景:当点击子组件中的按钮时,子组件调用父组件的方法实现点击一次子组件的按钮增大一次父组件字体。
1.给子组件注册一个自定义事件
<div id="app">
Vue.component('menu-item',{
data(){
return {
msg:'这是传递给父组件的值'
}
}
template:`
<div>
<button @click='$emit("enlarge-text")'>点击扩大父组件中的字体</button>
</div>
`
});
</div>
2.父组件域中,给子组件定义的事件绑定父组件的方法
<div id="app">
<div :style='{fontSize:fontSize+"px"}'>{{pMsg}}</div>
<menu-item @enlarge-text="handle"></menu-item>
</div>
3.父组件实例中定义方法
const vm=new Vue({
el:'#app',
data:{
pMsg:'父组件中的数据',
fontSize:10
},
methods:{
handle(){
this.fontSize+=5;
}
}
})
4.展示效果
当点击按钮后,明显看到字体变大: