美文网首页
Vue.js组件

Vue.js组件

作者: 奶瓶SAMA | 来源:发表于2018-05-13 20:54 被阅读0次

组件: 顾名思义, 也就是组成的部件, 即整体的组成部分
这个组成部分是可以缺少的,但是其存在的意义是无可替代的
这个组成部分也是可以复用的
全局方法一:
大致可以分成三步
1.在我们引入vue.js之后,Vue会被注册为一个全局对象,我们使用对象本身的方法进行组件的创建
------使用Vue这个全局对象的component方法进行全局注册一个组件

2.创建根实例,进行视图的绑定

3.组件的显示

-----将组价的名称作为标签写在视图内部,就能够完成组件的显示

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <!--引入js-->
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>

    <body>
        <div id="app">
            <!--3. 定义的组件名作为标签存在,将组件显示在页面上-->
            <my-component></my-component>

        </div>
    </body>

</html>
<script>

    //1. 使用vue这个全局队形内置的components方法进行组件的创建
    //在components这个方法中有两个重要的参数,第一个参数是组件的名称,第二个参数是组件的内容
    Vue.component('my-component', {
        //在这里使用一个父标签将组件包裹起来
        template: '<div><a href="#">注册</a><a href="#">登录</a></div>'
    })

    //2. 创建根实例,也就是实例化一个vue对象,进行视图的绑定
    var vm = new Vue({
        el: '#app'
    })
</script>

全局方法二
使用全局的Vue.extend()构造器进行注册
Vue.extend()类似于继承,通过这个构造器扩展(继承)之后,相当于Vue对象本身添加了一些这个对象原先没有的东西

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>Vue入门之extend全局方法</title>
        <script src="https://unpkg.com/vue/dist/vue.js"></script>

        <style type="text/css">

        </style>
    </head>

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

</html>
<script>
    //通过构造器创建一个组件,相当于在vue这个全局对象本身上添加了一些新的内容,作用相当于构造函数
    //----继承自vue,但是比vue本身更强大
    var myVue = Vue.extend({
        template: '<div>这是通过构造器创建出来的组件</div>'
    });
    var app = new myVue({
        el: '#app'
    });
</script>

局部方法一
大致分成两个部分
1.穿件跟实例
2.在跟实例内部定义组件

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <!--引入js-->
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>

    <body>
        <div id="app">
            <!--3. 这是我定义的组件    占位标签-->
            <my-component></my-component>

        </div>
    </body>

</html>
<script>
    //1. 创建根实例
    var vm = new Vue({
        el: '#app',
        //2. 在根实例内部创建组件
        components:{
           'my-component':{
               template: '<div><a href="#">注册</a><a href="#">登录</a></div>'
           }
        }
    })
</script>

组件注册的其它方式1

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <!--引入js-->
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>

    <body>
        <div id="app">
            <!--这是我定义的组件-->
            <my-component></my-component>

        </div>

        <template id="my-template">
            <div>
                <a href="#">注册</a>
                <a href="#">登录</a>
            </div>
        </template>
    </body>

</html>
<!--

    注意组件的模板替换了自定义元素,自定义元素的作用只是作为一个挂载点。

    ----这可以用实例选项 replace 改变。


-->
<script>
    //1. --定义  +  注册 组件构造器
    Vue.component('my-component', {
        //将template的内容提取到一个标签中,通过id来获取
        template: '#my-template'
    })

    //2. 创建根实例
    var vm = new Vue({
        el: '#app'
    })
</script>

组件注册的其它方式2

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <!--引入js-->
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>

    <body>
        <div id="app">
            <!--这是我定义的组件-->
            <template>
                <div>
                    <a href="#">注册</a>
                    <a href="#">登录</a>
                </div>
            </template>

        </div>

    </body>

</html>
<!--

自定义的标签只是自定义组件的一个挂载点,自定义组件会将其替换掉

----直接使用自定义的组件将自定义的标签替换

-->
<script>
    //2. 创建根实例
    var vm = new Vue({
        el: '#app'
    })
</script>

组件内部的data
组件内部的data属性必须是一个函数
以全局注册的组件为例

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <!--引入js-->
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>

    <body>
        <div id="app">
            <!--全局的组件-->
            <ab></ab>
            <!--局部的组件-->
            <my-component></my-component>
        </div>
    </body>

</html>
<script>
    //自定义指令
    //Vue.directive('指令名',{})


    //定义组件    参数1:组件的名称    参数2: 对象
    Vue.component("ab",{
        template:
            `<ul>
                <li>{{name}}</li>
                <li>{{age}}</li>
                <li>{{sex}}</li>
            </ul>`,
        //data属性的属性值是一个函数----函数内部返回一个对象
        data:function(){
            return {
                name:"首页",
                age:"联系我们",
                sex:"新闻"
            }
        }

    })

    //2. 创建根实例-----并在根实例下面创建一个局部的组件
    var vm = new Vue({
        el: '#app',
        //局部组件
         components:{
           'my-component':{
               template: `<ul>
                <li>{{name}}</li>
                <li>{{age}}</li>
                <li>{{sex}}</li>
            </ul>`,
            data:function(){
                return {
                    name:1,
                    age:2,
                    sex:3
                }
            }
           }
        }
    })

</script>

父子组件通信
父组件将数据传递给自组件使用prop 子组件将其内部发生的事情通告给父组件使用emit
复杂的父子组件的props

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <!--引入js-->
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
        <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    </head>

    <body>
        <div id="app">
            <parent></parent>
        </div>
        <template id="parent">
            <div>
                <div>我是父组件</div>
                <child :message="message"></child>
            </div>
        </template>
        <template id="child">
            <div>
                <div>我是子组件</div>
                <span>{{message}}</span>
            </div>
        </template>
    </body>
</html>
<script>
    var vm = new Vue({
        el: '#app',
        //我是父组件
        components:{'parent':{
            template:"#parent",
            data:function(){
                return {
                    message:"hello world"
                }
            },
            //我是子组件
            components:{'child':{
                props:['message'],
                template:"#child"
            }}
        }}
    })
</script>

字面量语法 vs 动态语法
使用字面量语法传递数字,有时候会出现问题
单向数据流
数据从父组件传递到子组件,但是不会反过来传递
数据传递-注意事项
在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,
如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。
自定义事件

每个 Vue 实例都实现了事件接口(Events interface),即:

    使用 $on(eventName) 监听事件

    使用 $emit(eventName) 触发事件

类似于我们注册(vue中是$on)点击事件,通过鼠标点击触发(vue中是emit)
    document.onclick = function(event){
        console.log(111)
    }
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
        <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
        <style>
            #dv1,
            #dv2 {
                width: 500px;
                height: 100px;
            }

            #dv1 {
                border: 1px solid red;
                margin: 50px auto;
            }

            #dv2 {
                border: 1px solid green;
                margin: 50px auto;
            }
        </style>
    </head>

    <body>

        <div id="app2">
            <component2></component2>
        </div>

        <div id="app1">
            <component1></component1>
        </div>
    </body>

</html>
<script type="text/javascript">
    //1. 创建一个空的公共的vue对象
    var bus = new Vue();

    //2. 在vm1实例中创建组件1,定义$emit来发送数据
    var vm1 = new Vue({
        el: '#app1',
        components: {
            component1: {
                template: `<div id="dv1"  v-on:click="add">
                                <div>点击我,触发自定义事件,进行数据的传递</div>
                                <div>当前的数据是:{{num}}</div>
                            </div>`,
                data: function() {
                    return {
                        num: 0
                    }
                },
                methods: {
                    add: function() {
                        this.num++;
                        bus.$emit('test', this.num)
                    }
                }
            }
        }
    })

    //在vm2实例中创建组件2,定义$on来接收传递的数据
    var vm2 = new Vue({
        el: '#app2',
        components: {
            component2: {
                template: `<div id="dv2" v-on:click="result">
                                <div>点击我,进行自定义事件的注册</div>
                                <div>传递过来的数据是{{getData}}</div>
                            </div>`,
                data: function() {
                    return {
                        getData: 0
                    }
                },
                methods: {
                    result: function() {
                        //this问题
                        var vm2This = this;
                        bus.$on('test', function(num) {
                            vm2This.getData = num;
                            //事件的解绑问题
                            bus.$off("test")
                        })

                    }
                }
            }
        }
    })
</script>

slot
有时候,我们需要对组件进行局部的修改,
vue提供了一种方式来混合父组件的内容与子组件自己的模板
这个过程被称为 内容分发 也就是slot

<!DOCTYPE html>
    <html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>Vue入门之extend全局方法</title>
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>

    <body>
        <div id="app">
            <!--父容器输入标签,会将slot标签替换掉-->
            <my-slot>
                <h3>这里是父容器写入的</h3>
            </my-slot>

            <!--父容器绑定数据到子容器的slot,会将slot中的数据替换掉-->
            <my-slot>{{ email }}</my-slot>

            <!--父容器什么都不传内容-->
            <my-slot></my-slot>
        </div>
    </body>

    </html>

    <script>
        // 反引号:可以定义多行字符串。
        var temp = `
      <div>
        <h1>这里是子组件</h1>
        <hr>
        <slot>slot标签会被父容器写的额外的内容替换掉,如果父容器没有写入任何东西,此标签将保留!</slot>
      </div>
    `;
        Vue.component('MySlot', { // 如果定义的组件为MySlot,那么用组件的时候:<my-slot></my-slot>
            template: temp,
        });
        // 初始化一个Vue实例
        var app = new Vue({
            el: '#app',
            data: {
                email: 'flydragon@gmail.com'
            }
        });
    </script>

具名slot
元素可以用一个特殊的属性 name 来配置如何分发内容。多个 slot 可以有不同的名字。
具名 slot 将匹配内容片段中有对应 slot 特性的元素
仍然可以有一个匿名 slot ,它是默认 slot ,作为找不到匹配的内容片段的备用插槽。如果没有默认的 slot ,这些找不到匹配的内容片段将被抛弃

动态组件
通过使用保留的 元素,动态地绑定到它的 is 特性,我们让多个组件可以使用同一个挂载点,并动态切换
如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <!--引入js-->
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
        <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    </head>

    <body>
        <h3>动态组件</h3>
        <!-- 定义三个temp模板,用于切换 -->
        <template id="temp-tab01">
            <div>this is tab01</div>
        </template>
        <template id="temp-tab02">
            <div>this is tab02</div>
        </template>
        <template id="temp-tab03">
            <div>this is tab03</div>
        </template>

        <div id="dr01">
            <!-- 导航栏 -->
            <div class="border cf">
                <ul>
                    <li>
                        <a href="javascript:void(0);" @click="toggleTabs(tab01Text);">{{tab01Text}}</a>
                    </li>
                    <li>
                        <a href="javascript:void(0);" @click="toggleTabs(tab02Text);">{{tab02Text}}</a>
                    </li>
                    <li>
                        <a href="javascript:void(0);" @click="toggleTabs(tab03Text);">{{tab03Text}}</a>
                    </li>
                </ul>
            </div>
            <!-- 点击导航后要切换的内容 -->
            <div class="border" style="height: 100px;">
                <!-- 如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数 -->
                <component :is="currentView" keep-alive></component>
            </div>
        </div>
    </body>

</html>
<script>
//通过使用保留的 <component> 元素,动态地绑定到它的is属性,我们让多个组件可以使用同一个挂载点,并动态切换:
    //扩展组件tab01
    var tab01 = Vue.extend({
        template: "#temp-tab01",
    });
    //扩展组件tab02
    var tab02 = Vue.extend({
        template: "#temp-tab02",
    });
    //扩展组件tab03
    var tab03 = Vue.extend({
        template: "#temp-tab03",
    });
    //新建vue实例
    var dr01 = new Vue({
        el: "#dr01",
        data: {
            tab01Text: "tab01", //导航栏文本1
            tab02Text: "tab02", //导航栏文本2
            tab03Text: "tab03", //导航栏文本3
            currentView: 'tab01', //默认选中的导航栏
        },
        //局部注册组件
        components: {
            tab01: tab01,
            tab02: tab02,
            tab03: tab03,
        },
        methods: {
            //绑定tab的切换事件
            toggleTabs: function(tabText) {
                this.currentView = tabText;
            }
        }
    });
</script>

相关文章

网友评论

      本文标题:Vue.js组件

      本文链接:https://www.haomeiwen.com/subject/nkqrdftx.html