在开发中,往往一些数据确实需要从上层传递到下层:
比如在一个页面中,我们从服务器请求到了很多的数据,其中一部分数据,并非是整个页面的大组件来展示,而是需要下面的子组件进行展示。这个个时候,并不会让子组件再次发送一个网络请求,而是直接让大组件将数据传递给小组件。
如何进行父子组件间的通信?
const cpn2 = Vue.extend({
template: ` <div> <h1>{{cmovies}}</h1> <h3>哈哈哈<h3> </div> `,
props:['cmovies'],
});
const app = new Vue({
el: "#app",
components: {
cpn2,
},
data:{
movies:["美国队长1","美国队长2","美国队长3"]
}
})
props不仅仅可以是传入数组,也可以传入对象
props:{
//1、类型限制
cmoives:Array,
//2、提供一些默认值
cmoives:{
type:Array,
default(){
return []
},//默认值,如果默认值是个数组,就必须写成函数形式
required:true,//如果为true,就是必须传入
}
}
在命名子组件的props属性时,往往会采取驼峰体,但是在html中是无法有效识别驼峰体代码。
例如:
<body>
<div id="app">
<cpn2 :cMovies="movies"></cpn2><!--这里无法识别驼峰体代码-->
</div>
<script> const cpn2 = Vue.extend({ template: ` <div> <h1>{{cMovies}}</h1> <h3>哈哈哈</h3> </div> `, props:{ cMovies:{ //命名为驼峰体 type:Array, default(){ return [] }, required:true, } } }); const app = new Vue({ el: "#app", components: { cpn2, }, data:{ movies:["美国队长1","美国队长2","美国队长3"] } }) </script>
</body>
此时,数组中什么也没有传过来,所以显示了默认值。需要将html代码中的cMovies改成c-movies,才能显示。<cpn2 :c-movies="movies"></cpn2>
什么时候需要自定义事件呢?
当子组件需要向父组件传递数据时,就要用到自定义事件了,之前学习的v-on不仅仅用于监听DOM事件,也可以用于组件间的自定义事件。
<body>
<div id="app">
<cpn2 @itemclick="cpnclick"></cpn2>
</div>
<script> const cpn2 = Vue.extend({ template: ` <div> <button v-for="item in categories" @click="btnclick(item)">{{item.name}}</button> </div> `, data(){ return{ categories:[ {id:"aaa",name:"热门推荐"}, {id:"bbb",name:"手机数码"}, {id:"ccc",name:"家用家电"}, {id:"ddd",name:"生鲜水果"}, ] } }, methods:{ btnclick(item){ //发射事件:自定义事件 this.$emit("itemclick",item); } } }); const app = new Vue({ el: "#app", components: { cpn2, }, methods:{ cpnclick(item){ console.log(item); } } }) </script>
</body>
<body>
<div id="app">
<cpn :number1="num1" :number2="num2" @num1change="num1change" @num2change="num2change"></cpn>
</div>
<template id="cpn">
<div>
<h2>props:{{number1}}</h2>
<h2>data:{{dnumber1}}</h2>
<input type="text" :value="dnumber1" @input="num1Input">
<h2>props:{{number2}}</h2>
<h2>data:{{dnumber2}}</h2>
<input type="text" :value="dnumber2" @input="num2Input">
</div>
</template>
<script> const app= new Vue({ el:"#app", data:{ num1:1, num2:0 }, methods:{ num1change(value){ this.num1 = parseFloat(value); }, num2change(value){ this.num2 = parseFloat(value); } }, components:{ cpn:{ template:"#cpn", props:{ number1:Number, number2:Number, }, data(){ return { dnumber1:this.number1, dnumber2:this.number2, } }, methods:{ num1Input(event){ this.dnumber1 = event.target.value; this.$emit("num1change",this.dnumber1); this.dnumber2 = this.dnumber1*100; this.$emit("num2change",this.dnumber2); }, num2Input(event){ this.dnumber2 = event.target.value; this.$emit("num2change",this.dnumber2); this.dnumber1 = this.dnumber2 / 100; this.$emit("num1change",this.dnumber1); }, } } } }) </script>
</body>
有时候需要父组件直接访问子组件,子组件直接访问父组件,或者是子组件访问根组件。
父组件访问子组件:使用$children或 $refs 引用
子组件访问父组件:使用$parent
通过对button进行绑定事件,然后直接获取子组件中的属性。
但是要注意使用$children获取的是一个数组。
<body>
<div id="app">
<cpn></cpn>
<button @click="btnclick">按钮</button>
</div>
<template id="cpn">
<div>
<h2>我是内容</h2>
</div>
</template>
<script> const app=new Vue({ el:"#app", methods:{ btnclick(){ console.log(this.$children[0].name); this.$children[0].name = "李四"; console.log(this.$children[0].name); } }, components:{ cpn:{ template:"#cpn", data(){ return {name:"张三"} } } } }) </script>
</body>
如果有多个数组就需要通过索引值来确定获取的需要修改的子组件,这样就造成了一个问题,如果子组件的位置变化,例如中间插入了新的子组件,就要修改索引值,非常麻烦。
这就用到了第二个方法
通过对子组件进行refs赋值,就可以确定需要获取的子组件。
注意的是不是refs,而是ref<cpn ref="cpn1"></cpn>
console.log(this.$refs.cpn1.name);
子组件可以访问父组件,但是不建议使用,因为复用性不高,如果该子组件运用在其他父组件中,如果该父组件没有该属性就会报错。
<body>
<div id="app">
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>我是内容</h2>
<button @click="btnclick">按钮</button>
</div>
</template>
<script> const app = new Vue({ el: "#app", data:{ age:18, }, components: { cpn: { template: "#cpn", data() { return { name: "张三" } }, methods: { btnclick() { console.log(this.$parent); } }, } } }) </script>
</body>
可以直接访问到Vue实例中的属性。
用法与上述相似。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/xiaotangyu7dong/article/details/119977228
内容来源于网络,如有侵权,请联系作者删除!