• 【VUE】自定义组件数据双向绑定


    自定义一个组件

    通过 Prop 向子组件传递数据

    props: {
        value: {
            type: String,
            default: ''
        }
    }

    监听子组件事件

    子组件可以通过调用内建的 $emit 方法,并传入事件名称来触发一个事件,父级组件就会接收该事件并作出处理

    子组件抛出事件

    $emit('yourEventName'); // 不传值
    $emit('yourEventName', 'hello'); // 传值

    父组件处理事件

    v-on:yourEventName="doSomething"
    
    doSomething(v) {
    }

    在组件上使用 v-model

    先看 input 组件如何工作

    <input v-model="searchText"> 等价于: <input v-bind:value="searchText" v-on:input="searchText = $event.target.value">

    当在组件上时 v-model 则会这样

    <custom-input v-bind:value="searchText" v-on:input="searchText = $event"></custom-input>

    为了让它正常工作,这个组件内的 <input> 必须:
    将其 value attribute 绑定到一个名叫 value 的 prop 上
    在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出

    Vue.component('custom-input', {
      props: ['value'],
      template: `<input v-bind:value="value" v-on:input="$emit('input', $event.target.value)">`
    })

    现在 v-model 就可以在这个组件上完美地工作起来了

    <custom-input v-model="searchText"></custom-input>

    问题:如果自定义组件不是一个 input 该如何,使用 model 定制 prop 和 event

    model: {
      prop: 'checked',
      event: 'change'
    },
    

    将 value 的事件重新定义为 change

    一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框、下拉框等类型的输入控件可能会将 value 属性用于不同的目的,model 选项可以用来避免这样的冲突:

    Vue.component('my-checkbox', {
      model: {
        prop: 'checked',
        event: 'change'
      },
      props: {
        value: String, // 允许 value 属性用户其他目的
        // 使用 checked 作为属性来取代 value 地方
        checked: {
          type: Number,
          default: 0
        }
      },
    })
    
    <my-checkbox v-model="foo" value="some value"></my-checkbox>
    上述代码相当于:
    <my-checkbox :checked="foo" @change="val => { foo = val }" value="some value"></my-checkbox>

    自定义组件例子

    父组件

    调用子组件,v-model 绑定

    <area-code-select-element v-model="myCode"></area-code-select-element>

    子组件

    <template>
        <el-select v-model.trim="selectedCode" :size="btnSize" placeholder="区划编码" filterable clearable @change="selectChange">
            <el-option v-for="item in list" :key="item.code" :label="item.codeText" :value="item.code"></el-option>
        </el-select>
    </template>
    
    <script>
        import {mapGetters} from 'vuex';
        import {
            getDictionaryByIndexId
        } from "../../api/admin/dictionary";
    
        export default {
            name: "area-code-select-element",
            model: {
                prop: "value",
                event: "change"
            },
            props: {
                value: {
                    type: String,
                    default: ''
                },
                disable: {
                    type: Boolean,
                    default: false
                }
            },
            data() {
                return {
                    list: [],
                    selectedCode: undefined,
                }
            },
            computed: {
                ...mapGetters([
                    'btnSize'
                ])
            },
            watch: {
                value(newValue, oldValue) {
                    console.log(`父组件值:${newValue}`);
                    console.log(`子组件值:${this.selectedCode}`);
                }
            },
            created() {
                this.loadDictionaryByIndexId();
            },
            methods: {
                loadDictionaryByIndexId() {
                    this.list = [];
                    getDictionaryByIndexId("area_code").then(response => {
                        this.list = response.data;
                    });
                },
                selectChange(value) {
                    this.$emit('change', value);
                },
            }
        }
    </script>
    
    <style scoped>
    
    </style>
  • 相关阅读:
    JAVA正则表达式判断元音
    JAVA正则表达式校验qq号码
    方法
    数组
    Java基础随笔3
    LDA背景资料
    scrapy系列(四)——CrawlSpider解析
    scrapy系列(三)——基础spider源码解析
    scrapy系列(二)——startproject、genspider创建项目与模板使用
    我眼中的机器学习(四) 快速寻找最优解
  • 原文地址:https://www.cnblogs.com/yangchongxing/p/16130156.html
Copyright © 2020-2023  润新知