09-vue组件化开发

Posted Ultraman_agul

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了09-vue组件化开发相关的知识,希望对你有一定的参考价值。

组件化开发

  • 什么是组件化:

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

  • 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">以上是关于09-vue组件化开发的主要内容,如果未能解决你的问题,请参考以下文章

    09-vue组件化开发

    09-vue组件化开发

    VUE学习笔记:8.vue组件化之概述,基本使用,全局组件与局部组件概念,父组件与子组件的概念

    09Vue 之 Vuex

    VUE移动端音乐APP学习十七:歌单详情页组件开发

    家政服务小程序实战教程12-详情页