组件通信
父给子组件通信
-
子组件通过
props
属性接收var father = { template: ` <div> <button @click="handleClick"></button> <!-- 静态传值 zhangsan --> <son name="name"></son> <!-- 动态传值 zhangsi --> <son :name="name"></son> </div> `, data() { return { name: "zhangsan" } }, methods: { handleClick (){ this.name = "zhangsi" } } } var son = { props: ['name'], template: ` <div> <p>{{name}}</p> </div> ` }
-
props 对象写法
props: { title: String, likes: Number, isPublished: Boolean, commentIds: Array, author: Object, callback: Function, contactsPromise: Promise, // or any other constructor // 多个可能的类型 propB: [String, Number], name: { // 类型定义 type: String, // 必传字段 required: true, default: "zhangsan" }, age: { type: Nubmer, // 默认值 default: 100 }, // 自定义验证函数 propF: { validator(value) { // 这个值必须与下列字符串中的其中一个相匹配 return ['success', 'warning', 'danger'].includes(value) } }, // 具有默认值的函数 propG: { type: Function, // 与对象或数组的默认值不同,这不是一个工厂函数——这是一个用作默认值的函数 default() { return 'Default function' } } }
必传变量
name: { // 类型定义 type: String, // 必传字段 required: true, default: "zhangsan" },
默认值
age: { type: Nubmer, // 默认值 default: 100 },
-
子给父组件通信
-
通过父组件传递方法给子组件
-
子组件通过
this.$emit("方法名")
触发父组件传递过来方法, -
this.$emit("方法名", 数据)
的第二个参数把数据传递给父组件 -
父给子传递方法
-
hClick
自定义事件 -
this.$emit("hClick")
触发事件
var father = { template: ` <div> <button @click="handleClick"></button> <!-- 静态传值 zhangsan --> <son name="name"></son> <!-- 动态传值 zhangsi --> <son :name="name" @hClick="handleClick"></son> </div> `, data() { return { name: "zhangsan" } }, methods: { handleClick (){ this.name = "zhangsi" } } } var son = { props: ['name'], template: ` <div> <p>{{name}}</p> </div> ` }
-
兄弟组件通信
-
1.创建一个gege组件,一个didi组件
-
2.创建
eventBus
对象,let eventBus = new Vue()
-
3.gege 组件通过
eventBus.$emit("自定义事件", 数据)
-
4.didi 组件通过
eventBus.$on("自定义事件", callbackFn)
-
let eventBus = new Vue(); var gege = { data (){ return { name: 'gege', } }, methods: { handlePass (){ eventBus.$emit('receive', this.name) } } } var didi = { data (){ return { name: 'didi', } }, methods: { }, created (){ handlePass (){ // 监听方法 eventBus.$on('receive', function(res){ console.log(res) }) } } }
跨级组件通讯
yeye组件,想给sunzi组件通信
-
爷爷组件
- provide , 数据提供者
- inject , 数据接收者,
- yeye组件不需要知道哪些sunzi组件使用了它 provide 的 property
- sunzi组件不需要知道 inject 的 property 来自哪
const app = Vue.createApp({}) app.component('grandfa', { data() { return { todos: ['Feed a cat', 'Buy tickets'], name: "zhangsan" } }, methods: { handleChange(){ this.name = "lisi" } } provide: { // 返回 this的属性值, 就必须返回对象 return { name: {name: this.name} getname: ()=>{ {username: this.name} } }, template: ` <div> {{ todos.length }} <!-- 模板的其余部分 --> <button @click="handleChange"></button> </div> ` }) app.component('grandson', { inject: ["name", "getname" ], computed: { username (){ return this.getname().username } } template: ` <div> {{ todos.length }} <!-- 模板的其余部分 --> </div> ` })
插槽
具名插槽
-
具有名字的插槽
-
使用 中的 “name” 属性绑定元素
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> <grandfa> <template #mySolt> <h2>我在哪里呢1</h2> </template> <template #default> <h3>laoer</h3> </template> </grandfa> </div> <script src="./js/vue.js"></script> <script type="" ></script> <script> Vue.component('grandfa', { data() { return { todos: ['Feed a cat', 'Buy tickets'], } }, methods: { handleChange(res) { eventBus.$emit("transmini", this.todos) } }, template: ` <div> <hr></hr> <h1>具名插槽</h1> <slot name="mySolt"></slot> <hr></hr> <h1>默认插槽</h1> <slot></slot> <hr></hr> <grandson @handle="handleChange"></grandson> </div> `, }) Vue.component('grandson', { props: ["name", "handle"], data (){ return { list: null, } }, template: ` <div> <button @click="handleClick">点击事件</button> <p>{{list}}</p> </div> `, methods: { handleClick(){ this.$emit("handle", "数据1") console.log(1); } }, }) new Vue({ el: "#app", }) </script> </body> </html>
-
作用域插槽
-
父组件对子组件加工处理
-
既可以复用子组件的slot,又可以使slot内容不一致
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> <grandfa> <template #mySolt> <h2>我在哪里呢1</h2> </template> <template #default> <h3>laoer</h3> </template> </grandfa> </div> <script src="./js/vue.js"></script> <script type="" ></script> <script> Vue.component('grandfa', { data() { return { } }, methods: { }, template: ` <div> <grandson @handle="handleChange"> <!----作用域插槽-----> <template slot-scope="slotProps"> <h4>{{slotProps}}</h4> <ul> <li v-for="item in slotProps.list"> {{item}} </li> </ul> </template> </grandson> </div> `, }) Vue.component('grandson', { props: ["name", "handle"], data (){ return { list: [1,23,4234,32432,2432,43,2,4,32], } }, template: ` <div> <slot :list="list"></slot> </div> `, methods: { handleClick(){ this.$emit("handle", "数据1") console.log(1); } }, }) new Vue({ el: "#app", }) </script> </body> </html>