vue seven day
组件插槽
<div id="app"> <chacao>bug</chacao> </div> <script> // 组件插槽 // 固定标签<slot></slot> // 在调用组件的时候:上述案例bug就是传递值, // 如果上述没有传递,则显示slot默认内容 Vue.component("chacao",{ template: ` <div> <strong>Error:</strong> <slot></slot> </div> ` }) var vm = new Vue({ el: "#app", }) </script>
具名插槽
<!-- 具名插槽 --> <div id="app"> <jumingchacao> <template #woshinp> <p>np1</p> </template> <p>meimingzi</p> </jumingchacao> </div> <script> // ----------------------------------------------------- // 具名插槽 // 其实就是给插槽起了名字 然后进行相对应的匹配 // 标签里直接使用slot属性已被启用 // 现在必须在template标签里写v-slot然后绑定名字 缩写#+slotname Vue.component("jumingchacao", { template: ` <div> <strong>Error:</strong> <slot></slot> <header> <slot name="woshinp"></slot> </header> </div> ` }) var vm = new Vue({ el: "#app", }) </script>
作用域插槽
应用场景:父组件对子组件的内容进行加工处理
<!-- 插槽作用域 --> <div id="app"> <chacaozyy :flist="list"> <template v-slot="ppoos"> <!-- 通过template绑定v-slot 拿到子组件模板传出的数据 就可以操控了 --> <strong v-if="ppoos.info.id==2">{{ppoos.info.name}}</strong> <p v-else>{{ppoos.info.name}}</p> </template> </chacaozyy> </div> <script> // 插槽作用域 // 应用场景:父组件对子组件的内容操控 // 子组件里通过slot绑定属性,属性名自定义,可以传出数据 // 父 通过template标签绑定v-slot,属性名自定义,拿到数据 // 然后可以在父组件处理子组件的数据 Vue.component("chacaozyy", { props:["flist"], template: ` <div> <ul :key="index" v-for="item,index in flist"> <li> <slot :info="item"></slot> </li> </ul> </div> ` }) var vm = new Vue({ el: "#app", data:{ list:[ { id:1, name:"apple" }, { id:2, name:"xigua" }, { id:3, name:"orange" } ] } }) </script>
购物车案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>购物车案例</title> </head> <body> <div id="app"> <my-cart></my-cart> </div> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> // 功能实现步骤 // 1.实现整体的布局和样式效果 // 2.划分独立的功能组件 // 3.组合所有的子组件形成整体结构 // 4.逐渐实现各个组件功能:标题组件、列表组件、结算组件 var CartTitle = { props: ["username"], template: ` <div class="title">{{username}}的商品</div> ` } var CartList = { props: ["plist"], template: ` <div> <div :key="item.id" v-for="item in plist" class="item"> <img :src="item.img"/> <div class="name">{{item.name}}</div> <div class="change"> <a herf="" @click.prevent="sub(item.id)">-</a> <input type="text" class="num" :value="item.num" @blur="changeNum(item.id,$event)"></input> <a herf="" @click.prevent="add(item.id)">+</a> </div> <button class="del" @click=del(item.id)>x</button> </div> </div> `, methods: { del: function (id) { // 把id传给父组件 让父组件去操作数据 this.$emit("cart-del", id) }, changeNum: function (id, event) { // 通过失去焦点事件获取到当前的id 及用户修改的value this.$emit("change-num", { id: id, num: event.target.value, type: "change" }) }, sub: function (id) { this.$emit("change-num", { id: id, type: "sub" }) }, add: function (id) { this.$emit("change-num", { id: id, type: "add" }) } } } var CartTotal = { props: ["plist"], template: ` <div class="total"> <span>总价:{{total}}</span> <button>结算</button> </div> `, computed: { total: function () { // 用计算属性计算总价 var t = 0; this.plist.forEach(element => { t += element.num * element.price }); return t } } } Vue.component("my-cart", { data: function () { return { uname: "元素女皇", list: [ { id: 1, name: "电视机", price: 3299, num: 1, img: "" }, { id: 2, name: "电脑", price: 7999, num: 1, img: "" }, { id: 3, name: "手机", price: 5999, num: 1, img: "" }, { id: 4, name: "耳机", price: 98, num: 1, img: "" }, { id: 5, name: "口罩", price: 3, num: 1, img: "" } ] } }, template: ` <div> <cart-title :username="uname"></cart-title> <cart-list :plist="list" @cart-del=delCart($event) @change-num="Changenum($event)"></cart-list> <cart-total :plist="list"></cart-total> </div> `, components: { "cart-title": CartTitle, "cart-list": CartList, "cart-total": CartTotal }, methods: { delCart: function (id) { // 先找到对应id的index var index = this.list.findIndex(item => { return item.id == id; }) //删除对应的数据 this.list.splice(index, 1) }, Changenum: function (val) { if (val.type == "change") { // 根据子组件传过来的数据 更新num // some是arr的一个方法 可以用来找数据 this.list.some(item => { if (item.id == val.id) { // 如果找到id 就把list里面的num换成最新的num item.num = val.num; return true } }) } else if (val.type == "sub") { this.list.some(item => { if (item.id == val.id) { // 如果找到id 就把list里面的num-=1 if(item.num >0){ item.num -=1; } return true } }) }else{ this.list.some(item => { if (item.id == val.id) { // 如果找到id 就把list里面的num换成最新的num item.num +=1; return true } }) } } } }) var vm = new Vue({ el: "#app", data: { } }) </script> </body> </html>