zoukankan      html  css  js  c++  java
  • 5. 组件化开发

     本节内容:

      一、组件[component]

        1.1局部组件

        1.2 默认组件(全局组件)

      二、组件传值

        2.1 父组件往子组件传值

        2.2 子组件父组件传值

        2. 3 平行组件传值

    一、组件[component]

         组件(Component)是自定义封装的功能。在前端开发过程中,经常出现多个网页的功能是重复的,而且很多不同的网站之间,也存在同样的功能

    而在网页中实现一个功能,需要使用html定义功能的内容结构,使用css声明功能的外观样式,还要使用js来定义功能的特效,因此就产生了把一个

    功能相关的[HTML、css和javascript]代码封装在一起组成一个整体的代码块封装模式,我们称之为“组件”。

    所以,组件就是一个html网页中的功能,一般就是一个标签,标签中有自己的html内容结构,css样式和js特效。

    这样,前端人员就可以在开发时,只需要书写一次代码,随处引入即可使用。

     

    我们在进行vue开发的时候,还记得我们自己创建的vm对象吗,这个vm对象我们称为一个大组件,根组件(页面上叫Root),在一个网页的开发中,

    根据网页上的功能区域我们又可以细分成其他组件,或称为子组件

    注意: 在组建中template ,写组件中的html标签时,外层一定要套一个标签

    1.1局部组件

    三步:声子、用子、挂子

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <script src="vue.js"></script>
    </head>
    <body>
    
    <div id="app">
        <div class="vheader">
            这是头部{{msg}}
        </div>
        <App/>  <!--3 使用子组件-->
    
    </div>
    
    
    </body>
    <script>
        //子组件的名称尽量不要叫做Header或者vHeader等,以防和最新的H5中的标签名称冲突,导致组件无法使用
        //  1 声明子组件
        let App = {
    
            data(){
                return { //组件中必须写成函数形式的
                    'appmsg':'hello app!'
                }
            },
            // 写组件的html标签的地方
            template:`
                <div class="content">
    
                    内容部分{{appmsg}}
                </div>
    
            `
    
    
        };
    
    
    
        let vm = new Vue({
            el:'#app',
    
            data(){
                return {
                    'msg':'hello'
                }
            },
    
            components:{
                //App:App  //键的名臣和组件名称相同时,可以简写
                App,  // 2 挂载子组件
    
            }
    
        })
    
    
    </script>
    </html>
    View Code

    1.2 默认组件(全局组件)

    直接看代码,局部组件使用时需要挂载,全局组件使用时不需要挂载。那么他们两个什么时候用呢,

    局部组件就在某个局部使用的时候,全局组件是大家公用的,或者说每个页面都有这么一个功能的

    时候,在哪里可能都会用到的时候。

    <div id="app">
        <addnum></addnum>
    
    </div>
    
    <script>
        Vue.component("addnum",{
            template:'<div><input type="text" v-model="num"><button @click="num+=1">点击</button></div>',
            data: function(){
                // 写在这里的数据只有当前组件可以使用
                return {
                    num:1,
                }
            }
        });
    
    
        var vm = new Vue({
            el:"#app",
            data:{
    
            }
        })
    </script>
    View Code

    二、组件传值

    2.1 父组件往子组件传值

    两步:  

    1.在子组件中使用props属性声明,然后可以直接在子组件中任意使用

    2.父组件要定义自定义的属性

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <script src="vue.js"></script>
    </head>
    <body>
    
    <div id="app">
        <div class="vheader">
            这是头部{{msg}}
        </div>
        <App :xx="msg"/> 
    
    </div>
    
    
    </body>
    <script>
        let App = {
    
            data(){
                return {
                    'appmsg':'hello app!'
                }
            },
            template:`
                <div class="content">
    
                    内容部分{{appmsg}}--{{xx}}
                </div>
    
            `,
            props:['xx',]
    
        };
    
        let vm = new Vue({
            el:'#app',
    
            data(){
                return {
                    'msg':'hello'
                }
            },
    
            components:{
                App,  
    
            }
    
        })
    
    
    
    
    </script>
    </html>
    示例
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            .c1{
                background-color: green;
            }
        </style>
    </head>
    <body>
    
    <div id="app">
        <h1>{{ganmao}}</h1>
        <!-- 用子: 使用子组件 -->
    
        <App></App>
    
    
    
    </div>
    
    
    </body>
    <script src="../vue.js"></script>
    <script src="../axios.js"></script>
    <script>
        // 局部组件
        //1 声子: 声明子组件
        let Vheader = {
            data(){
                return {
                    msg:'我是子组件1号'
                }
            },
            // 写组件的html标签的地方
            template:
                        `
                <div class="c1">
                    <h3 style="color:#ff0000">{{msg}}</h3>
                    <h2 style="color:blue;">{{son}}</h2>
    
                </div>
            `
            ,
            props:['son', ],  //第二步: 写父组件中使用子组件时的自定义标签属性名称,那么他就可以拿到标签属性对应的值,并且可以作为当前子标签的一个数据属性来使用
    
        };
    
        let App = {
            data(){
                return {
                    app_num:80,
                }
            },
    
            components: {
                Vheader,
            },
    
            // 注意: 写组件中的html标签时,外层一定要套一个标签
    
    
            // 第一步: 使用子组件的地方写自定义属性
            // 静态传值: <Vheader son="20"></Vheader>
            // 动态传值: <Vheader :son="app_num"></Vheader>
            template:
                        `
                   <div class="app">
                       <h2>我是app组件</h2>
                      <Vheader :son="app_num"></Vheader>
    
    
                  </div>
    
                        `
        }
    
        
    
        let vm  = new Vue({
            el:'#app',
            // data:{}
            data(){
                return {
                    ganmao:'xxx',
    
                }
            },
            components:{
               App,
            }
    
    
        })
    
    
    </script>
    
    
    </html>
    View Code
    使用父组件传递数据给子组件时, 注意一下几点:
    
    1. 传递数据是变量,则需要在属性左边添加冒号.
    
       传递数据是变量,这种数据称之为"动态数据传递"
    
       传递数据不是变量,这种数据称之为"静态数据传递"
    
    2. 父组件中修改了数据,在子组件中会被同步修改,但是,子组件中的数据修改了,是不是影响到父组件中的数据.
    
       这种情况,在开发时,也被称为"单向数据流"

    2.2 子组件父组件传值

    两步:

      a.子组件中使用this.$emit('fatherHandler',val);fatherHandler是父组件中使用子组件的地方添加的绑定自定义事件,

      注意,如果fatherHandler报错了,那么可能是你的vue版本不支持自定义键名称fatherHandler中有大写字母,

      所以我们改成father-handler或者直接就全部小写就可以了

      b.父组件中的methods中写一个自定义的事件函数:appFatherHandler(val){},在函数里面使用这个val,

      这个val就是上面子组件传过来的数据

     第一步:在父组件使用子组件的地方写自定义事件
      <Vheader @fatherHandler="xx"></Vheader>

    第二步: 在子组件中this.$emit('fatherHandler', 200);
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <script src="vue.js"></script>
    </head>
    <body>
    
    <div id="app">
        <div class="vheader">
            这是头部{{msg}} -- {{sondata}}
        </div>
        <App @son="sonDataHandler"/>
    
    </div>
    
    
    </body>
    <script>
        let App = {
    
            data(){
                return {
                    'appmsg':'hello app!'
                }
            },
            template:`
                <div class="content">
    
                    内容部分{{appmsg}}
                    <button @click="xH"></button>
                </div>
    
            `,
            methods:{
                xH(){
                    this.$emit('son',this.appmsg)
                }
            }
    
        };
    
        let vm = new Vue({
            el:'#app',
    
            data(){
                return {
                    'msg':'hello',
                    'sondata':'xxx',
                }
            },
    
            components:{
                App,
    
            },
            methods:{
                sonDataHandler(val){
                    console.log(val);
    
                    this.sondata = val;
    
                }
    
            }
    
        })
    
    
    </script>
    </html>
    View Code
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            .c1{
                background-color: green;
            }
        </style>
    </head>
    <body>
    
    <div id="app">
        <h1>{{ganmao}}</h1>
        <!-- 用子: 使用子组件 -->
    
        <App></App>
    
    
    
    </div>
    
    
    </body>
    <script src="../vue.js"></script>
    <script src="../axios.js"></script>
    <script>
        // 局部组件
        //1 声子: 声明子组件
        let Vheader = {
            data(){
                return {
                    msg:'我是子组件1号',
                    header_num:99,
                }
            },
            // 写组件的html标签的地方
            template:
                        `
                <div class="c1">
                    <h3 style="color:#ff0000">{{msg}}</h3>
                    <button @click="zouni">zouni</button>
    
                </div>
            `
            ,
            methods: {
                zouni(){
                    console.log(this);
                    // this -- 组件对象
                    this.$emit('fatherHandler', this.header_num);
                }
    
            }
    
    
        };
    
        let App = {
            data(){
                return {
                    app_num:80,
    
                    //  声明数据属性,承接子组件传递来的值
                    son_data:0,
                }
            },
    
            components: {
                Vheader,
            },
    
            // 第一步:在父组件使用子组件的地方写自定义事件
            // <Vheader @fatherHandler="xx"></Vheader>
    
            // 第二步: 在子组件中this.$emit('fatherHandler', 200);
    
    
            template:
                        `
                   <div class="app">
                       <h2>我是app组件</h2>
                      <Vheader @fatherHandler="xx"></Vheader>
                       <h3 style="color:yellow;">{{son_data}}</h3>
    
                  </div>
    
                        `
            ,
    
            methods:{
                xx(val){
                    this.son_data = val;
                    console.log(this);
                    // console.log('>>>>>', val);
                },
    
    
            }
    
    
    
        }
    
    
        let vm  = new Vue({
            el:'#app',
            // data:{}
            data(){
                return {
                    ganmao:'xxx',
    
                }
            },
            components:{
               App,
            },
    
    
    
        })
        console.log(vm);
    
    </script>
    
    
    </html>
    View Code

    2. 3 平行组件传值

    什么是平行组件,看图

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            .c1{
                background-color: green;
            }
        </style>
    </head>
    <body>
    
    <div id="app">
    
        <h1>{{ganmao}}</h1>
        <!-- 用子: 使用子组件 -->
        <App></App>
    
    
    </div>
    
    
    </body>
    <script src="../vue.js"></script>
    <script src="../axios.js"></script>
    <script>
    
        // 第一步:声明公交车
    
        let bus = new Vue();
    
    
        let Vheader2 = {
            data(){
                return {
                    msg:'我是子组件2号',
                    header2_num:88,
                    vheader_data:'',
                }
            },
            // 写组件的html标签的地方
            template:
                        `
                <div class="c1">
                    <h3 style="color:#ff0000">{{msg}}</h3>
                    <h3>{{vheader_data}}</h3>
    
                </div>
            `,
            created(){
    
                // 第三步:在公交车上获取值
                bus.$on('xxx',(val) => {
                    console.log('???', val); // ??? 99
    
                    this.vheader_data = val;
    
                });
    
    
            }
    
        }
    
        // 局部组件
        //1 声子: 声明子组件
        let Vheader = {
            data(){
                return {
                    msg:'我是子组件1号',
                    header_num:99,
                }
            },
            // 写组件的html标签的地方
            template:
                        `
                <div class="c1">
                    <h3 style="color:#ff0000">{{msg}}</h3>
                     <button @click="zouni">zouni</button>
    
                </div>
            `
            ,
            methods: {
                zouni(){
                    // 第二步:往公交车上添加值
                    bus.$emit('xxx', this.header_num)
                }
    
            }
    
    
        };
    
        let App = {
            data(){
                return {
                    app_num:80,
    
                    //  声明数据属性,承接子组件传递来的值
                    son_data:0,
                }
            },
    
            components: {
                Vheader,
                Vheader2,
            },
    
            // 第一步:在父组件使用子组件的地方写自定义事件
            // <Vheader @fatherHandler="xx"></Vheader>
    
            // 第二步: 在子组件中this.$emit('fatherHandler', 200);
    
    
            template:
                        `
                   <div class="app">
                       <h2>我是app组件</h2>
                      <Vheader></Vheader>
                       <Vheader2></Vheader2>
    
                  </div>
    
                        `
            ,
    
            methods:{
                xx(val){
                    this.son_data = val;
                    console.log(this);
                    // console.log('>>>>>', val);
                },
    
    
            }
    
    
    
        }
    
    
        let vm  = new Vue({
            el:'#app',
            // data:{}
            data(){
                return {
                    ganmao:'xxx',
    
                }
            },
            components:{
               App,
            },
    
    
    
        })
        console.log(vm);
    
    </script>
    
    
    </html>
    例子1
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <script src="vue.js"></script>
    </head>
    <body>
    
    <div id="app">
        <div class="vheader">
            这是头部{{msg}} -- {{sondata}}
        </div>
        <!--<App :xx="msg"/>-->
        <App @sonHa="sonDataHandler"/>
    
    </div>
    
    
    </body>
    <script>
        let bus = new Vue();
    
        Vue.component('T1',{
            data(){
                return {
                    't1num':100,
                }
            },
            template:`
    
                <div class="t1">
    
                    {{t1num}}
                    <button @click="f1">走你</button>
    
                </div>
            `,
            methods:{
                f1(){
                    // console.log(this.t1num);
                    bus.$emit('TestData',this.t1num)
    
                }
            }
    
        });
    
        Vue.component('T2',{
    
            data(){
                return {
                    't2num':200,
                    't1n':0,
                }
            },
            template:`
    
                <div class="t2">
    
                    <h1>{{t2num}}</h1>
                    <h2 style="color:red;">{{t1n}}</h2>
    
                </div>
            `,
            created(){
                // console.log(this.t1n);
                bus.$on('TestData',(val)=>{
    
                    console.log(val);
                    this.t1n = val;
    
                })
    
            }
    
        });
    
    
        let App = {
    
            data(){
                return {
                    'appmsg':'hello app!'
                }
            },
            template:`
                <div class="content">
    
                    内容部分{{appmsg}}
                    <button @click="xH">点击</button>
                    <T1></T1>
                    <T2></T2>
                </div>
    
            `,
            methods:{
                xH(){
                    this.$emit('sonHa',this.appmsg)
                }
                // console.log(this);
    
    
            }
            // props:['xx',]
    
    
        };
    
    
    
        let vm = new Vue({
            el:'#app',
    
            data(){
                return {
                    'msg':'hello',
                    'sondata':'xxx',
                }
            },
    
            components:{
                App,
    
            },
            methods:{
                sonDataHandler(val){
                    console.log(val);
    
                    this.sondata = val;
    
                }
    
            }
    
        })
    
    </script>
    </html>
    例子2

     

     

  • 相关阅读:
    349. 两个数组的交集
    383. 赎金信
    242. 有效的字母异位词
    844. 比较含退格的字符串
    904. 水果成篮
    剑指offer(9)变态跳台阶
    剑指offer(8)跳台阶
    剑指offer(7)斐波那契数列
    剑指offer(6)旋转数组的最小数字
    剑指offer(5)用两个栈实现队列
  • 原文地址:https://www.cnblogs.com/yj0405/p/14562964.html
Copyright © 2011-2022 走看看