vue组件之间的通信(数据的传递)
组件设计初衷就是要配合使用的,最常见的就是形成父子组件的关系:组件A 在它的模板中使用了组件 B。它们之间必然需要相互通信:父组件可能要给子组件下发数据,子组件则可能要将它内部发生的事情告知父组件。然而,通过一个良好定义的接口来尽可能将父子组件解耦也是很重要的。这保证了每个组件的代码可以在相对隔离的环境中书写和理解,从而提高了其可维护性和复用性。在 Vue 中,父子组件的关系可以总结为
·
组件设计初衷就是要配合使用的,最常见的就是形成父子组件的关系:组件 A 在它的模板中使用了组件 B。它们之间必然需要相互通信:父组件可能要给子组件下发数据,子组件则可能要将它内部发生的事情告知父组件。然而,通过一个良好定义的接口来尽可能将父子组件解耦也是很重要的。这保证了每个组件的代码可以在相对隔离的环境中书写和理解,从而提高了其可维护性和复用性。
在 Vue 中,父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息。
父组件的data写法与子组件的data写法不同
//父组件
data:{
//对象形式
}
//子组件
data:function(){
return {
//函数形式
}
}
几种常见的传递数据的方式
1、父组件传递数据到子组件
(1) props第一种写法
Vue.component("my-component", {
props: ['msg'],
template: "<div><h1>child component,{{msg}}</h1></div>"
})
(2) props第二种写法
Vue.component("my-component", {
props: {
msg:{
required:true/false //代表改变是否必须
type:String/Array/Number/Object //传入的变量的类型检查
},
names:{
required:false,
type:Array
}
},
template: "<div><h1>child component,{{msg}}</h1></div>"
})
2、子组件如何传递数据给父组件
(1)通过发送事件的方式实现
(2)发送事件的过程
//使用组件
<div class="box">
<child-component @aaa="handle"></child-component>
</div>
//定义组件
Vue.component("child-component", {
template: "#child",
methods: {
send() {
//子组件向父组件传递数据的方式,是通过事件触发
this.$emit("aaa", "green")
//myevent---->子组件向父组件发送的事件名称
//green----->是发送的数据
}
}
})
//创建vue实例
new Vue({
el: ".box",
data: {
bgColor: 'red'
},
methods: {
handle(data) {
this.bgColor = data
}
}
})
3、非父子组件的通信
(1) 解决方案
通过中间桥梁实现非父子组件之间的通信
(2) 实现过程
//创建一个非父子组件之间通信的中间桥梁
var hub = new Vue()
//第一个组件
Vue.component("first-component",{
template:"<div><button @click='send'>发送事件</button><div>",
methods:{
send(){
//通过中间hub发送事件
hub.$emit("tosecond","some data....")
}
}
})
//第二个组件
Vue.component("first-component",{
template:"<div><button @click='send'>发送事件</button><div>",
created:function(){
//通过hub监听事件
hub.$on("tosecond",function(data){
//data---->hub发送事件时所携带的参数
})
}
})
4、组件的简单应用
写一个星星评分的简单例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
<style>
*{
margin:0;
padding:0;
}
ul,li{
list-style: none;
}
.list-item{
width: 200px;
float: left;
margin:15px;
}
.list-item img{
width: 100%;
height: 150px;
}
</style>
</head>
<body>
<div class="box">
<div class="product-list">
<div class="list-item" v-for="item in products">
<img :src="item.img" alt="">
<!-- 为img标签绑定src属性 -->
<p>{{item.title}}</p>
<Star :stars="item.stars"></Star>
<!-- v-bind绑定stars变量,并赋值item.stars -->
</div>
</div>
</div>
<template id="star">
<ul>
<li v-for="(title,index) in titles">
<!-- title为数组titles元素 -->
<label>{{title}}</label>
<!-- 遍历三个span -->
<span v-for="item in new Array(stars[index])" class="star glyphicon glyphicon-star"></span>
<span v-for="item in new Array(5-stars[index])" class="star-empty glyphicon glyphicon-star-empty"></span>
</li>
</ul>
</template>
<script src="js/vue.js"></script>
<script>
//定义了一个评分的组件:<Star></Star>
Vue.component("Star",{
template:"#star",
data:function(){
return {
titles:["总评","推荐","包装"]
}
},
props:{
stars:{
required:true,
type:Array
}
},
created:function(){
console.log(this.stars)
}
})
new Vue({
el:".box",
data:{
products:[{
img: "img/01.jpg",
title: "商品1",
stars: [2, 2, 5]
},{
img: "img/02.jpg",
title: "商品2",
stars: [3, 4, 4]
}, {
img: "img/03.jpg",
title: "商品3",
stars: [3, 3, 3]
}, {
img: "img/04.jpg",
title: "商品4",
stars: [2, 1, 4]
}]
}
})
</script>
</body>
</html>
更多推荐
已为社区贡献2条内容
所有评论(0)