• Vue笔记(二):Components


    组件注册


    <!-- 组件使用 -->
    <div id="exp">
        <my-component></my-component>
    </div>
    
    // 1. 全局注册 任何地方都可使用
    Vue.component('my-component', {
        props: ['msg'],
        template: '<span>this is my component!</span>',
        data: function(){
            return {
                ...
            }
        }
    });
    
    // 2. 创建根实例
    new Vue({
        el: '#exp',
        data: {}
    });
    
    注意:
        组件中的 data 必须是一个函数,否则 Vue 会停止工作。这样做是为了避免多个组件实例引用同一个 data 对象,导致彼此相互影响。换句话说,是为了保证组件实例间的相互独立,而这是通过每次调用 data 函数返回一个新对象来实现的。
    

    Props


    1. 字面量语法

    组件实例的作用域是孤立的,不能在子组件的模板内直接引用父组件的数据。如果子组件要引用父组件的数据,需要使用 props 属性。

    Vue.component('child', {
      props: ['myName'], // 声明 props
      template: '<span>{{ myName }}</span>'
    });
    

    这里的 props 就如同实例中的 data 对象,也可以在实例中以 this.myName 形式使用。

    <child my-name="hello!"></child>
    
    注意:
        HTML 特性不区分大小写。使用驼峰式命名的 prop 需要转换为相对应的短横线隔开式命名。
        myName --> my-name
    

    2. 动态语法:v-bind

    类似于用 v-bind 绑定 HTML 特性,我们也可用 v-bind 将动态 props 绑定到父组件中的数据。实现父组件与子组件数据变化的传递。

    <div id="exp-1">
        <input v-model="parentMsg">
        <child :msg="parentMsg"></child>
    </div>
    
    new Vue({
        el: '#exp-1',
        data: {
            parentMsg: 'parent message'
        },
        components: {
            child: {
                props: ['msg'],
                template: '<button>{{msg}}</button>'
            }
        }
    });
    
    注意:
        这种数据绑定是单向的,父组件数据会影响子组件数据,但子组件数据不会影响父组件。
    

    3. Prop验证

    我们可以为组件的 props 指定验证规格。如果传入的数据不符合规格,Vue 会发出警告。

    Vue.component('my-component', {
        props: {
            prop1: 'null', // 任何类型皆可
            prop2: [String, Number], // 指定多种类型
            prop3: {
                type: Number,
                reuqired: true, // 属性必需且为数值型
                default: 20, // 指定默认值
                twoway: true, // 指定此prop为双向绑定 2.0移除
                validator: function(v){ // 自定义验证器
                    return v > 10
                }
            }
        }
    });
    

    props 验证失败时, Vuejs 将拒绝在子组件上设置此值。

    组件通信 / 2.0+


    1. v-on 绑定自定义事件

    $on 监听事件:vm.$on('eventName', handler)

    $emit 触发事件:vm.$emit('eventName', args)

    <div id="exp-2">
        <h4>Total:{{total}}</h4>
        <my-btn @customEvt="reduceNum">{{counter}}</my-btn>
        <my-btn @customEvt="reduceNum">{{counter}}</my-btn>
    </div>
    

    在使用子组件的地方直接用 v-on:customEvt 来监听子组件事件的触发,来实现父子组件的通信。

    Vue.component('my-btn', {
        template: '<button @click="addNum">{{counter}}</button>',
        data: function(){
            return {
                counter: 0
            }
        },
        methods: {
            addNum: function(){
                this.counter++;
                this.$emit('customEvt');
            }
        }
    });
    
    new Vue({
        el: '#exp-2',
        data: {
            total: 0
        },
        methods: {
            reduceNum: function(){
                this.total++;
            }
        }
    });
    

    2. 双向绑定的两种简单实现

    # v-model + watch

    1. 由于子组件内部 props 不可写,因此我们需要在 data 对象中创建一个副本并将其初始为 props 属性的值。
    2. 组件外修改 props 并不会同步到副本中,因此我们设置一个侦听器 watchprops 与其副本数据同步。
    3. 监听副本状态变化,触发事件回调 this.$emit('input', val)
    4. 最后结合 v-model 将子组件的数据传递到外部,父组件数据响应式改变。
    <template id="temp">
        <div>
            <input v-model="myname">
            <button>{{myname}}</button>
        </div>
    </template>
    
    <div id="exp-3">
        <h3>父组件</h3>
        <input v-model="name">
        <button>{{name}}</button>
        
        <h3>子组件</h3>
        <child :sname="name" v-model="name"></child>
    </div>
    
    
    new Vue({
        el: '#exp',
        data: {
            name: 'zz'
        },
        components: {
            'child': {
                template: '#temp',
                props: ['sname'],
                data: function(){
                    return {
                        myname: this.sname  // 1
                    }
                },
                watch: {
                    sname: function(val){
                        this.myname = val;  // 2
                    },
                    myname: function(val){
                        this.$emit('input', val);  // 3
                    }
                }
            }
        }
    });
    

    JS Bin - watch 双向绑定

    # props + obj

    将一个引用类型传递给 props 属性,由于对象的地址引用特性,子组件修改对象属性父组件数据也相应改变。借此实现组件数据的双向绑定。

    <template id="temp">
        <div>
            <input v-model="obj.name">
            <button>{{obj.name}}</button>
        </div>
    </template>
    
    <div id="exp">
        <h3>父组件</h3>
        <input v-model="obj.name">
        <button>{{obj.name}}</button>
            
        <h3>子组件</h3>
        <child :obj="obj"></child>
    </div>
    
    new Vue({
        el: '#exp',
        data: {
            obj:{
                name: 'oo'
            }
        },
        components:{
            'child':{
                template: '#temp',
                props: ['obj']
            }
        }
    });
    

    JS Bin - 对象props双向绑定

  • 相关阅读:
    Python数据结构-链表
    面试题4:替换空格
    面试题3:二维数组中的查找
    2019.12.17基佬出的一道题
    2019.12.17霍格沃兹测试学院一道题
    python_ck01(虚拟环境管理)
    api_DZFPKJ & api_DZFPCX(get_AES_url代码优化)
    cwyth(自动核销代码)
    api_DZFPKJ & api_DZFPCX
    字符串返回数组并排序(算法题)
  • 原文地址:https://www.cnblogs.com/qimeng/p/7683948.html
Copyright © 2020-2023  润新知