VUE构建组件(转载)

一、vue组件的概念

官方定义:组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。

博主理解:Vue里面的组件可以理解为通过对普通html标签的封装,得到一套独立而且可以通用的html标签,我们在页面里面使用这些标签传入相应的参数即可调用封装好的组件。通过下面这张图相信可以一目了然。

由普通的html标签form、input、button、label组成了一个新的元素集合,我们命名为i-form,这个i-form就是vue里面组件的概念。我们在页面里面使用<i-form></i-form>时,通过vue的组件渲染机制,在浏览器里面最终就可以显示成为普通的html标签form、input、button、label。

二、组件原理

通过上图我们知道,vue里面的组件实际上就是一些普通html元素的集合。那么,它是如何将这些自定义标签转换为普通html标签的呢?在介绍组件原理之前,还是先来看一个最简单的组件实例。

    <div style="text-align:center;margin-top:200px;" id="app">
        <!-- 3. 在Vue实例里面使用组件-->
        <b-component></b-component>
    </div>

    <script src="Content/vue/dist/vue.js"></script>
    <script type="text/javascript">
        // 1.创建组件构造器
        var myComponent = Vue.extend({
            template: '<div id="bComponent">我是自定义组件的内容</div>'
        });

        //2.注册组件到vue里面
        Vue.component('b-component', myComponent)

        new Vue({
            el: '#app',
        });
        
    </script>

整个过程不难理解,主要分为三个大的步骤:

  1. 定义一个组件构造器,声明组件要渲染的html内容
  2. 将组件构造器注册到Vue的组件系统里面,使其成为Vue的一个组件,给组件取一个名称,比如b-component
  3. 在Vue的实例里面使用组件。因为上面两步定义了Vue的组件,既然是Vue的组件,那么要使用组件,首先得有一个Vue的实例,组件必须要在Vue的实例里面使用。

整个过程:

其实有时为了简便,我们常将1、2步合并,代码如下:

    <div style="text-align:center;margin-top:200px;" id="app">
        <!-- 2. 在Vue实例里面使用组件-->
        <b-component></b-component>
    </div>

    <script src="Content/vue/dist/vue.js"></script>
    <script type="text/javascript">
        //1.创建组件构造器,注册组件到vue里面
        Vue.component('b-component', {
            template: '<div id="bComponent">我是自定义组件的内容</div>'
        })

        new Vue({
            el: '#app',
        });
        
    </script>

三、组件的使用

上述解释了下组件的定义和原理,关于组件的简单实用,我们主要介绍以下几个方面。

(1)组件的作用域

这个应该不难理解,组件分为全局组件和局部组件,也就是说,你可以在页面上面定义一个全局组件,页面上面的任何Vue实例都可使用;而对于局部组件,是和具体的Vue实例相关的,只能在当前Vue实例里面使用组件。还有一点需要说明:组件必须在Vue的实例里面使用,在Vue实例之外使用组件无效。通过下面一个例子即可清晰说明它们的区别。

<body>
    <div style="text-align:center;margin-top:50px;" id="app">
        <b-component></b-component>
        <b-component2></b-component2>
    </div>
    <div style="text-align:center;margin-top:50px;" id="app2">
        <b-component></b-component>
        <b-component2></b-component2>
    </div>

    <b-component></b-component>
    <b-component2></b-component2>
   
    <script src="Content/vue/dist/vue.js"></script>
    <script type="text/javascript">

        //定义组件
        Vue.component('b-component', {
            template: '<div id="bComponent">我是全局组件,任何Vue实例都可使用</div>'
        })

        new Vue({
            el: '#app',
            components: {
                'b-component2': {
                    template: '<div id="bComponent">我是局部组件,只能在app这个div里面使用</div>'
                }
            }
        });
        new Vue({
            el: '#app2',
        });
        
    </script>
</body>

(2)组件的传值

组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 props 把数据传给子组件。这段话怎么理解呢?我们先来看几个例子。

  • 静态Prop

我们先来看看下面的一段简单的代码

<body>
    <div style="text-align:center;margin-top:50px;" id="app">
        <b-component componentmessage="你好"></b-component>
    </div>
   
    <script src="Content/vue/dist/vue.js"></script>
    <script type="text/javascript">
        Vue.component('b-component', {
            template: '<div>{{componentmessage}}</div>',
            props: ['componentmessage'],
        })

        new Vue({
            el: '#app'
        });
    </script>
</body>

通过在组件里面使用props属性,将外部的值传入组件模板。最终渲染到页面上面就得到“<div>你好</div>”这么一段html

  • 动态Prop

在多数情况下,我们在使用Vue实例的时候,一般通过data属性传入模型,这个时候,我们的name和age如何传到组件实例里面呢?如下:

<body>
    <div style="text-align:center;margin-top:50px;" id="app">
        <b-component v-bind:my-name="name" v-bind:my-age="Age"></b-component>
    </div>
    <script src="Content/vue/dist/vue.js"></script>
    <script type="text/javascript">
        Vue.component('b-component', {
            template: '<div>姓名:{{myName}},年龄:{{myAge}}</div>',
            props: ['myName', 'myAge'],
        })

        new Vue({
            el: '#app',
            data: {
                name: 'Jim',
                Age: '28'
            }
        });
    </script>
</body>

需要说明几点:

  • 在使用标签<b-component>的时候,通过v-bind命令,将Vue实例里面的name、Age属性以别名my-name、my-age的形式传入组件实例。
  • 为什么my-name、my-age传到组件里面就变成了['myName', 'myAge']呢?这是因为在子组件中定义prop时,使用了camelCase命名法。由于HTML特性不区分大小写,camelCase的prop用于特性时,需要转为 kebab-case(短横线隔开)。
  • 很多情况下,v-bind可以简写为冒号(:),所以上述代码也可以这么写: <b-component :my-name="name" :my-age="Age"></b-component> 。效果也是一样。
  • 这里很恶心的还有一点,在Props里面定义的必须要使用所谓“驼峰式”的方式来定义变量,否则会因为一个变量名大小写搞死你。比如props:["myName"]这样可以正确,但是如果props:["myname"]这样的话就错误,使用myname取值会是undefined。博主第一次玩这个玩意找了好半天,新手一定注意,大坑,大坑,大坑!慎入!

在封装组件里面,props属性使用非常多,更多props用法可参见文档https://vuefe.cn/v2/guide/components.html#Prop

(3)组件的插槽

在使用组件的时候,我们经常需要在组件实例向组件模板传入html元素,这个时候我们就需要在组件的模板标签里面留一些占位符(俗称“坑”),然后在具体的组件实例里面传入标签来填“坑”,在Vue里面这些“坑”也叫插槽,使用<slot>来解决。对于开发人员来说,这个其实不陌生,从原来的母版页到现在的layout页面,基本都是使用的这种原理。

<body>
    <div style="text-align:center;margin-top:50px;" id="app">
        <b-component>
            <h1 slot="header">这里可能是一个页面标题</h1>
            <h2 slot="content">姓名:{{name}},年龄:{{Age}}</h2>
            <h1 slot="footer">尾部</h1>
        </b-component>
    </div>
    <template id="slottest">
        <div class="container">
            <header>
                <slot name="header"></slot>
            </header>
            <main>
                <slot name="content"></slot>
            </main>
            <footer>
                <slot name="footer"></slot>
            </footer>
        </div>
    </template>
   
    <script src="Content/vue/dist/vue.js"></script>
    <script type="text/javascript">

        Vue.component('b-component', {
            template: '#slottest',
        })

        new Vue({
            el: '#app',
            data: {
                name: 'Jim',
                Age: '28'
            }
        });
    </script>
</body>

上述代码应该不难理解,就是一个“挖坑”和“填坑”的过程。顺便要提一笔的是,Vue的组件支持使用<templete>的模式来定义标签模板,使用更加灵活和方便。

猜你喜欢

转载自blog.csdn.net/u010295735/article/details/81541207