Vuejs 深入浅出 - 组件

Posted 星火燎原2016

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vuejs 深入浅出 - 组件相关的知识,希望对你有一定的参考价值。

组件的定义

全局组件

全局组件可以在不同的挂载点中进行引用,全局组件的 3 种定义方式:

  1. 使用 Vue.extend 配合 Vue.component

    <body>
        <div id="app">
            <!-- 1.3 使用组件时,直接把组件名称以 HMTL 标签的形式引入即可 -->
           <my-Comp></my-Comp>   <!-- 对应定义方式为:  Vue.component('myComp',comp) -->
           <mycomp></mycomp>     <!-- 对应定义方式为:  Vue.component('mycomp',comp) -->
        </div>
    
        <script>
           //  方式一 : 使用 Vue.extend 和 Vue.component 进行定义,步骤为:
           // 1.1 使用 Vue.extend 创建全局 Vue 组件
           var comp = Vue.extend(
               template: '<h2>这是使用 Vue.extend 来创建的组件</h2>'    // template 属性指定组件的 HMTL 结构
           )
           // 1.2 使用 Vue.component('组件名称',创建出来的组件模板对象)
           // 如果定义组件时,名称是驼峰命名,则在使用时,需要使用 - 短横线分割,如果名称不是驼峰,则不能使用短横线分割 
           // Vue.component('myComp',comp)
           Vue.component('mycomp',comp)
            
           // 创建 Vue 实例
            var app = new Vue(
                el:'#app',
                data:function() 
                    return 
                       from: 'ccc' 
                    
                        
            );
        </script>
    </body>
    
  2. 直接使用 html 字符串定义组件模板对象

    <body>
        <div id="app">
           <my-Comp2></my-Comp2>
        </div>
        <script>
           // 方式二: 直接使用html字符串来定义组件模板对象
           Vue.component('myComp2',
               template: '<h3>这是直接使用 Vue.component 创建的组件</h3>'
           )
    
           // 创建 Vue 实例
            var app = new Vue(
                el:'#app',
                data:function() 
                    return 
                       from: 'ccc' 
                    
                        
            );
        </script>
    </body>
    
  3. 使用 标签定义组件模板结构,有提示和高亮(推荐)

    <body>
        <div id="app">
           <my-Comp3></my-Comp3>
        </div>
    
        <!-- 在 app 结构的外部,使用 template 标签定义组件的 html 模板结构 -->
        <template id="temp">
            <!-- 同样只能有一个根标签 -->
             <div>
                 <h3>这是通过 template 标签定义的组件模板结构,有代码提示和高亮</h3>   
                 <h4>这种方式更好用,推荐使用这种</h4>
            </div>   
        </template>
    
        <script>
            // 方式三;
            Vue.component('myComp3',
                template:'#temp'
            )
    
           // 创建 Vue 实例
            var app = new Vue(
                el:'#app',
                data:function() 
                    return 
                       from: 'ccc' 
                    
                        
            );
        </script>
    </body>
    

注意点: 组件模板 template 只能有一个 根元素标签。

私有组件

实例私有组件,只能该实例使用,不和其他 Vue 实例对象共享.

<body>
    <div id="app">
       <login></login>
    </div>
    <div id="app2">
        <!-- 该实例内引用不到 login 组件--->
    </div>
    <script>
		// 创建 Vue 实例
        var app = new Vue(
            el:'#app',
            data:function() 
                return 
                   from: 'ccc' 
                
            ,
            components:
                login: 
                    template:'<h1>这是实例对象 app 内定义的私有组件,只能在该实例内才能引用</h1>'
                
                    
        );
        var vm2 = new Vue(
            el:'#app2'
        );
    </script>
</body>

组件中的 data

组件可以有自己的 data 数据,但是组件中的 data 和 实例中的 data 有点不一样,实例中的 data 可以为一个对象,但是组件中的 data 必须是一个 方法,并且方法的返回值必须是一个对象。

<body>
    <div id="app">
       <my-Comp3></my-Comp3>
    </div>

    <!-- 在 app 结构的外部,使用 template 标签定义组件的 html 模板结构 -->
    <template id="temp">
        <!-- 同样只能有一个根标签 -->
         <div>
             <h3>这是通过 template 标签定义的组件模板结构,有代码提示和高亮</h3>   
             <h4>这种方式更好用,推荐使用这种</h4>
             <h5>在组件的 template 中引用 组件的 data 中的变量msg ======  msg</h5>
        </div>   
    </template>


    <script>
        // 方式三;
        Vue.component('myComp3',
            template: '#temp',
            data: function() 
               return 
                   msg:"这是组件中 data 定义的数据"
               
           
        )

       // 创建 Vue 实例
        var app = new Vue(
            el:'#app',
            data:function() 
                return 
                   from: 'ccc' 
                
                   
        );
    </script>
</body>

组件切换

Vue 提供了 标签展示对应名称的组件, :is 属性指定要展示的组件的名称。

<body>
    <div id="app">
       <a @click.prevent="compName='login'">登录</a>
       <a @click.prevent="compName='register'">注册</a>
       <!-- :is 属性指定当前要展示的组件的组件名称 ---->
       <component :is="compName"></component>
    </div>
    <script>
        Vue.component('login',
            template: '<h2>登录组件</h2>'
        )

        Vue.component('register',
            template: '<h2>注册组件</h2>'
        )

       // 创建 Vue 实例
        var app = new Vue(
            el:'#app',
            data:function() 
                return 
                   compName: 'login'
                
                   
        );
    </script>
</body>

组件传值

父组件向子组件传值(props)
<body>
    <div id="app">
        <!-- 父组件在引用子组件时,可以通过属性绑定 v-bind: 的形式将数据传递给子组件, -->
        <comp1 v-bind:parentmsg="msg"></comp1>
    </div>
    <script>
        var vm = new Vue(
            el:'#app',
            data:
                msg: '我是父组件中的数据'
            ,
            components:
                comp1: 
                    template:'<h2>这是子组件 ---- parentmsg</h2>',
                    props:['parentmsg']   // 父组件传递来的 parentmsg 属性,要先在 props 数组中定义一下,这样才能使用这个数据
                
            
        )
    </script>
</body>

注意:组件中的 props 中的数据,都是通过父组件传递给子组件的,并且 props 中的数据,都是只读的,无法重新赋值。

子组件中的 data 不是父组件传递来的,而是子组件自己私有的,data 中的数据都是可读可写的。

子组件向父组件传值
<body>
    <div id="app">
        <!-- 父组件在引用子组件时,可以通过属性绑定 v-bind: 的形式将数据传递给子组件, -->
        <!-- <comp1 v-bind:parentmsg="msg"></comp1> -->
        <comp1 v-on:pfunc="show"></comp1>
    </div>

    <template id="childcomp">
            <div>
               <h2>这是子组件 ---- parentmsg</h2>
               <input type="button" value="这是子组件中的按钮,点击它,触发父组件传递过来的 pfunc方法" @click="send"></div>'
            </div>   
    </template>

    <script>
        var vm = new Vue(
            el:'#app',
            data:
                msg: '我是父组件中向子组件传递的数据'
            ,
            methods:
                show(data) 
                    console.log('我是父组件中的方法,接收到子组件的回调数据 ; '+ data);
                
            ,
            components:
                comp1: 
                    data()
                        return 
                            childdata:name:"child",age:12
                        
                    ,
                    template:'#childcomp',
                    props:['parentmsg'],
                    methods:
                        send()
                            this.$emit('pfunc',this.childdata)
                        
                    
                
            
        )
    </script>
</body>

以上是关于Vuejs 深入浅出 - 组件的主要内容,如果未能解决你的问题,请参考以下文章

Vuejs - 深入浅出响应式系统

VueJS 道具 - 我怎样才能避免“类”属性继承?

vuejs2:我怎样才能摧毁一个观察者?

让 vuejs 组件等待变量可用

深入浅出Vue.js--变化侦测

使用VueJS的Web组件