vue组件化开发

1.什么是组件化开发?

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

 

而在网页中实现一个功能,需要使用html定义功能的内容结构,使用css声明功能的外观样式,还要使用js来定义功能的特效,因此就产生了把一个功能相关的[HTML、css和javascript]代码封装在一起组成一个整体的代码块封装模式,我们称之为“组件”。

 

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

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

我们在进行vue开发的时候,还记得我们自己创建的vm对象吗,这个vm对象我们称为一个大组件,根组件(页面上叫Root),在一个网页的开发中,根据网页上的功能区域我们又可以细分成其他组件,或称为子组件

img

组件有两种:默认组件[全局组件] 和 单文件组件[局部组件]

局部组件 :

注意:每个组件中的template对应的标签,都必须有一个外层标签包裹

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>todolist</title>

</head>
<body>
    <div id="app">
        <!-- 3.使用子组件  用子 -->
<!--        <xx></xx>-->
<!--        <xx2></xx2>-->
    <Vheader></Vheader>
    <xxx></xxx>
    <Kk></Kk>
<!--    content  header footer aside section nav H5有一些新标签,注意,组件名称尽量不要和标签名称冲突 -->
    </div>
</body>
<script src="vue.js"></script>
<script src="axios.js"></script>
<script>
    // 组件化开发(将页面的每块功能,单独封装为一个组件,哪个页面用哪些组件,就直接拿到这几个组件,拼到页面上展示)
    // 1.声明子组件  声子
    let Vheader = {
        data(){
            return {
                nav_list:['个人中心','登录','注册']
            }
        },
        template:'<h1>{{nav_list}}</h1>',


    };

    let xxx = {
        data(){
            return {
                content_list:['xxx','ooo',]
            }
        },
        template:'<h1 style="color:red;">{{content_list}}</h1>',


    };

    // 全局组件  不需要挂载,直接使用
    Vue.component('Kk',{
        data(){
            return {
                name:'全局组件!!!'
            }
        },
        template:'<h1 style="color:tan;">{{name}}</h1>',

    })



    let vm  = new Vue({
        el:'#app',
        data(){
            return {
                data:'',
            }
        },

        created(){

        },
        components:{
            Vheader,  //2.挂载子组件  挂子
            // Content:Content,
            xxx,   // 键和值相同,就可以简写
        }


    })



</script>
</html>

全局组件

局部组件使用时需要挂载,全局组件使用时不需要挂载。那么他们两个什么时候用呢,局部组件就在某个局部使用的时候,全局组件是大家公用的,或者说每个页面都有这么一个功能的时候,在哪里可能都会用到的时候。

<div id="app">
    <Kk></Kk>

</div>

<script>
        // 全局组件  不需要挂载,直接使用
    Vue.component('Kk',{
        data(){
            return {
                name:'全局组件!!!'
            }
        },
        template:'<h1 style="color:tan;">{{name}}</h1>',

    })


    var vm = new Vue({
        el:"#app",
        data:{

        }
    })
</script>

2.组件传值

通过prop属性进行传值,父组件往子组件传值分为2步.

1.父组件在使用子组件时要定义自定义的属性:比如:<Vheader :ff="num"></Vheader>动态传值

静态传值:<Vheader ff="123"></Vheader>

2.在子组件中使用props属性声明:比如:props:['ff', ],然后子组件就可以将ff作为一个数据属性来使用了,比如:

template:`<div>
                    <h1>{{nav_list}}</h1>
                    <h2>{{nav_list}}</h2>
                    <h4 style="color:green;">{{ff}}</h4>

                </div>`,
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>todolist</title>

</head>
<body>
    <div id="app">
        <!-- 3.使用子组件  用子 -->
<!--        <xx></xx>-->
<!--        <xx2></xx2>-->
    <App></App>
<!--    content  header footer aside section nav H5有一些新标签,注意,组件名称尽量不要和标签名称冲突 -->
    </div>
</body>
<script src="vue.js"></script>
<script src="axios.js"></script>
<script>

    // 父组件往子组件传值:



    let Vheader = {
        data(){
            return {
                nav_list:['个人中心','登录','注册','username']
            }
        },
        template:`<div>
                    <h1>{{nav_list}}</h1>
                    <h2>{{nav_list}}</h2>
                    <h4 style="color:green;">{{ff}}</h4>

                </div>`,

        props:['ff', ],

    };


    let xxx = {
        data(){
            return {
                content_list:['xxx','ooo',]
            }
        },
        template:'<h1 style="color:red;">{{content_list}}</h1>',


    };

    let App = {
        data(){
            return {
                'xxx':'ooo',
                num:1000,
            }
        },
        // <Vheader ff="123"></Vheader> 静态传值
        template:
                `
                <div class="app">
                    <Vheader :ff="num"></Vheader>
                    <xxx></xxx>

                </div>

                `,
        components: {
            Vheader,
            xxx,
        }
    }


    let vm  = new Vue({
        el:'#app',

        components:{
            App,
        }


    })



</script>
</html>

注意点:

使用父组件传递数据给子组件时, 注意一下几点:

  1. 传递数据是变量,则需要在属性左边添加冒号.

    传递数据是变量,这种数据称之为"动态数据传递"

    传递数据不是变量,这种数据称之为"静态数据传递"

  2. 父组件中修改了数据,在子组件中会被同步修改,但是,子组件中的数据修改了,是不是影响到父组件中的数据.

    这种情况,在开发时,也被称为"单向数据流"

示例代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>todolist</title>

</head>
<body>
    <div id="app">
        <!-- 3.使用子组件  用子 -->
<!--        <xx></xx>-->
<!--        <xx2></xx2>-->
    <App></App>
<!--    content  header footer aside section nav H5有一些新标签,注意,组件名称尽量不要和标签名称冲突 -->
    </div>
</body>
<script src="vue.js"></script>
<script src="axios.js"></script>
<script>

    // 父组件往子组件传值:



    let Vheader = {
        data(){
            return {
                nav_list:['个人中心','登录','注册','username']
            }
        },
        template:`<div>
                    <h1>{{nav_list}}</h1>
                    <h2>{{nav_list}}</h2>
                    <h4 style="color:green;">{{ff}}</h4>
                    <input type="text" v-model="ff">  #修改input标签的值,不会影响父级标签的数据

                </div>`,

        props:['ff', ],

    };


    let xxx = {
        data(){
            return {
                content_list:['xxx','ooo',]
            }
        },
        template:'<h1 style="color:red;">{{content_list}}</h1>',


    };

    let App = {
        data(){
            return {
                'xxx':'ooo',
                num:1001,
            }
        },
        // <Vheader ff="123"></Vheader> 静态传值
        template:
                `
                <div class="app">
                    <Vheader :ff="num"></Vheader>
                    <xxx></xxx>
                    <h3 style="color:blue;">{{num}}</h3>

                </div>

                `,
        components: {
            Vheader,
            xxx,
        }
    }


    let vm  = new Vue({
        el:'#app',

        components:{
            App,
        }


    })



</script>
</html>

子组件父组件传值

两步:

  a.子组件中使用this.$emit('fatherHandler',val);fatherHandler是父组件中使用子组件的地方添加的绑定自定义事件,注意,如果fatherHandler报错了,那么可能是你的vue版本不支持自定义键名称fatherHandler中有大写字母,所以我们改成father-handler或者直接就全部小写就可以了

<Vheader @fatherHandler="appFatherHandler"></Vheader> 

  b.父组件中的methods中写一个自定义的事件函数:appFatherHandler(val){},在函数里面使用这个val,这个val就是上面子组件传过来的数据

示例代码:

<!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>

平行组件传值

什么是平行组件?

img

声明两个全局组件T1和T2,T1组件将数据传送给T2组件

<!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>

 

posted @ 2021-04-13 10:00  urls  阅读(278)  评论(0编辑  收藏  举报