zoukankan      html  css  js  c++  java
  • vue.js之组件

    代码复用一直是软件开发中长期存在的问题,每个开发者都想要再次使用之前写好的代码,又担心引入这段代码后对现有的程序产生影响。现在web Components的出现提供了一种新的思路,可以自定义tag标签,并拥有自身的模板,样式和交互。Vue.js提供了自己的组件系统,支持自定义tag元素和原生HTML元素的扩展

    一、基本步骤

      1、vue的组件使用有三个步骤:创建组件构造器、注册组件和使用组件

    • 调用Vue.extend({...})创建组件构造器
    • 用Vue.component()方法注册组件
    • 在Vue实例的作用范围内使用组件

    下面的代码演示了这三个步骤

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue组件</title>
      <script src="bower_components/vue/dist/vue.js"></script>
    </head>
    <body>
    <div id="box">
        <!--#box是vue实例挂载的元素,应该在挂载元素范围内使用组件-->
        <aaa></aaa>
    </div>
    <script>
        <!--定义一个组件-->
        // 全局组件
        //1.创建一个组件构造器
        var Aaa=Vue.extend({
            template:'<h3> 我是标题3</h3>'
        });
        //2.注册组件,并指定组件的标签,组件的HTML标签为<aaa>
        Vue.component('aaa',Aaa);
        var vm=new Vue({
            el:"#box"
        })
    </script>
    </body>
    </html>

     运行结果:

      2、理解组件的创建和注册
    • Vue.extend()是Vue构造器的扩展,调用Vue.extend()创建的是一个组件构造器。

    •  Vue.extend()构造器有一个选项对象,选项对象的template属性用于定义组件要渲染的HTML。 

    • 使用Vue.component()注册组件时,需要提供2个参数,第1个参数时组件的标签,第2个参数是组件构造器。 
    •  组件应该挂载到某个Vue实例下,否则它不会生效。
    <!DOCTYPE html>
    <html>
        <body>
            <div id="app1">
                <my-component></my-component>
            </div>
            
            <div id="app2">
                <my-component></my-component>
            </div>
            
            <!--该组件不会被渲染-->
            <my-component></my-component>
        </body>
        <script src="js/vue.js"></script>
        <script>
            var myComponent = Vue.extend({
                template: '<div>This is a component!</div>'
            });
            
            Vue.component('my-component', myComponent);
            
            var app1 = new Vue({
                el: '#app1'
            });
            
            var app2 = new Vue({
                el: '#app2'
            })
        </script>
    </html>

    注意:虽然上面有三个地方使用了<my-component>标签,但是只有#app1和#app2下的<my-component>标签才起到作用。因为第三个没有被挂载

    二、全局注册与局部注册

    1、全局注册

      全局注册需要确保在根实例初始化之前注册,这样才能使组件在任意实例中被使用,注册方式如下:

    <!DOCTYPE html>
    <html>
        <body>
            <div id="app1">
                <my-component></my-component>
            </div>
      </body>
        <script src="js/vue.js"></script>
        <script>
            var myComponent = Vue.extend({
                template: '<div>This is a component!</div>'
            })
            
            Vue.component('my-component', myComponent)        //这条语句应该写在var app1=new Vue({....})之前,注册成功之后,就可以在模块中以自定义元素<my-cpmponent>的形式使用组件
            
            var app1 = new Vue({
                el: '#app1'
            });</script>
    </html>

    运行结果:  

    This is a component!

    2、局部注册

      组件内使用其他组件,可以用选项对象的components属性实现局部注册。

      

    <!DOCTYPE html>
    <html>
        <body>
            <div id="app">
                <!-- 3. my-component只能在#app下使用-->
                <my-component></my-component>
            </div>
        </body>
        <script src="js/vue.js"></script>
        <script>
            // 1.创建一个组件构造器
            var myComponent = Vue.extend({
                template: '<div>This is my first component!</div>'
            })
            
            new Vue({
                el: '#app',
                components: {
                    // 2. 将myComponent组件注册到Vue实例下
                    'my-component' : myComponent
                }
            });
        </script>
    </html>

     三、父组件与子组件

      在 组件中定义并使用其他组件,这就构成了父子组件的关系 

    <!DOCTYPE html>
    <html>
        <body>
            <div id="app">
                <parent-component>
                </parent-component>
            </div>
        </body>
        <script src="js/vue.js"></script>
        <script>
            
            var Child = Vue.extend({
                template: '<p>This is a child component!</p>'
            })
            
            var Parent = Vue.extend({
                // 在Parent组件内使用<child-component>标签
                template :'<p>This is a Parent component</p><child-component></child-component>',
                components: {
                    // 局部注册Child组件,该组件只能在Parent组件内使用
                    'child-component': Child
                }
            })
            
            // 全局注册Parent组件
            Vue.component('parent-component', Parent)
            
            new Vue({
                el: '#app'
            })
            
        </script>
    </html>

     运行结果:

    理解上面的代码:

    1. var Child = Vue.extend(...)定义一了个Child组件构造器
    2. var Parent = Vue.extend(...)定义一个Parent组件构造器
    3. components: { 'child-component': Child },将Child组件注册到Parent组件,并将Child组件的标签设置为child-component
    4. template :'<p>This is a Parent component</p><child-component></child-component>',在Parent组件内以标签的形式使用Child组件。
    5. Vue.component('parent-component', Parent) 全局注册Parent组件
    6. 在页面中使用<parent-component>标签渲染Parent组件的内容,同时Child组件的内容也被渲染出来

     四、组件注册语法糖

      前面组件注册的方式有点繁琐,Vue.js为了简化这个过程,提供了注册语法糖

      1、使用vue.componet()直接创建和注册组件

    // 全局注册,my-component1是标签名称
    Vue.component('my-component1',{
        template: '<div>This is the first component!</div>'
    })
    
    var vm1 = new Vue({
        el: '#app1'
    })

      Vue.component()的第1个参数是标签名称,第2个参数是一个选项对象,使用选项对象的template属性定义组件模板。
           使用这种方式,Vue在背后会自动地调用Vue.extend()

      2、在选项对象的components属性中实现局部注册:

    var vm2 = new Vue({
        el: '#app2',
        components: {
            // 局部注册,my-component2是标签名称
            'my-component2': {
                template: '<div>This is the second component!</div>'
            },
            // 局部注册,my-component3是标签名称
            'my-component3': {
                template: '<div>This is the third component!</div>'
            }
        }
    })

    五、使用template和javascript标签

      尽管语法糖简化了组件注册,但在template选项中拼接HTML元素比较麻烦,这也导致了HTML和JavaScript的高耦合性。
      庆幸的是,Vue.js提供了两种方式将定义在JavaScript中的HTML模板分离出来。

      1、使用javascript

        

    <!DOCTYPE html>
    <html>
        <body>
            <div id="app">
                <my-component></my-component>
            </div>
            <!--type指定为text/x-template,意在告诉浏览器这不是一段js脚本,浏览器在解析HTML文档时会忽略<script>标签内定义的内容-->
            <script type="text/x-template" id="myComponent">
                <div>This is a component!</div>
            </script>
        </body>
        <script src="js/vue.js"></script>
        <script>
            
            Vue.component('my-component',{
                template: '#myComponent'          //与上面的模版id相对应

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

     template选项现在不再是HTML元素,而是一个id,Vue.js根据这个id查找对应的元素,然后将这个元素内的HTML作为模板进行编译

     运行结果:

     2、使用template标签

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <div id="app">
                <my-component></my-component>
            </div>
            <!--使用template标签不需要使用type属性-->
            <template id="myComponent">
                <div>This is a component!</div>
            </template>
        </body>
        <script src="js/vue.js"></script>
        <script>
            
            Vue.component('my-component',{
                template: '#myComponent'
            })
            
            new Vue({
                el: '#app'
            })
            
        </script>
    </html>

     在理解了组件的创建和注册过程后,我建议使用<script>或<template>标签来定义组件的HTML模板。
    这使得HTML代码和JavaScript代码是分离的,便于阅读和维护。

    六、使用个props

      组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 props 把数据传给子组件。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script src="bower_components/vue/dist/vue.js"></script>
        <style>
        </style>
    </head>
    <body>
    <div id="box">
        <div>{{a}}</div>
        <aaa>
            {{msg}}
        </aaa>
    </div>
    
    <template id="aa">
        <h1>11111</h1>
    <!--将父组件数据通过已定义好的props属性传递给子组件--> <bbb :mmm="msg2" :my-msg="msg"></bbb> </template> <script> var vm=new Vue({ el:'#box', data:{ a:'a' }, components:{ 'aaa':{ data(){ return { msg:111, msg2:'我是父组件的数据' } }, template:'#aa', components:{ 'bbb':{ props:{ 'mmm':String, 'myMsg':Number }, template:'<h3>我是bbb组件->{{mmm}} <br> {{myMsg}}</h3>' } } } } }); </script> </body> </html>

     运行结果:

    注意:在子组件中定义prop时,使用了camelCase命名法。由于HTML特性不区分大小写,camelCase的prop用于特性时,需要转为 kebab-case(短横线隔开)。例如,在prop中定义的myName,在用作特性时需要转换为my-name。

      

  • 相关阅读:
    vue小结
    ES6中的super关键字
    es5和es6
    雅虎工程师提供的CSS初始化示例代码
    移动端rem用法总结
    批量压缩图片
    cordova
    cordova 添加插件时报错相关问题
    JS 数组中对象去重 reduce 用法
    中间件笔录
  • 原文地址:https://www.cnblogs.com/15fj/p/8203326.html
Copyright © 2011-2022 走看看