1

Vue简明实用教程(14)——Vue的组件

 2 years ago
source link: https://blog.csdn.net/lfdfhl/article/details/122048980
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Vue简明实用教程(14)——Vue的组件

专栏收录该内容
14 篇文章 11 订阅

  • 本文原创作者:谷哥的小弟
  • 作者博客地址:http://blog.csdn.net/lfdfhl

VUE推荐前端采用 SPA 方式进行开发。在SPA(single page application)方式中,一个应用程序只有一个HTML页面。所以,也倡导一个页面中只有一个Vue的实例。

为了实现代码重用提升开发效率,可以根据业务功能将页面划分为不同的组件(component)以便于日后维护与修改。组件是可复用的实例,与Vue实例类似,它拥有自身的data、computed、methods 、生命周期函数。

Vue的组件可以为两大类:

  • 1、全局组件
  • 2、局部组件

全局注册的组件可以用在其被注册之后的任何 通过 new Vue 新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。简单地说:全局组件注册给Vue实例后可在任意Vue实例的范围内使用该组件。

全局组件语法

Vue.component('my-component-name', {
  // ... options ...
})

全局组件要点

  • 1、全局组件的名称请勿使用Java风格的驼峰命名法,名称中最好勿含大写字母
  • 2、全局组件的Html代码必须有且只有一个root元素(例如:div)
  • 3、全局组件的data必须是一个函数
  • 4、在Vue的作用范围内根据组件名使用全局组件,其使用方式非常类似于普通标签的使用

全局组件示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue</title>
    <!-- 引入vue -->
    <script src="js/vue.js"></script>
    <script type="text/javascript">
        // 声明Vue的实例
        let vueInstance = null;
        // 入口函数
        window.onload = function () {
            // 定义全局组件1
            Vue.component('com1',{
                template:'<div><h2>Hello Vue</h2></div>'
            });

            // 定义全局组件2
            Vue.component('com2',{
                // 显示数据
                template:'<div><h2>Hello {{site}}</h2></div>',
                data(){
                    return{
                        site:"CSDN"
                    }
                }
            });

            // 定义全局组件3
            Vue.component('com3',{
                // 双向绑定
                template:'<div><h2>Hello {{site}}</h2><input type="text" v-model="site"></div>',
                data(){
                    return{
                        site:"CSDN"
                    }
                }
            });

            // 定义全局组件4
            Vue.component('com4',{
                // 点击事件
                template:'<div><h2>Hello {{counter}}</h2><button @click="add(10)">点击执行counter++</button></div>',
                data(){
                    return{
                        site:"CSDN",
                        counter:0
                    }
                },
                methods:{
                    add(count){
                        this.counter+=count;
                    }
                },
                computed:{

                },
                // 组件生命周期方法
                beforeCreate(){
                    console.log("beforeCreate");
                },
                created(){
                    console.log("created");
                },
                // ...省略组件的其它声明周期方法...
                beforeDestroy(){
                    console.log("beforeDestroy");
                },
                destroyed(){
                    console.log("destroyed");
                },
            });

            // 初始化Vue实例
            vueInstance=new Vue({
                el: "#div1",
                data: {
                    name: "谷哥的小弟"
                },
                methods: {
                },
                computed:{
                }
            });
        }
    </script>
</head>
<body>
    <h2 style="color: red;">本文作者:谷哥的小弟</h2>
    <h2 style="color: red;">博客地址:http://blog.csdn.net/lfdfhl</h2>
    <div id="div1">
        <h3>{{name}}</h3>
        <hr/>
        <!-- 使用全局组件 -->
        <com1></com1>
        <hr/>
        <com2></com2>
        <hr/>
        <com3></com3>
        <hr/>
        <com4></com4>
    </div>

</body>
</html>

在这里插入图片描述

局部组件指的是未在全局组件中注册的组件,因此只能使用于局部。从使用语法和用途上来讲局部组件与全局组件并无明显区别,大致一致。

局部组件语法

new Vue({
    el: ,
    data: {
        
    },
    methods: {

    },
    computed: {

    },
    // 局部组件
    components: {
    }
})

局部组件示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue</title>
    <!-- 引入vue -->
    <script src="js/vue.js"></script>
    <script type="text/javascript">
        // 局部组件
        let com1={
            // 显示数据
            template:'<div><h2>Hello {{site}}</h2></div>',
            data(){
                return{
                    site:"CSDN"
                }
            }
        }

        // 声明Vue的实例
        let vueInstance = null;
        // 入口函数
        window.onload = function () {

            // 初始化Vue实例
            vueInstance = new Vue({
                el: "#div1",
                data: {
                    name: "谷哥的小弟"
                },
                methods: {

                },
                computed: {

                },
                components: {
                    // 局部组件1
                    com1:com1,
                    // 局部组件2
                    com2: {
                        template: '<div><h2>Hello {{counter}}</h2><button @click="add(10)">点击执行counter++</button></div>',
                        data() {
                            return {
                                site: "CSDN",
                                counter: 0
                            }
                        },
                        methods: {
                            add(count) {
                                this.counter += count;
                            }
                        }
                    }
                }
            });
        }
    </script>
</head>
<body>
<h2 style="color: red;">本文作者:谷哥的小弟</h2>
<h2 style="color: red;">博客地址:http://blog.csdn.net/lfdfhl</h2>
<div id="div1">
    <h3>{{name}}</h3>
    <hr/>
    <!-- 使用局部组件 -->
    <com1></com1>
    <com2></com2>
</div>

</body>
</html>

在这里插入图片描述

父组件向子组件传递数据

在Vue框架中,父组件可通过prop向子组件传递数据。所有的prop都使得其父子prop之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。

父组件向子组件传递的数据可分为两类:

  • 1、静态数据
  • 2、动态数据

父组件向子组件传递静态数据

父组件在标签上使用key=value的方式声明静态数据,子组件内部使用props数组接收所有key并在子组件中使用静态数据。

父组件向子组件传递动态数据

父组件在标签上使用v-bind:key=value的方式绑定动态数据(例如:Vue实例中data里的数据),子组件内部使用props数组接收所有key并在子组件中使用动态数据。故,子组件的数据可随着父组件中数据的变化而变化。

父组件向子组件传递数据示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue</title>
    <!-- 引入vue -->
    <script src="js/vue.js"></script>
    <script type="text/javascript">
        // 局部组件1
        let com1={
            // 显示数据以及从父组件传递而来的静态数据
            template:'<div><h2>Hello {{site}} {{nickname}} {{number}}</h2></div>',
            data(){
                return{
                    site:"CSDN"
                }
            },
            // 接收从父组件传递而来的静态数据
            props:['nickname','number']
        };

        // 局部组件2
        let com2={
            // 显示数据以及从父组件传递而来的动态数据
            template:'<div><h2>Hello {{site}} {{myname}} {{myage}}</h2></div>',
            data(){
                return{
                    site:"CSDN"
                }
            },
            // 接收从父组件传递而来的动态数据
            props:['myname','myage']
        }

        // 声明Vue的实例
        let vueInstance = null;
        // 入口函数
        window.onload = function () {

            // 初始化Vue实例
            vueInstance = new Vue({
                el: "#div1",
                data: {
                    name: "谷哥的小弟",
                    age:18
                },
                methods: {

                },
                computed: {

                },
                components: {
                    // 局部组件1
                    com1:com1,
                    // 局部组件2
                    com2:com2,
                }
            });
        }
    </script>
</head>
<body>
<h2 style="color: red;">本文作者:谷哥的小弟</h2>
<h2 style="color: red;">博客地址:http://blog.csdn.net/lfdfhl</h2>
<div id="div1">
    <hr/>
    <!-- 父组件向子组件传递静态数据 -->
    <com1 nickname="zxx" number=9527></com1>
    <hr/>

    <!-- 父组件向子组件传递动态数据 -->
    <h3>{{name}}</h3>
    <input type="text" v-model="name">
    <br/>
    <h3>{{age}}</h3>
    <input type="text" v-model="age">
    <br/>
    <!-- 向组件传递两个数据:myname和myage其值为Vue实例中data里的数据-->
    <com2 v-bind:myname="name" v-bind:myage="age"></com2>
</div>

</body>
</html>

在这里插入图片描述

父组件向子组件传递事件

父组件除了可以向子组件传递数据以外还可以向子组件传递事件。也就是说:在父组件中定义事件(函数),当事件(函数)被传递至子组件时子组件可执行该事件(函数)。

而且,通过事件的传递可以变相的实现子组件向父组件传递数据。

父组件向子组件传递事件语法如下:

<组件标签 @被传递的事件="父组件中事件名"></组件标签>

子组件执行父组件的事件语法如下:

 this.$emit("被传递的事件",[参数]);

示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue</title>
    <!-- 引入vue -->
    <script src="js/vue.js"></script>
    <script type="text/javascript">
        // 局部组件1
        let com1={
            // 显示数据以及从父组件传递而来的动态数据
            // 处理点击事件
            template:'<div><h2>Hello {{site}} {{myname}} {{myage}}</h2><button @click="childf1">Click Here</button></div>',
            data(){
                return{
                    site:"CSDN"
                }
            },
            // 接收从父组件传递而来的动态数据
            props:['myname','myage'],
            methods:{
                childf1(){
                    alert("This is childf1");
                }
            }
        };

        // 局部组件2
        let com2={
            // 显示数据以及从父组件传递而来的动态数据
            // 处理点击事件
            template:'<div><h2>Hello {{site}} {{myname}} {{myage}}</h2><button @click="childf2">Click Here</button></div>',
            data(){
                return{
                    site:"CSDN"
                }
            },
            // 接收从父组件传递而来的动态数据
            props:['myname','myage'],
            methods:{
                childf2(){
                    alert("This is childf2");
                    // 执行父组件传递而来的事件
                    this.$emit("myparentevent");
                }
            }
        };

        // 局部组件3
        let com3={
            // 显示数据以及从父组件传递而来的动态数据
            // 处理点击事件
            template:'<div><h2>Hello {{site}} {{myname}} {{myage}}</h2><button @click="childf3">Click Here</button></div>',
            data(){
                return{
                    site:"CSDN"
                }
            },
            // 接收从父组件传递而来的动态数据
            props:['myname','myage'],
            methods:{
                childf3(){
                    alert("This is childf3");
                    // 执行父组件传递而来的事件并传参
                    this.$emit("myparentevent",27);
                }
            }
        };

        // 局部组件4
        let com4={
            // 显示数据以及从父组件传递而来的动态数据
            // 处理点击事件
            template:'<div><h2>Hello {{site}} {{myname}} {{myage}}</h2><button @click="childf4">Click Here</button></div>',
            data(){
                return{
                    site:"CSDN"
                }
            },
            // 接收从父组件传递而来的动态数据
            props:['myname','myage'],
            methods:{
                childf4(){
                    alert("This is childf4");
                    // 执行父组件传递而来的事件并传参
                    let obj={"country":"China","city":"HK"};
                    this.$emit("myparentevent",obj);
                }
            }
        };

        // 声明Vue的实例
        let vueInstance = null;
        // 入口函数
        window.onload = function () {

            // 初始化Vue实例
            vueInstance = new Vue({
                el: "#div1",
                data: {
                    name: "谷哥的小弟",
                    age:18
                },
                methods: {
                    parentf1(){
                        alert("This is parentf1");
                    },
                    parentf2(){
                        alert("This is parentf2");
                    },
                    parentf3(age){
                        alert("This is parentf3");
                        // 接收子组件传递而来的数据并修改父组件中data里的数据
                        this.age=age;
                    },
                    parentf4(obj){
                        alert("This is parentf4");
                        // 接收子组件传递而来的对象
                        alert(obj.country+" "+obj.city);
                    }
                },
                computed: {

                },
                components: {
                    // 局部组件1
                    com1:com1,
                    // 局部组件2
                    com2:com2,
                    // 局部组件3
                    com3:com3,
                    // 局部组件4
                    com4:com4,
                }
            });
        }
    </script>
</head>
<body>
<h2 style="color: red;">本文作者:谷哥的小弟</h2>
<h2 style="color: red;">博客地址:http://blog.csdn.net/lfdfhl</h2>
<div id="div1">
    <hr/>
    <!-- 父组件向子组件传递动态数据 -->
    <h3>{{name}}</h3>
    <input type="text" v-model="name">
    <br/>
    <h3>{{age}}</h3>
    <input type="text" v-model="age">
    <br/>
    <!-- 向组件传递两个数据:myname和myage其值为Vue实例中data里的数据-->
    <com1 v-bind:myname="name" v-bind:myage="age"></com1>

    <hr/>
    <!-- 父组件向子组件传递动态数据和事件 -->
    <h3>{{name}}</h3>
    <input type="text" v-model="name">
    <br/>
    <h3>{{age}}</h3>
    <input type="text" v-model="age">
    <br/>
    <!-- 向组件传递两个数据:myname和myage其值为Vue实例中data里的数据-->
    <!-- 向组件传递事件 -->
    <com2 v-bind:myname="name" v-bind:myage="age" @myparentevent="parentf2"></com2>


    <hr/>
    <!-- 父组件向子组件传递动态数据和事件 -->
    <h3>{{name}}</h3>
    <input type="text" v-model="name">
    <br/>
    <h3>{{age}}</h3>
    <input type="text" v-model="age">
    <br/>
    <!-- 向组件传递两个数据:myname和myage其值为Vue实例中data里的数据-->
    <!-- 向组件传递事件 -->
    <com3 v-bind:myname="name" v-bind:myage="age" @myparentevent="parentf3"></com3>

    <hr/>
    <!-- 父组件向子组件传递动态数据和事件 -->
    <h3>{{name}}</h3>
    <input type="text" v-model="name">
    <br/>
    <h3>{{age}}</h3>
    <input type="text" v-model="age">
    <br/>
    <!-- 向组件传递两个数据:myname和myage其值为Vue实例中data里的数据-->
    <!-- 向组件传递事件 -->
    <com4 v-bind:myname="name" v-bind:myage="age" @myparentevent="parentf4"></com4>
</div>

</body>
</html>

在这里插入图片描述

在组件开发中,我们还可以使用插槽slot在template中预先占位;再在使用组件时替换占位即可。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue</title>
    <!-- 引入vue -->
    <script src="js/vue.js"></script>
    <script type="text/javascript">
        // 局部组件
        let com1={
            // 在template中设置两个插槽s1和s2
            template:'<div><slot name="s1"></slot><h2>Hello {{site}}</h2><slot name="s2"></slot></div>',
            data(){
                return{
                    site:"CSDN"
                }
            }
        }

        // 声明Vue的实例
        let vueInstance = null;
        // 入口函数
        window.onload = function () {

            // 初始化Vue实例
            vueInstance = new Vue({
                el: "#div1",
                data: {
                    name: "谷哥的小弟"
                },
                methods: {

                },
                computed: {

                },
                components: {
                    // 局部组件1
                    com1:com1
                }
            });
        }
    </script>
</head>
<body>
<h2 style="color: red;">本文作者:谷哥的小弟</h2>
<h2 style="color: red;">博客地址:http://blog.csdn.net/lfdfhl</h2>
<div id="div1">
    <h3>{{name}}</h3>
    <hr/>
    <!-- 不使用插槽 -->
    <com1></com1>
    <hr/>
    
    <!-- 在局部组件中使用插槽 -->

    <!-- 向插槽s1插入内容 -->
    <com1><span slot="s1">Welcome</span></com1>
    <hr/>
    <!-- 向插槽s2插入内容 -->
    <com1><span slot="s2">Welcome</span></com1>
    <hr/>
    <!-- 向插槽s1和s2插入内容 -->
    <com1><span slot="s1">Hello</span><span slot="s2">Welcome</span></com1>
</div>

</body>
</html>

在这里插入图片描述


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK