zoukankan      html  css  js  c++  java
  • [Vue] : 组件

    定义Vue组件

    什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可;
    组件化和模块化的不同:

    • 模块化: 是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一;
    • 组件化: 是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用;

    全局组件定义的三种方式

    1. 使用Vue.extend配合Vue.component方法:
    • 1.1 使用Vue.extend来创建全局的Vue组件
    • 1.2 通过template属性,指定了组件要展示的HTML结构,模板内容必须有且只能有唯一的一个根元素。
    • 1.3 使用Vue.component('组件的名称', 创建出来的组件模板对象)
    var com1 = Vue.extend({
        template: '<h1>这是通过Vue.extend()方式创建的组件</h1>'
    })
    
    Vue.component('myCom1', com1)
    
    • 1.4 如果要使用组件,直接把组件的名称,以 HTML 标签的形式,引入到页面中即可
    • 1.5 如果使用Vue.component定义全局组件的时候,组件名称使用了驼峰命名,则在引用组件的时候,需要把大写的驼峰改为小写的字母,两个单词之前,使用-链接
    • 1.6 如果不使用驼峰,则直接拿名称来使用即可
    <div id="app">
        <my-com1></my-com1>
    </div>
    

    也可以直接写成

    Vue.component('myCom1', Vue.extend({
        template: '<h1>这是通过Vue.extend()方式创建的组件</h1>'
    }))
    
    1. 直接使用 Vue.component 方法:
    Vue.component('myCom2', {
        template: '<h1>第二个参数直接传个对象</h1>'
    })
    
    • 也可以改为
    var tmpObj = {
        template: '<h1>第二个参数直接传个对象</h1>'
    }
    
    Vue.component('myCom2', tmpObj)
    
    1. 在 被控制的 #app 外面,使用 template 元素,定义组件的HTML模板结构
    <template id="tmpl">
        <div>
            <h1>通过 template 在组件外部定义的模板</h1>
            <h4>哈哈</h4>
        </div>
    </template>
    

    同时,需要使用 Vue.component 来定义组件:

    Vue.component('myCom1', {
        template: '#tmpl'
    })
    

    注意: 组件中的DOM结构,有且只能有唯一的根元素(Root Element)来进行包裹!

    定义私有组件

    定义实例内部私有组件,子组件内部还可以继续定义子组件

    var vm = new Vue({
        el: '#app',
        data: {
        },
        components: {
            login: {
                template: '<div><h1>登录</h1><child-com></child-com></div>',
                components: {
                    childCom: {
                        template: '<h3>登录子组件的子组件</h3>'
                    }
                }
            }
        }
    })
    

    也可将模板写在html结构中,实例内部写成template: '#login'

    或者将模板对象定义到实例外部,内部通过'组件的名称': 组件的模板对象的方式定义私有组件。如果组件名称与组件模板对象同名,可以简写。

    var login = {
        template: '<h1>1234</h1>'
    }
    
    var vm = new Vue({
        el: '#app',
        components: {
            // '组件的名称': 组件的模板对象
            // 'mylogin': login
            login
        }
    })
    

    在组件内部

    <template id="login">
        <h1>登录</h1>
    </template>
    

    组件中datamethods

    1. 在组件中,data需要被定义为一个方法,这个方法内部必须返回一个对象。
    2. 组件中 的data 使用方式,和实例中的 data 使用方式完全一样。
    Vue.component('account', {
        template: '#tmpl',
        data() {
            return {
                msg: '大家好!'
            }
        },
        methods:{
            login(){
                alert('点击了登录按钮');
            }
        }
    });
    

    计数器示例

    注意:data如果return dataObj,会导致多个计数器共用dataObj对象,因此需要return { count: 0 },才能保证各个计数器之间互不影响

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <script src="lib/vue-2.4.0.js"></script>
    </head>
    
    <body>
      <div id="app">
        <counter></counter>
        <hr>
        <counter></counter>
      </div>
    
      <template id="tmpl">
        <div>
          <input type="button" value="+1" @click="increment">
          <h3>{{count}}</h3>
        </div>
      </template>
    
      <script>
        var dataObj = { count: 0 }
    
        Vue.component('counter', {
          template: '#tmpl',
          data() {
            // return dataObj
            return { count: 0 }
          },
          methods: {
            increment() {
              this.count++
            }
          }
        })
    
        var vm = new Vue({
          el: '#app'
        })
      </script>
    </body>
    
    </html>
    

    切换组件

    定义登录和注册组件

    Vue.component('login', {
        template: '<h3>登录组件</h3>'
    })
    
    Vue.component('register', {
        template: '<h3>注册组件</h3>'
    })
    

    通过flag配合v-if v-else切换组件

    <div id="app">
        <a href="#" @click.prevent="flag=true">登录</a>
        <a href="#" @click.prevent="flag=false">注册</a>
        <login v-if="flag"></login>
        <register v-else></register>
    </div>
    

    使用:is属性来切换组件

    使用component标签,来引用组件,并通过:is属性来指定要加载的组件

    <div id="app">
        <a href="#" @click.prevent="comName='login'">登录</a>
        <a href="#" @click.prevent="comName='register'">注册</a>
        <component :is="comName"></component>
    </div>
    

    组件切换的动画效果

    • 使用transition包裹要实现动画的组件
    • 定义v-enter, v-leave-to, v-enter-active, v-leave-active样式
    • 设置transition mode属性设置组件切换时候的模式,否则两个动画会同时执行
    <div id="app">
        <a href="#" @click.prevent="comName='login'">登录</a>
        <a href="#" @click.prevent="comName='register'">注册</a>
        <transition mode="out-in">
            <component :is="comName"></component>
        </transition>
    </div>
    

    父组件向子组件传值

    1. 父组件可以在引用子组件的时候, 通过属性绑定v-bind:的形式, 把需要传递给子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用。
    <div id="app">
        <com1 v-bind:parentmsg="msg"></com1>
    </div>
    
    1. 子组件一定要使用props属性来定义父组件传递过来的数据
    var vm = new Vue({
        el: '#app',
        data: {
            msg: '这是父组件的数据'
        },
        components: {
            com1: {
                template: '<h1>子组件 -- {{parentmsg}}</h1>',
                props: ['parentmsg']
            }
        }
    })
    

    子组件中的data中的数据和props中的数据的区别:

    • 子组件中的data数据,并不是通过 父组件传递过来的,而是子组件自身私有的,组件中的所有props中的数据,都是通过父组件传递给子组件的
    • data上的数据,都是可读可写的;props中的数据,都是只读的,无法重新赋值

    父组件向子组件传递方法

    • 父组件向子组件传递方法,使用的是v-on事件绑定机制;
    • 子组件在自定义的myclick方法中,通过this.$emit('事件属性')的方式调用父组件传递过来的方法
    <body>
      <div id="app">
        <!-- 用func接收父组件的show方法 -->
        <com2 @func="show"></com2>
      </div>
    
      <!-- 定义了子组件模板 -->
      <template id="tmpl">
        <div>
          <h1>这是子组件</h1>
          <input type="button" value="子组件按钮,点击调父组件show方法" @click="myclick">
        </div>
      </template>
    
      <script>
        // 定义了一个字面量类型的组件模板对象
        var com2 = {
          template: '#tmpl',
          methods: {
            myclick() {
              this.$emit('func')
            }
          }
        }
    
        var vm = new Vue({
          el: '#app',
          methods: {
            show() {
              console.log('这是父组件的show方法')
            }
          },
          components: {
            com2
          }
        })
      </script>
    </body>
    

    子组件向父组件传值

    1. 原理:父组件将方法的引用,传递到子组件内部,子组件在内部调用父组件传递过来的方法,同时把要发送给父组件的数据,在调用方法的时候当作参数传递进去;
    2. 父组件将方法的引用传递给子组件,其中,getMsg是父组件中methods中定义的方法名称,func是子组件调用传递过来方法时候的方法名称
    3. 子组件内部通过this.$emit('方法名', 要传递的数据)方式,来调用父组件中的方法,同时把数据传递给父组件使用
    <div id="app">
        <com2 @func="getMsg"></com2>
    </div>
    
    <!-- 定义了子组件模板 -->
    <template id="tmpl">
        <div>
            <h1>这是子组件</h1>
            <input type="button" value="按钮" @click="myclick">
        </div>
    </template>
    
    <script>
        // 定义了一个字面量类型的组件模板对象
        var com2 = {
            template: '#tmpl',
            data() {
                return {
                    sonMsg: { id: 1, name: '张三' }
                }
            },
            methods: {
                myclick() {
                    this.$emit('func', this.sonMsg)
                }
            }
        }
    
        var vm = new Vue({
            el: '#app',
            data: {
                parentMsg: null
            },
            methods: {
                getMsg(data) {
                    this.parentMsg = data
                    console.log(this.parentMsg)
                }
            },
            components: {
                com2
            }
        })
    </script>
    

    使用 this.$refs 来获取DOM元素和组件

    • 获取DOM元素
    <h3 ref="myh3">这是一个H3</h3>
    

    在Vue实例中,使用this.$refs.myh3 获取到DOM元素,与document.getElementById('myh3') 等效

    • 获取组件
    <div id="app">
        <input type="button" value="获取组件" @click="getElement">
        <com1 ref="mycom"></com1>
    </div>
    
    <template id="tmpl">
        <div>
            <h3>子组件</h3>
        </div>
    </template>
    <script>
    
        var com1 = {
            template: '#tmpl',
            data(){
                return {
                    msg:'子组件的msg'
                }
            },
            methods: {
                show(){
                    console.log('子组件的show方法')
                }
            }
        }
        var vm = new Vue({
            el: '#app',
            data: {
            },
            methods:{
                getElement() {
                    // 获取子组件的data数据
                    console.log(this.$refs.mycom.msg)
                    // 调用子组件的方法
                    this.$refs.mycom.show()
                }
            },
            components:{
                com1
            }
        })
    </script>
    
  • 相关阅读:
    VLAN配置Trunk接口
    VLAN基础配置及Access接口实验
    在linux虚拟机中演示DHCP管理动态IP地址
    虚拟机 有关于Vsftpd验证方式虚拟用户访问模式
    使用Bind提供域名解析服务:正向解析和反向解析
    虚拟机环境下有关于NFS系统的介绍操作
    虚拟机 有关于Vsftpd验证方式本地用户访问模式
    虚拟机 有关于Vsftpd验证方式匿名访问模式
    虚拟机上有关于Apache服务基于主机名@基于端口号
    C#版 Winform界面 Socket编程 Client客户端
  • 原文地址:https://www.cnblogs.com/moon1992/p/11075018.html
Copyright © 2011-2022 走看看