组件传值
Vue 组件传值
一. 父子组件传值
步骤: 1. 在子组件标签中通过v-bind把自定义属性赋值为父组件的动态数据
2. 在子组件对象中通过props字段添加自定义属性
props: ["myData"]
3, 在子组件模板中, 使用自定义属性渲染数据
{{myData}}
<body>
<script src='vue.js'></script>
<!-- vue模板 -->
<div id='myApp'>
父组件中的输入:
<input type="text" v-model="name"> <br>
<hr>
子组件的显示:
<my-com :my-data="name"></my-com>
</div>
<!-- 组件模板 -->
<template id='com'>
<span>
{{myData}}
</span>
</template>
<script>
// 组件
Vue.component('myCom',{
template: '#com',
// 使用props字段添加自定义属性,用于接收父组件传值, 值是数组结构
props: ["myData"],
// created() {
// console.log(this.myData)
// },
// watch:{
// myData(newValue){console.log(newValue)}
// },
// computed:{ }
})
// 根组件
var vm = new Vue({
el: '#myApp',
data: {
name: "张三"
}
})
// 总结: 父组件向子组件传值步骤:
// 1, 在子组件对象中通过props字段添加自定义属性
// props: ["myData"]
// 2, 在子组件标签中通过v-bind把自定义属性赋值为父组件的动态数据
// <my-com :my-data="name"></my-com>
// 3, 在子组件模板中, 使用自定义属性渲染数据
// <span> {{myData}} </span>
</script>
二 . 子传父
<body>
<script src='vue.js'></script>
<!-- vue模板 -->
<div id='myApp'>
<!-- 在组件标签上使用v-on绑定自定义事件, 调用父组件中的函数 -->
<my-com @myevent="getData"></my-com> <hr>
父组件显示: {{fatherData}}
</div>
<!-- 组件模板 -->
<template id='com'>
<div>
子组件输入: <input type="text" v-model="childData">
</div>
</template>
<script>
// 组件
Vue.component('myCom',{
template: '#com',
data(){
return{
childData: "child"
}
},
watch:{
childData(newValue){
// 监听到子组件数据更新时,把新数据发送给父组件
// 原理: 子组件调用$emit函数发射一个自定义事件, 在父组件中监听事件并在事件函数中取值
this.$emit("myevent", newValue)
// 参数一是自定义事件名, 事件名必须用小写
// 参数二是发送的数据
}
}
})
// 根组件
var vm = new Vue({
el: '#myApp',
data: {
fatherData:""
},
methods: {
//在父组件的事件函数中拿到参数中的数据并展示
getData(data){
this.fatherData = data
}
}
})
// 总结: 子组件向父组件传值的步骤:
// 1, 在子组件中合适的位置, 通过$emit函数发射自定义事件,把数据发出去
// this.$emit("myevent", newValue)
// 2, 在子组件标签上, 通过v-on绑定自定义事件,调用父组件中的事件函数
// <my-com @myevent="getData"></my-com>
// 3, 在父组件的事件函数中拿到参数中的数据并展示
// getData(data){ this.fatherData = data }
</script>
</body>
三 . 非父子组件传值
<script src='vue.js'></script>
<!-- vue模板 -->
<div id='myApp'>
<my-com1></my-com1>
<my-com2></my-com2>
</div>
<!-- 组件模板 -->
<template id='com1'>
<div>
组件1输入 : <input type="text" v-model="name">
</div>
</template>
<template id='com2'>
<div>
组件2显示 : {{name2}}
</div>
</template>
<script>
// 总线: 在全局作用域创建一个空的vue对象,视作总线.用于非父子传值
var bus = new Vue();
// 组件1
Vue.component('myCom1',{
template: '#com1',
data(){
return{
name:"张三"
}
},
watch: {
name(value){
// 调用$emit自定义事件把数据发出去
// this.$emit()
// 使用bus总线调用$emit发送数据
bus.$emit("myevent", value)
console.log("发送")
}
}
})
// 组件2
Vue.component('myCom2',{
template: '#com2',
data(){
return{
name2: ""
}
},
created() {
console.log(this)
// 在另一个组件的初始化函数created中使用bus总线监听自定义事件,取值
// bus.$on("myevent", function(data){
// // 在事件函数中this指向事件目标bus, 不是当前组件com2
// console.log("接收",data, this)
// this.name2 = data
// })
// 使用箭头函数保证函数中的this和函数外的this保持一致为com2
bus.$on("myevent", (data)=>{
// 在事件函数中this指向事件目标bus, 不是当前组件com2
console.log("接收",data, this)
this.name2 = data
})
// 注意: 每一个组件对象中都有属性 _uid 它是一个索引值, 记录的是这个组件创建的顺序(第一个创建的组件,_uid是0, 往后依次增加)
},
})
// 根组件
var vm = new Vue({
el: '#myApp',
data: {
},
methods: {
}
})
// 总结: 非父子组件传值/兄弟组件传值/bus总线传值
// 1, 在全局作用域中创建空的vue对象, 称之为总线bus
// var bus = new Vue();
// 2, 在一个组件中合适的位置,通过bus总线调用$emit发送数据
// bus.$emit("myevent", value)
// 3, 在另一个组件中的初始化函数created中,使用bus总线监听事件, 接收数据并展示
// bus.$on("myevent", (data)=>{ this.name2 = data })
</script>
四 . 插槽传值
<script src='vue.js'></script>
<!-- vue模板 -->
<div id='myApp'>
父组件输入:
<input type="text" v-model="name"> <hr>
<my-com>默认在组件标签之间的信息会被忽略</my-com>
<!-- 把父组件中的动态数据写入子组件标签中 -->
<my-com>{{name}}</my-com>
</div>
<!-- 组件模板 -->
<template id='com'>
<div>
<!-- 使用slot插槽标签显示子组件标签中的信息 -->
子组件显示: <slot></slot>
</div>
</template>
<script>
// 组件
Vue.component('myCom',{
template: '#com',
created() {
// 在组件对象中拿不到插槽数据
},
})
// 根组件
var vm = new Vue({
el: '#myApp',
data: {
name: "张三"
}
})
五 . 具名插槽
<script src='vue.js'></script>
<!-- vue模板 -->
<div id='myApp'>
<my-com>父组件动态数据</my-com> <hr>
<my-com>
<span slot="s1">父组件数据1</span>
<span slot="s2">父组件数据3</span>
</my-com>
</div>
<!-- 组件模板 -->
<template id='com'>
<div>
<!-- 子组件模板中的每一个slot标签都会把插槽数据渲染一遍 -->
<!-- 子组件显示: <slot></slot> <slot></slot> -->
<!-- 当给slot标签添加name属性时, slot插槽就叫具名插槽 -->
<!-- 具名插槽: 作用可以把插槽中的部分数据分发给不同的slot标签单独渲染 -->
<slot name="s1"></slot> <br>
子组件数据2 <br>
<slot name="s2"></slot>
</div>
</template>
<script>
// 组件
Vue.component('myCom',{
template: '#com'
})
// 根组件
var vm = new Vue({
el: '#myApp'
})
// 总结: 插槽的用法
// 1, 子组件模板中slot标签如果没有name属性会把插槽数据全部渲染
// 2, slot标签添加name属性后,只会渲染插槽数据中拥有slot属性且name属性和slot属性值相同的数据
</script>


浙公网安备 33010602011771号