案例 组件信息的通信
自己思考一下 答案在本文章的后面
插槽 v-slot
这个时候我们就可以来定义插槽slot: 插槽的使用过程其实是抽取共性、预留不同;
我们会将共同的元素、内容依然在组件内进行封装;
同时会将不同的元素使用slot作为占位,让外部决定到底显示什么样的元素;
如何使用slot呢?
Vue中将 元素作为承载分发内容的出口;
在封装组件中,使用特殊的元素就可以为封装组件开启一个插槽;
该插槽插入什么内容取决于父组件如何使用;
插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签。简单理解就是子组件中留下个“坑”,父组件可以使用指定内容来补“坑”.
页面控制平台
案例一
这个案例带你去理解啥是插槽
主页面
<template #bbb> name=BBB请输入密码:<input type="password" name="" id="" /> </template>
<template> <div class="App"> <headerTab> <!-- v-solt 插槽 名称 --> <template v-slot:aaa> <a href="name=AAA返回按钮<">name=AAA返回按钮</a> </template> <template #bbb> name=BBB请输入密码:<input type="password" name="" id="" /> </template> <template #ccc> name=CCC:<input type="Number"> </template> <template #ddd>name=DDD <input type="checkbox" name="" id="" />男 </template> <template #eee> name=EEE<input type="checkbox" name="" id="" />女</template> <template #[msg]><button>name=fff你好呀</button> </template> </headerTab> <headerTab> <template #[msg]> <button>返回按钮</button> </template> <template v-slot:aaa> <a href="#">返回按钮</a> </template> <template #bbb> 请输入密码:<input type="password" name="" id="" /> </template> <template #ccc> 点击按钮:<button>{{ msg }}</button> </template> <template #ddd> <input type="checkbox" name="" id="" />男 </template> <template #eee> <input type="checkbox" name="" id="" />女</template> </headerTab> <button @click="msg = 'left'">left</button> <button @click="msg = 'center'">center</button> <button @click="msg = 'right'">right</button> <button @click="msg = 'left'">left</button> <button @click="msg = 'aaa'">aaa</button> <button @click="msg = 'bbb'">bbb</button> <button @click="msg = 'ccc'">ccc</button> <button @click="msg = 'ddd'">ddd</button> <p>返回</p> <hr /> <headerTab :propList="propList"> <template v-slot="slotProps"> <div>{{ slotProps.item + " " + slotProps.index }}</div> </template> </headerTab> <hr /> <!-- <headerTab :propList="propList" v-slot="slotProps"> --> <!-- <div>{{slotProps.item+'-'+slotProps.index}}</div> --> <!-- </headerTab> --> </div> </template> <script> import headerTab from "./components/header-tab.vue"; export default { name: "App", components: { headerTab, }, data() { return { msg: "我是登录按钮", propList: ["王者荣耀", "JavaScript", "Jquery", "Web", "EEEE"], }; }, methods: {}, }; </script> <style scoped> div{ border-top: 2px solid red; background-color: rgb(124, 188, 225); } </style>
子组件
<div class="content"> <div class="item left"> <slot name="aaa"> 请输入姓名:<input type="text" /> </slot> </div> <div class="item"><slot name="bbb">请输入邮箱地址:<input type="emil" /></slot></div> <div class="item"><slot name="ccc">我是a链接:<a href="#">我是a标签</a></slot></div> <div class="item center"> <!-- 命令 --> <slot name="ddd">标题</slot> </div> <div class="item right"> <slot name="eee">登录</slot> </div>
<template> <div class="content"> <div class="item left"> <slot name=" item lefts"> 请输入姓名:<input type="text" /> </slot> </div> <div class="item">请输入邮箱地址:<input type="emil" /></div> <div class="item">我是a链接:<a href="#">我是a标签</a></div> <div class="item center"> <slot name="center">标题</slot> </div> <div class="item right"> <slot name="right">登录</slot> </div> </div> <div class="content"> <div class="item left"> <slot name="aaa"> 请输入姓名:<input type="text" /> </slot> </div> <div class="item"><slot name="bbb">请输入邮箱地址:<input type="emil" /></slot></div> <div class="item"><slot name="ccc">我是a链接:<a href="#">我是a标签</a></slot></div> <div class="item center"> <!-- 命令 --> <slot name="ddd">标题</slot> </div> <div class="item right"> <slot name="eee">登录</slot> </div> </div> <div> <div class="item" v-for="item,index in propList" :key="item"> <slot :item="item" :index="index">登录信息</slot> <slot name="two">我是数据信息</slot> </div> </div> </template> <script> export default { // eslint-disable-next-line vue/multi-word-component-names name: "left", props: ["propList"], data() { return { msg: "子组件的msg", }; }, methods: {}, }; </script> <style scoped> .content { display: flex; height: 50px; line-height: 50px; text-align: center; display: flex; } .item { margin-top: 3px; border-left: 2px solid red; flex: 1; background-color: rgb(166, 236, 167); color: rgb(0, 0, 0); } .left { background: rgb(171, 220, 223); } .center { background: rgb(50, 174, 28); } .right { background: rgb(10, 155, 213); } </style>
案例二 兄弟的组件直接转送值
定义对象的属性值
取出值展示在页面上
主页面
<template> <div class="app"> <h3 style="color:red">Provide和Inject基本使用</h3> <home></home> <hr> <content></content> </div> </template> <script> import content from "./components/content.vue"; import home from "./components/home.vue"; export default { name: "app", data() { return { message: "Hello world vue cli", }; }, components: { // eslint-disable-next-line vue/no-unused-components content, // eslint-disable-next-line vue/no-unused-components home, }, methods: { btnclick() { console.log("为难忘"); }, }, }; </script> <style scoped> </style>
子组件1
<template> <div class="content"> <home></home> </div> </template> <script> import home from "../components/home.vue"; export default { // eslint-disable-next-line vue/multi-word-component-names name: "content", data() { return { message: "Hello world vue cli", }; }, // 定义对象 provide: { name: "李四", age: 20, height: 123, weight: 78, email: "2678903458@qq.com", qq: "2386754567", weixing: "12389999933", }, // 函数的写法 methods: { btnclick() { console.log("为难忘"); }, }, components: { // eslint-disable-next-line vue/no-unused-components home, }, }; </script> <style scoped> </style>
// 定义对象 provide: { name: "李四", age: 20, height: 123, weight: 78, email: "2678903458@qq.com", qq: "2386754567", weixing: "12389999933", }
子组件2
// 取值 inject: ["name", "age", "height", "weight", "email", "qq", "weixing"],
<template> <h6> 在home.vue组件中和content组件中利用 provide定义对象 利用 inject取出对象 </h6> <div class="home"> <content></content> <table> <tr> <th>姓名</th> <th>年龄</th> <th>身高</th> <th>体重</th> <th>邮箱</th> <th>qq</th> <th>微信</th> </tr> <tr> <td> <span>{{ name }}</span> </td> <td> <span>{{ age }}</span> </td> <td> <span>{{ height }}</span> </td> <td> <span>{{ weight }}</span> </td> <td> <span>{{ email }}</span> </td> <td> <span>{{ qq }}</span> </td> <td> <span>{{ weixing }}</span> </td> </tr> </table> </div> </template> <script> import content from '../components/content.vue' // home 与content组件为兄弟元素 export default { // eslint-disable-next-line vue/multi-word-component-names name: "home", data() { return { message: "Hello world vue cli", }; }, components: { // eslint-disable-next-line vue/no-unused-components content }, // 取值 inject: ["name", "age", "height", "weight", "email", "qq", "weixing"], methods: { btnclick() { console.log("为难忘"); }, }, }; </script> <style scoped> .home { background-color: rgb(214, 248, 177); display: flex; } .home span { font-size: 20px; background-color: rgb(236, 253, 239); color: red; flex: 1; } table { width: 100%; background-color: rgb(176, 230, 232); color: rgb(255, 0, 0); font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif; } td { width: 18%; border-radius: 10px; } td { text-align: center; line-height: 60px; height: 60px; border: 3px solid green; } </style>
组件通信答案
<!-- eslint-disable vue/require-v-for-key --> <template> <div class="app"> <div class="big_father"> <span v-for="(item, index) in arrays" :key="index.id + ''" class=".big_father" :class="{ active: isshow === index }" @click="btnclick(index)" >{{ item }} {{ index }}</span > </div> <div> <span v-for="(item, index) in infor" :key="index.id + ''" class=".big_father" :class="{ active: isshow === index }" @click="btnclick1(ko)">{{ item }} {{ index }}</span > </div> <yf v-show="isshow === 0"></yf> <kz v-show="isshow === 1"></kz> <xz v-show="isshow === 2"></xz> <sy v-show="isshow === 3"></sy> <wt v-show="isshow === 4"></wt> </div> </template> <script> // 导入文件信息 import yf from "./components/yf.vue"; import xz from "./components/xz.vue"; import kz from "./components/kz.vue"; import sy from "./components/sy.vue"; import wt from './components/wt.vue'; export default { components: { // eslint-disable-next-line vue/no-unused-components yf, // eslint-disable-next-line vue/no-unused-components xz, // eslint-disable-next-line vue/no-unused-components kz, // eslint-disable-next-line vue/no-unused-components sy, wt }, name: "app", data() { return { message: "Hello world vue cli", isshow: 0, arrays: ["衣服", "鞋子", "裤子", "上衣", "外套"], infor: ["衣服页面", "鞋子页面", "裤子页面", "上衣页面", "外套页面"], index:0, ko:true }; }, methods: { btnclick(flag) { this.isshow = flag; }, btnclick1(ko){ this.ko= !ko } }, }; </script> <style scoped> .active { color: red; background-color: azure; border: 2px solid lightseagreen; border-bottom: 8px solid red; border-radius: 12px; } .big_father { display: flex; } .big_father div { text-align: center; height: 60px; line-height: 60px; flex: 1; color: white; background-color: rgb(28, 125, 147); } .big_father div span { text-align: center; height: 60px; line-height: 60px; width: 100px; flex: 1; color: white; background-color: rgb(116, 214, 236); } button { height: 60px; width: 100px; line-height: 60px; margin-left: 100px; } span { text-align: center; line-height: 60px; margin-left: 10px; display: inline-block; width: 17%; height: 60px; font-size: 20px; border-radius: 20px; background: rgb(121, 224, 235); border-right: 2px solid red; } </style>