案例 组件信息的通信
自己思考一下 答案在本文章的后面
插槽 v-slot
- 这个时候我们就可以来定义插槽slot: 插槽的使用过程其实是抽取共性、预留不同;
- 我们会将共同的元素、内容依然在组件内进行封装;
- 同时会将不同的元素使用slot作为占位,让外部决定到底显示什么样的元素;
- 如何使用slot呢?
- Vue中将 <slot> 元素作为承载分发内容的出口;
- 在封装组件中,使用特殊的元素<slot>就可以为封装组件开启一个插槽;
- 该插槽插入什么内容取决于父组件如何使用;
插槽就是子组件中的提供给父组件使用的一个占位符,用<slot></slot> 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的<slot></slot>标签。简单理解就是子组件中留下个“坑”,父组件可以使用指定内容来补“坑”.
页面控制平台
案例一
这个案例带你去理解啥是插槽
主页面
<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-namesname: "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-componentscontent,// eslint-disable-next-line vue/no-unused-componentshome,},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-namesname: "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-componentshome,},
};
</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-namesname: "home",data() {return {message: "Hello world vue cli",};},components: {// eslint-disable-next-line vue/no-unused-componentscontent},// 取值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"><spanv-for="(item, index) in arrays":key="index.id + ''"class=".big_father":class="{ active: isshow === index }"@click="btnclick(index)">{{ item }} {{ index }}</span></div><div><spanv-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-componentsyf,// eslint-disable-next-line vue/no-unused-componentsxz,// eslint-disable-next-line vue/no-unused-componentskz,// eslint-disable-next-line vue/no-unused-componentssy,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>