Vuejs 深入浅出 - 组件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xingxtao/article/details/85041876

组件的定义

全局组件

全局组件可以在不同的挂载点中进行引用,全局组件的 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>

猜你喜欢

转载自blog.csdn.net/xingxtao/article/details/85041876