1、何为组件通讯?
vue中主要的思想之一就是组件化思想,在前端设计时,组件化的思想能使页面之间重复使用组件中的内容,增强了代码的复用性提高了代码的运行效率。组件通讯其实就是不同层级之间的组件之间的数据交互。举个简单例子:
淘宝官网以及大多数购物商城的页面就可以看成是由一个个的组件构成的,我们可以将整个页面看作是一个大的组件,而页面中的导航栏,商品展示等区域就可以看成是大组件中的一些小组件。在前端请求后端数据时我们不可能为每个商品的展示都请求一次服务器,而是一次性获取所有商品的信息展示到对应的组件中,一般来说请求服务器的是最外面的大组件,那么大组件请求的数据该如何展示给里面的小组件呢?大组件向小组件传递数据的过程或者小组件向大组件传递数据的过程就是组件通讯。
2、父组件向子组件传递数据
在此之前要明白vue实例其实就是个组件,我们常叫root组件(也就是根组件)。大组件向小组件传递数据用到的对象是props.当然了,组件通讯首当其冲的是需要先创建组件了。
*1.v-bind:cmoves="moves":将跟组件在中的moves绑定到cmoves变量中。
2.props:['cmoves']:将该变量cmoves(该变量包含根组件vue中moves数组中的全部数据)传递到模板cpc中。*
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件通讯</title>
</head>
<body>
<script src="../js/vue.js"></script>
<div id="app">
<!--使用数组向子组件传值的时候:
1.v-bind:cmoves="moves":将跟组件在中的moves绑定到cmoves变量中。
2.props:['cmoves']:将该变量cmoves(该变量包含根组件vue中moves数组中的全部数据)传递到模板cpc中。
-->
<cpc v-bind:cmoves="moves" v-bind:m="message"></cpc>
</div>
<template id="cpc">
<div>
<ul>
<li v-for="item in cmoves">{{item}}</li>
</ul>
{{m}}
</div>
</template>
<script>
//vue实例是根组件
const v = new Vue({
el:"#app",
data:{
message:"你好啊!",
moves:['海王','星际穿越','大话西游','盗梦空间'] //父组件中的数据
},
/*注册局部组件语法糖写法*/
components:{
//'cpc':cpc
//属性增强写法
'cpc':{
template:`#cpc`,
// props:['cmoves','m'], 使用数组向子组件传值。
props:{ //使用对象方式向子组件传值
cmoves:{ //cmoves指的是</cpc>标签中绑定vue父组件中数据的变量。
type:Array, //指的是该变量的类型是数组类型。
default:['w','s','n','d'] //default表示在没有进行父组件向子组件传值时,子组件使用cmoves变量的默认值。
} ,
m:String //表示m变量的类型是字符串类型的。
}
}
}
})
</script>
</body>
</html>
自组件向父组件传递数据的流程:
父组件向子组件传递数据结果:
3、子组件向父组件传递数据
子组件向父组件传递数据的原理是:子组件发射事件,父组件监听子组件发射的事件调用函数处理子组件发射的事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件</title>
</head>
<body>
<script src="../js/vue.js"></script>
<!--app相当于是父组件-->
<div id="app">
{{message}}
<!--使用子组件模板-->
<!--监听子组件发射出来的事件,监听到事件之后调用函数处理事件-->
<cpc @itemclick="cpcclick"></cpc>
</div>
<!--子组件-->
<template id="temp">
<div>
<button v-for="item in categories"
@click="itemclick(item)">
{{item.name}}
</button>
</div>
</template>
<script>
//vue实例相当于是父组件
const v = new Vue({
el:"#app",
data:{
message:"你好啊!"
},
//组件注册
components:{
"cpc":{
template: `#temp`,
data(){
return{
categories:[
{id:1,name:"热门推荐"},
{id:2,name:"手机数码"},
{id:3,name:"家用家电"},
{id:4,name:"电脑办公"},
]
}
},
methods:{
itemclick(item){
//发射事件(事件是自定义的)
this.$emit('itemclick',item)
}
}
}
},
methods:{
cpcclick(item){
console.log(item)
}
}
})
</script>
</body>
</html>
子组件向父组件传递数据的流程:
综上:父组件向子组件传递数据时使用props,父组件向子组件传递数据时使用$emit方法将事件发射。
4、父组件访问子组件
所谓的父组件访问子组件就是父组件得到子组件对象,获取子组件对象对子组件里面的方法进行操作。父组件访问子组件有两种方式1. $children 2.$refs
但是父组件中可能存在多个子组件,所以*$children返回的数据类型是数组类型,代表父组件中所有的子组件。$refs是实际开发中常用的获取子组件对象的方式,该方法获取的是所有标有ref属性的标签的所代表的子组件对象,如果没有任何组件设置ref属性那么该方式将不会获取到任何子组件对象。只有在需要获取父组件中全部子组件对象时才会使用$children来获取。*
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父访问子</title>
</head>
<body>
<script src="../js/vue.js"></script>
<div id="app">
{{message}}
<!--每写一个cpc标签都会创建一个新的子组件-->
<!--使用ref属性-->
<cpc ref="aaa"></cpc>
<cpc></cpc>
<!--使用ref属性-->
<cpc ref="ccc"></cpc>
<button @click="btnClick">按钮</button>
</div>
<!--子组件模板-->
<template id="temp">
<div>
<h2>我是子组件</h2>
<p>子组件</p>
</div>
</template>
<script>
const v = new Vue({
el:"#app",
data:{
message:"你好啊!"
},
methods: {
btnClick(){
/*1.$children*/
//获取父组件中所有的子组件
//console.log(this.$children);
//获取子组件中的方法
//this.$children[0].showMessage();
//获取子组件中的值
//console.log(this.$children[0].name)
//获取第二个子组件的name
//console.log(this.$children[1].name)
/*2.$refs*/
console.log(this.$refs)
}
},
components:{
"cpc":{
template:`#temp`,
data(){
return{
name:"张三"
}
},
methods:{
showMessage(){
console.log("哈哈哈")
}
}
},
}
})
</script>
</body>
</html>
代码运行结果:
获取某个子组件对象就用this.$refs.xxx(这个xxx就是组件标签上的ref属性值。)
/*获取ref='aaa'的组件对象*/
console.log(this.$refs.aaa)
运行结果:
获取ref属性为aaa的子组件对象中的值使用:this.$refs.aaa.name
/*获取ref='aaa'的组件对象的name属性*/
console.log(this.$refs.aaa.name)
5、子组件访问父组件
子组件访问父组件使用$parent,需要注意的是该方式获取的是子组件的直接父组件。假设vue实例下有一个子组件1,子组件1下又有一个子组件2,那么子组件2使用*$parent获取的父组件就只有一个子组件1,无法访问vue实例。如果想要在组件2中访问vue组件的实例的话还是有办法的,就是使用$root.*
获取父组件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>子访问父</title>
</head>
<body>
<script src="../js/vue.js"></script>
<div id="app">
{{message}}
<cpc></cpc>
</div>
<!--组件模板-->
<template id="temp">
<div>
<h1>我是子组件</h1>
<!--子组件监听-->
<button @click="btnClick">按钮</button>
</div>
</template>
<script>
const v = new Vue({
el:"#app",
data:{
message:"你好啊!"
},
components:{
"cpc":{
template:`#temp`,
methods:{
btnClick(){
/*访问父组件$parent*/
console.log(this.$parent)
}
}
}
}
})
</script>
</body>
</html>
代码运行结果,打印出来的是vue对象,因为我们的子组件的父组件就是vue实例。
获取根组件的数据:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>子访问父</title>
</head>
<body>
<script src="../js/vue.js"></script>
<div id="app">
{{message}}
<cpc></cpc>
</div>
<!--组件1模板-->
<template id="temp">
<!--组件1中使用组件2-->
<div>
<cpcc></cpcc>
</div>
</template>
<!--组件2模板-->
<template id="cpcc">
<div>
<h2>我是组件2</h2>
<button @click="btnClick2">按钮2</button>
</div>
</template>
<script>
const v = new Vue({
el:"#app",
data:{
message:"你好啊!"
},
components:{
"cpc":{
template:`#temp`,
methods:{
btnClick(){
/*访问父组件$parent*/
console.log(this.$parent)
}
},
components: {
"cpcc":{
template: `#cpcc`,
methods:{
btnClick2(){
/*获取根组件,也就是vue实例*/
console.log(this.$root.message)
}
}
}
}
}
}
})
</script>
</body>
</html>
代码运行结果:
版权归原作者 软件20-2张锦 所有, 如有侵权,请联系我们删除。