09-vue组件化开发

本文详细介绍了Vue.js中的组件化开发,包括全局与局部组件注册、父子组件通信(props、自定义事件、$refs)、非父子组件通信(中间人模式、事件总线bus)、v-model通信以及动态组件和组件插槽的使用。通过实例展示了如何实现组件间的交互和内容分发,阐述了组件在实际开发中的重要性和灵活性。
摘要由CSDN通过智能技术生成

组件化开发

  • 什么是组件化:

    将一个功能实现的表现,结构,行为作一个整体来封装,形成一个组件,达到整体效果复用的目的。

  • Vue组件的注册方式:
    • 根组件:
      • 当前我们在开始使用vue的时候,就创建了一个组件,new Vue()实例化的过程 ,就是创建了一个vue的根组件,运行new Vue的文件就是vue项目中的根组件。
    • 注册组件(自定义组件)
    <div id="box">
        <!-- 使用组件navbar -->
        <navbar></navbar>
    </div>
    <script>
        // 注册组件navbar
        Vue.component("navbar",{
            //template:定义组件模板
            template : `
                <div style="background-color: #cccccc;">
                    <span @click="main()">{{ getMain }}</span>|
                    <span>home</span>|
                    <span>aboult</span>
                </div>
            `,
            methods:{
                main(){
                    console.log("回到首页")
                }
            },
            computed:{
                getMain(){
                    return "首页"
                }
            }
        })
        var vm = new Vue({
            el:"#box"
        })
        </script>
    

    程序说明:

    ​ 上面只是一个最基础的组件的注册和使用,这里有如下问题需要说明

    ​ 1,自定义的组件必须在根组件环境下才能运行。

    ​ 2,组件取名问题:component注册的组件名称如果是以驼峰的形式,如:navBar,那么在html中使用该组件时,必须书写成

    ​ 3, template定义的html片段:没有代码提示,没有高亮,会造书写容易出差,难以查错的情况,后续有解决办法

    ​ 4,css目前只能写成行内形式,后续有解决办法

    ​ 5,template片段只能包含一个根节点。否则会报错。

    ​ 6,组件是独立存在的,当前component内部的程序无法直接访问外部的模型状态或方法,将来可以通过组件之间通讯来解决

    ​ 7,组件中的数据模型必须定义在 data(){}函数中,data函数必须有return返回,如下:

    Vue.component("navbar",{
        template : `
            <div style="background-color: #cccccc;">
                <span @click="main()">{{ myMain }}</span>|
                <span>home</span>|
                <span>aboult</span>
            </div>
        `,
        methods:{
            main(){
                console.log("回到首页")
            }
        },
        data(){//
            return {
                myMain:"main"
            }
        }
    })
    
    • 全局组件:

      Vue.component():方法注册的组件都是全局组件。

    <div id="box">
        <!-- 页面中使用全局组件 -->
        <navbar></navbar>
        <tabbar></tabbar>
    </div>
    <script>
        //全局组件navbar
        Vue.component("navbar",{
            template : `
                <div style="background-color: #cccccc;">
                    <tabbar></tabbar>
                    navbar 这里也可以使用了tabbar
                </div>
            `
        })
        //全局组件tabbar
        Vue.component("tabbar",{
            template:`
                <div style="background:blue;">
                    tabbar
                </div>
            `
        })
        var vm = new Vue({
            el:"#box"
        })
    </script>
    
    • 注册局部组件
    全局组件tabbar
    Vue.component("tabbar",{
        //局部组件只能在当前组件下使用
        template:`
            <div style="background:blue;">
                tabbar
                <tabbarChild></tabbarChild>
            </div>
        `,
        //定义局部组件
        components:{
            "tabbarChild":{//局部组件名称
                //局部组件模板
                template:`<p>这是一个局部组件</p>`
            }
            
        }
    })
    
  • 父子组件之间的通信传值
    • 父传子:
    <div id="box">
        <!-- 父组件范围使用组件 -->
        <!-- 向子组件中传递的值有:home,detail,cart,flag,true,false -->
        <tabbar :text="home" :show-home="flag"></tabbar>
        <tabbar :text="detail" show-home="true"></tabbar>
        <!-- 没有添加show-home属性,默认设置为true -->
        <tabbar :text="cart"></tabbar>
    </div>
    <script>
        Vue.component("tabbar",{
            template:`
                <div style="background:blue;color:white;">
                    <button v-if="showHome">返回</button>
                    <span>导航--{{text}}</span>
                    <button>登录</button>
                </div>
            `,
            //props:["text","showHome"]//子组件通过自定义的行内属性获取父组件中传递过来的值
            // props:{
            //     text:String,//指定接收的数据类型
            //     showHome:Boolean//指定接收的数据类型是一个布尔值,如果传递过来的不是布尔值,程序会报错,提示错误原因
            // }
            props:{//完整写法
                text:{
                    type:String,
                    default:"默认值"
                },
                showHome:{
                    type:Boolean,
                    default:true
                }
            }
        })
        //根组件:tabbar组件的父组件
        var vm = new Vue({
            el:"#box",
            data:{
                //父组件中的数据
                home:"首页",
                detail:"详情",
                cart:"购物车",
                flag:false
            }
        })
    </script>
    
    • 子传父
    <div id="box">
        <!-- 使用子组件 -->
        <!-- 自定义事件myEvent,事件处理程序为getData,该处理程序要在父组件中定义 -->
        <child @myevent="getData"></child>
    </div>
    <script>
        Vue.component("child",{
            template:`
                <div style="background:blue;color:white;">
                    子组件--<button @click="sendData">点击传递数据给父组件</button>
                </div>
            `,
            data(){
                return {
                    //子组件中的模型状态
                    childData:"1000000"
                }
            },
            methods:{
                sendData(){//点击组件中的button后,会触发该处理程序
                    //事件分发机制 this.$emit,方法可以触发组件使用时的自定义事件
                    this.$emit("myevent",this.childData);
                }  
            }
        })
        //根组件
        var vm = new Vue({
            el:"#box",
            methods:{
                //父组件中定义的方法,用于接收子组件传递过来的数据
                getData(data){
                    //data参数保存了组件传递过来的数据
                    console.log("子组件中的数据:"+data);
                }
            }
        })
    </script>
    
  • 子传父:this.$refs:
    • vue中可以通过this.$refs获取页面中所有定义了ref行内属性的元素对象(DOM节点对象)
        <div id="box">
            <!-- 元素定义了ref行内属性,ref属性可以在任意的元素上绑定 -->
            <input type="text" ref="myinput">
            <div ref="mycontainer">container</div>
            <button @click="handleClick">click</button>
        </div>
        <script>
            
            //根组件
            var vm = new Vue({
                el:"#box",
                methods:{
                    handleClick(){
                        //通过this.$refs属性可以获取页面中所有绑定ref行内属性的DOM对象
                        console.log(this.$refs)
                    }
                }
            })
        </script>
    

在这里插入图片描述

  • 通过this.$refs属性获取子组件对象
<div id="box">
     <!-- 子组件上定义ref属性 -->
     <child ref="myChild"></child>
     <button @click="handleClick">获取子组件</button>
 </div>
 <script>
     Vue.component("child",{
         template:`<div>child</div>`,
         data(){
             return{
                 msg:"哈哈"
             }
         }
     })
     //根组件
     var vm = new Vue({
         el:"#box",
         methods:{
             handleClick(){
                 //通过this.$refs属性可以直接获取子组件对象
                 console.log(this.$refs.myChild)
             }
         }
     })
 </script>

在这里插入图片描述

  • 非父子组件之间的通信
    • 中间人模式:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="../js/vue.js"></script>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            .goodWarmp{
                width: 500px;
                display: flex;
                justify-content:left;
                border: 1px dashed black;
            }
            .goodWarmp>div:last-child{
                text-align: left;
            }
            .detail{
                width: 200px;
                height: 200px;
                background-color: #cccccc;
                position: fixed;
                right: 10px;
                top: 100px;
                border: 2px solid black;
            }
        </style>
    </head>
    <body>
        <div id="box">
            <button @click="handleAjax">ajax</button>
            <!-- 
                使用组件,显示商品列表
                :mydata:自定义属性,将数据传递给子组件
                @myevent="midHandle":自定义事件,用于处理子组件传递过来的数据
             -->
            <film-item v-for="(item,index) in dataList" :key="item.id" :mydata="item" @myevent="midHandle"></film-item>
            <!-- 使用组件显示详情信息
                detailmsg:接收从filmItem组件传递过来的数据
            -->
            <show-detail :detailmsg="midData"></show-detail>
        </div>
            
        <script>
            //创建组件filmItem,用于渲染商品列表界面
            Vue.component("filmItem",{
                template : `
                    <div class="goodWarmp">
                        <div>
                            <img :src="mydata.img"/>
                        </div>
                        <div>
                            <h2>{{mydata.nm}}</h2>
                            <p>
                                电影评分:<span>{{mydata.sc}}</span>
                            </p>
                            <p>
                                主要演员:<span>{{mydata.star}}</span>
                            </p>
                            <p>
                                <button @click="getDetail">详情</button>
                            </p>
                        </div>
                    </div>
                `,
                //通过组件中的自定义属性mydata接收父组件传递过来的数据
                props : ["mydata"],
                methods : {
                    getDetail(){//点击获取详情信息
                        //详情信息,需要传递到非父子组件showDetail中
                        //先传递给父组件,再由父组件传递给showDetail,父组件类似于一个中转站,起到了一个中间人的作用
                        this.$emit("myevent",this.mydata.showInfo);
                    }
                }
            })
            //创建详情显示组件
            Vue.component("showDetail",{
                template : `
                    <div class="detail">{{detailmsg}}</div>
                `,
                props : ['detailmsg']//接收filmItem的详情信息
            })
            var vm = new Vue({
                el : "#box",
                data : {
                    //保存商品列表数据
                    dataList : [],
                    //保存中间人传递的数据
                    midData : ""
                },
                methods : {
                    handleAjax(){
                        fetch("../data/maoyan.json")
                            .then(res=>res.json())
                            .then(res=>{
                                //请求获取数据
                                console.log(res.movieList)
                                //将数据保存在模型状态下
                                this.dataList = res.movieList
                            })
                    },
                    midHandle(detail){//中间人函数
                        console.log(detail);
                        this.midData = detail
                    }
                }
            })
        </script>
    </body>
    
    </html>
    
    • bus通信:

      创建一个新的Vue实例,通过实例下的 e m i t ( ) 方 法 通 过 事 件 分 发 的 形 式 派 发 一 个 自 定 义 事 件 , 通 过 实 例 下 的 、 emit()方法通过事件分发的形式派发一个自定义事件,通过实例下的、 emit()on()方法可以监听到$emit分发的事件,达到数据传递的目的

      bus.$emit(event,data)//发布

      ​ event:要发布的事件

      ​ data:要发布的信息数据

      ​ bus.$on(event,(data)=>{//监听

      ​ event:监听的事件

      ​ data:发布的对应数据

      ​ })

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="../js/vue.js"></script>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            .goodWarmp{
                width: 500px;
                display: flex;
                justify-content:left;
                border: 1px dashed black;
            }
            .goodWarmp>div:last-child{
                text-align: left;
            }
            .detail{
                width: 200px;
                height: 200px;
                background-color: #cccccc;
                position: fixed;
                right: 10px;
                top: 100px;
                border: 2px solid black;
            }
        </style>
    </head>
    <body>
        <div id="box">
            <child1></child1>
            <child2></child2>
        </div>
            
        <script>
           //创建中央事件总线 bus
           var bus = new Vue();
           Vue.component("child1",{
                template : `
                    <div>child1-<button @click="busClick">发布详细信息</button></div>
                `,
                methods : {
                    busClick(){
                        //分发一个自定义事件busEvent,并发布了信息数据
                        bus.$emit("busEvent",{name:"tom",age:19});
                    }
                }
            })
            Vue.component("child2",{
                template : `
                    <div>
                        <p>child2-订阅组件</p>
                        <p v-if="msg">{{msg.name}} | {{msg.age}}</p>
                    </div>
                `,
                mounted(){//生命周期函数,函数触发时机:DOM渲染完毕后就会执行的函数。
                    console.log("执行了")
                    //监听busEvent事件的分发,从而通过回调获取发布的信息数据
                    bus.$on("busEvent",(data)=>{
                        console.log("获取到详情了",data);
                        //保存数据模型状态
                        this.msg = data
                    });
                },
                data(){
                    return {
                        msg : null
                    }
                }
            })
            var vm = new Vue({
                el : "#box"
            })
        </script>
    </body>
    
    </html>
    
    • bus通信实现中间人模式中的案例
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="../js/vue.js"></script>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            .goodWarmp{
                width: 500px;
                display: flex;
                justify-content:left;
                border: 1px dashed black;
            }
            .goodWarmp>div:last-child{
                text-align: left;
            }
            .detail{
                width: 200px;
                height: 200px;
                background-color: #cccccc;
                position: fixed;
                right: 10px;
                top: 100px;
                border: 2px solid black;
            }
        </style>
    </head>
    <body>
        <div id="box">
            <button @click="handleAjax">ajax</button>
            <!-- 
                使用组件,显示商品列表
                :mydata:自定义属性,将数据传递给子组件
             -->
            <film-item v-for="(item,index) in dataList" :key="item.id" :mydata="item"></film-item>
            <show-detail></show-detail>
        </div>
            
        <script>
            var bus = new Vue();//新实例
            //创建组件filmItem,用于渲染商品列表界面
            Vue.component("filmItem",{
                template : `
                    <div class="goodWarmp">
                        <div>
                            <img :src="mydata.img"/>
                        </div>
                        <div>
                            <h2>{{mydata.nm}}</h2>
                            <p>
                                电影评分:<span>{{mydata.sc}}</span>
                            </p>
                            <p>
                                主要演员:<span>{{mydata.star}}</span>
                            </p>
                            <p>
                                <button @click="emitDetail">详情</button>
                            </p>
                        </div>
                    </div>
                `,
                //通过组件中的自定义属性mydata接收父组件传递过来的数据
                props : ["mydata"],
                methods : {
                    emitDetail(){//发布信息
                        bus.$emit("myevent",this.mydata.showInfo);
                    }
                }
            })
            //创建详情显示组件
            Vue.component("showDetail",{
                template : `
                    <div class="detail">{{detail}}</div>
                `,
                mounted(){
                    bus.$on("myevent",data=>{
                        //保存监听到的信息
                        this.detail = data
                    })
                },
                data(){
                    return {
                        detail : "请点击查看详情"
                    }
                }
            })
            var vm = new Vue({
                el : "#box",
                data : {
                    //保存商品列表数据
                    dataList : [],
                },
                methods : {
                    handleAjax(){
                        fetch("../data/maoyan.json")
                            .then(res=>res.json())
                            .then(res=>{
                                //请求获取数据
                                console.log(res.movieList)
                                //将数据保存在模型状态下
                                this.dataList = res.movieList
                            })
                    }
                }
            })
        </script>
    </body>
    </html>
    
    • v-model通信

      v-model语法糖,可以直接实现组件之间的数据传递

      v-model用于组件实例上,在组件内部可以直接通过props关联上一个value,

      组件内部的input元素需要注册一个input事件,并在处理函数中通过分发input事件将数据再次发布出去。

        <div id="box">
            <!-- 
                v-model绑定一个uname状态
                父组件中的uname模板状态可以接收到子组件中input的value值 
            -->
            <my-input type="text" title="姓名" v-model="uname"></my-input>
            <my-input type="password" title="密码" v-model="pass"></my-input>
            <my-input type="number" title="电话" v-model="phone"></my-input>
    
            <button type="submit" @click="registerClick">register</button>
            <button type="reset" @click="clearClick">reset</button>
        </div>
            
        <script>
            Vue.component("myInput",{
                template : `
                    <div>
                        <label>{{title}}</label>
                        <input :type="type" @input="handleInput" :value="value"/>
                    </div>
                `,
                //props直接绑定value,可以与组件实例中的属性v-model关联
                props : ["type","title","value"],
                methods : {
                    handleInput(eve){
                        //console.log(eve.target.value);
                        //分发一个input事件,将改变后的value传递出去
                        //父组件因为v-model的双向数据绑定关系,可以直接获取到对应的内容
                        this.$emit("input",eve.target.value);
                    }
                }
            })
            var vm = new Vue({
                el : "#box",
                data : {
                    uname : "",
                    pass : "",
                    phone : 0
                },
                methods : {
                    registerClick(){//点击获取所有字段的内容
                        console.log(this.uname,this.pass,this.phone);
                    },
                    clearClick(){
                        this.uname = "",
                        this.pass = "",
                        this.phone = ""
                    }
                }
            })
        </script>
    
  • 动态组件

    • 方案一:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="../js/vue.js"></script>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            *{
                padding: 0;
                margin: 0;
            }
            body{
                width: 100%;
                height: 100%;
            }
            footer{
                height: 30px;
                width: 100%;
                background-color: #cccccc;
                position: fixed;
                left: 0;
                bottom: 0;
            }
            footer ul{
                list-style: none;
                height: 100%;
                display: flex;
                justify-content: space-between;
            }
            footer ul li{
                text-align: center;
                width: 33%;
                line-height: 30px;
            }
        </style>
    </head>
    <body>
        <div id="box">
            <!-- 当isWhitch状态为1时,显示home组件页面 -->
            <home v-show="isWhitch === 1"></home>
             <!-- 当isWhitch状态为2时,显示detail组件页面 -->
            <detail v-show="isWhitch === 2"></detail>
            <!-- 当isWhitch状态为3时,显示cart组件页面 -->
            <cart v-show="isWhitch === 3"></cart>
            <footer>
                <ul>
                    <!-- 点击时修改isWhitch状态值,以些决定显示哪个组件作为当前页面显示 -->
                    <li @click=" isWhitch = 1 ">首页</li>
                    <li @click=" isWhitch = 2 ">详情</li>
                    <li @click=" isWhitch = 3 ">购物车</li>
                </ul>
            </footer>
        </div>
            
        <script>
           Vue.component("home",{
               template : `<div>home</div>`
           })
           Vue.component("detail",{
               template : `<div>detail</div>`
           })
           Vue.component("cart",{
               template : `<div>cart</div>`
           })
            var vm = new Vue({
                el : "#box",
                data : {
                    isWhitch : 1//定义初始值
                }
            })
        </script>
    </body>
    </html>
    
    • 方案二,使用vue中的自定义component标签
      • 标签是Vue框架自定义的标签,它的用途就是可以动态绑定我们的组件,根据数据的不同更换不同的组件
        <div id="box">
            <!-- :is指令,绑定模型状态,当状态改变时,会自动切换到对应的组件显示 -->
            <component :is="isWhitch"></component>
            <footer>
                <ul>
                    <!-- 点击时修改isWhitch状态值,以些决定显示哪个组件作为当前页面显示 -->
                    <li @click=" isWhitch = 'home' ">首页</li>
                    <li @click=" isWhitch = 'detail' ">详情</li>
                    <li @click=" isWhitch = 'cart' ">购物车</li>
                </ul>
            </footer>
        </div>
        <script>
           Vue.component("home",{
               template : `<div>home</div>`
           })
           Vue.component("detail",{
               template : `<div>detail</div>`
           })
           Vue.component("cart",{
               template : `<div>cart</div>`
           })
            var vm = new Vue({
                el : "#box",
                data : {
                    isWhitch : 'home'//定义初始值
                }
            })
    
    • 在动态绑定组件时,使用keep-alive标签,可以保持组件的实时状态

    如:

        <div id="box">
            <!-- :is指令,绑定模型状态,当状态改变时,会自动切换到对应的组件显示 -->
            <!-- 使用keep-alive标签可以保证在切换组件页面时,不会破坏用户在原组件的输入状态 -->
            <keep-alive>
                <component :is="isWhitch"></component>
            </keep-alive>
            <footer>
                <ul>
                    <!-- 点击时修改isWhitch状态值,以些决定显示哪个组件作为当前页面显示 -->
                    <li @click=" isWhitch = 'home' ">首页</li>
                    <li @click=" isWhitch = 'detail' ">详情</li>
                    <li @click=" isWhitch = 'cart' ">购物车</li>
                </ul>
            </footer>
        </div>
        <script>
           Vue.component("home",{
               template : `<div>
                    home <input type="text"/>
                </div>`
           })
           Vue.component("detail",{
               template : `<div>detail</div>`
           })
           Vue.component("cart",{
               template : `<div>cart</div>`
           })
            var vm = new Vue({
                el : "#box",
                data : {
                    isWhitch : 'home'//定义初始值
                }
            })
        </script>
    
  • 组件插槽slot(内容分发)

    混合父组件的内容与子组件自己的模板–>内容分发

    父组件模板的内容在父组件作用域内编译,子组件模板的内容在子组件作用域内编译

    • 在一个组件实例中 ,无法插入其它元素,插入的元素不会被渲染,会被组件内部的元素覆盖
        <div id="box">
            <child>
                <!-- 组件实例中使用的元素不会被渲染 -->
                <div>11111111111</div>
            </child>
        </div>
        <script>
           Vue.component("child",{
            //    内部的元素会覆盖组件实例中插入的元素
               template:`
                    <div>child</div>     
               `
           })
            var vm = new Vue({
                el : "#box",
                data : {}
            })
        </script>
        
    

在这里插入图片描述

  • 如果要在组件实例中插入其它元素并被成功渲染,需要使用组件插槽slot;
    <div id="box">
        <child>
            <!-- 这里插入的元素将全部被插入到slot插槽中 -->
            <div>11111111111</div>
            <div>22222222222</div>
            <div>33333333333</div>
        </child>
    </div>
    <script>
       Vue.component("child",{
        //    使用slot插槽,组件实例中的所有元素都将插入到这个slot插槽中
        //    有多个slot,则将会被对应的插入多少次。
           template:`
                <div>
                    <slot></slot> 
                    child
                    <slot></slot>
                </div>  
                 
           `
       })
        var vm = new Vue({
            el : "#box",
            data : {}
        })
    </script>
    

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uAaddpSv-1630632678351)(/images/slot2.png)]

  • 我们可以将元素插入到指定的插槽中

在这里插入图片描述

  • slot插槽应用
    • 下面看一个简单的导航案例
<div id="box">
     <navbar @myevent="isShow=!isShow"></navbar>
     <sidebar v-show="isShow"></sidebar>
 </div>
 <script>
    Vue.component("navbar",{
        template:`
             <div style="background:skyblue">
                 导航栏-<button @click="handleClick">click</button>
             </div>  
        `,
        methods:{
             handleClick(){
                 this.$emit("myevent")
             }
        }
    })
    Vue.component("sidebar",{
        template:`
             <div>
                 <ul style="width:100px;background:#ccc;">
                     <li>1</li>
                     <li>2</li>
                     <li>3</li>
                 </ul>
             </div>  
        `
    })
     var vm = new Vue({
         el : "#box",
         data : {
             isShow:false
         }
     })
 </script>

通过分析上面的案例,我们发现,导航点击的组件中,需要通过事件分发的方式,才能处理父组件中的isShow状态值,使用插槽进行整改:可以将button按钮提取到父组件范围中插入,在父组件中,button按钮可以直接操作父组件下的isShow,无需通过子父组件之间传值方式来进行操作,使得程序变得既简洁又合理。

    <div id="box">
        <navbar>
            <!-- 这里的按钮可以直接操作父组件中的模型状态 -->
            <button @click="isShow=!isShow">click</button>
        </navbar>
        <sidebar v-show="isShow"></sidebar>
    </div>
    <script>
       Vue.component("navbar",{
           //组件中使用slot插槽来存放实例中的按钮
           template:`
                <div style="background:skyblue">
                    导航栏-<slot></slot>
                </div>  
           `
       })
       Vue.component("sidebar",{
           template:`
                <div>
                    <ul style="width:100px;background:#ccc;">
                        <li>1</li>
                        <li>2</li>
                        <li>3</li>
                    </ul>
                </div>  
           `
       })
        var vm = new Vue({
            el : "#box",
            data : {
                isShow:false
            }
        })
    </script>
  • slot的新用法 v-slot:name:必须使用在template标签上
<div id="box">
     <navbar>
         <template v-slot:left>
             <div>
                 <span><</span>
                 <span>返回</span>
             </div>
         </template>
         <template v-slot:middle>
             <div>
                 标题
             </div>
         </template>
         <template v-slot:right>
             <div>
                 <img width="25px" src="seach.png" alt="">
             </div>
         </template>
     </navbar>
    
 </div>
 <script>
    Vue.component("navbar",{
        //组件中使用slot插槽来存放实例中的按钮
        template:`
             <div style="display:flex;justify-content: space-around;">
                 <slot name="left"></slot>
                 <slot name="middle"></slot>
                 <slot name="right"></slot>
             </div>  
        `
    })
     var vm = new Vue({
         el : "#box",
         data : {}
     })
 </script>

在这里插入图片描述

v-slot还可以使用简写:

​ 我们知道,vue中,一些指令有其简写,如 v-bind:属性 的简写为:属性v-on:事件的简写为@事件

v-slot:name的简写为#name

    <div id="box">
        <navbar>
            <template #left>
                <div>
                    <span><</span>
                    <span>返回</span>
                </div>
            </template>
            <template #middle>
                <div>
                    标题
                </div>
            </template>
            <template #right>
                <div>
                    <img width="25px" src="seach.png" alt="">
                </div>
            </template>
        </navbar>
    </div>
  • 组件库网站:https://element.eleme.cn/#/zh-CN/component/installation

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值