动态添加时第一个组件上的单击组件触发事件

Posted

技术标签:

【中文标题】动态添加时第一个组件上的单击组件触发事件【英文标题】:Clicked component trigger event on first component when dynamic added 【发布时间】:2019-03-05 20:02:51 【问题描述】:

我有这个组件

<template>
    <div class="row py-2">
        <div class="col-sm-12">
            <v-checkbox @clicked="changeStatus($event)" :val="checkFont" :key="'checkfont'">
                <span>Activar/Desactivar</span>
            </v-checkbox>
        </div>
        <transition name="fade">
            <div class="col-sm-12" v-if="checkFont == true">
                <div v-for="(type, key) in types">
                    <div class="my-2">
                        <h5 class="text-capitalize"> type.label </h5>
                    </div>  
                    <div class="my-2">
                        <v-selectpicker :input-name="fieldName(type.label)" :properties="fonts" :has-addon="false" field="family" :notlang="true" @optionselected="getFont($event, key)"></v-selectpicker>
                    </div>
                    <div class="" v-if="type.font !== ''">
                        <div v-for="(v, index) in getVariants(key)" :key="index">
                            <v-checkbox @clicked="setVariant($event, key, v)" :val="variantText(v)" :key="index">
                                <span> variantText(v) </span>
                            </v-checkbox>
                        </div>
                    </div>


                </div>
            </div>
        </transition>
    </div>
</template>
<script>
    const SelectPicker = () => import('../admin/selectpicker')
    const CustomCheckbox = () => import('./customCheckbox')
    export default 
        data : function() 
            return 
                fonts   : [family : ''],
                types   : 
                    headers : 
                        label   : 'Titulos',
                        font : '',
                        variant : ''
                    ,
                    paragraphs : 
                        label   : 'parrafos',
                        font    : '',
                        variant : '',
                    ,
                    links      : 
                        label   : 'Links',
                        font    : '',
                        variant : '',
                    
                ,
                checkFont : false
            
        ,
        created : function() 
            this.getFonts();
        ,
        components : 
            'v-selectpicker' : SelectPicker,
            'v-checkbox' : CustomCheckbox
        ,
        methods : 
            getFonts : function() 
                axios.get('https://www.googleapis.com/webfonts/v1/webfonts?sort=popularity&key=AIzaSyBUjWSsTwBeOFXwHYga8YQZIDauLiS8Gy8').then((response) => 
                    this.fonts = response.data.items;
                );
            ,
            fieldName : function(field) 
                return field.toLowerCase()
            ,
            getFont : function($event, key) 
                this.types[key].font = $event.option;
                this.getVariants(key);
            ,
            changeStatus : function($event) 
                console.log($event)
                this.checkFont   = !this.checkFont;
            ,
            getVariants : function(key) 
                return this.fonts.filter((element) => element.family == this.types[key].font)[0].variants;
            ,
            setVariant : function($event, key, v) 
                console.log('variant clicked');
                console.log($event);
                this.types[key].variant = v;
            ,
            variantText : function(v) 
                return v.indexOf('00') !== -1 ? v.split('00').join('00 ') : v;
            
        
    
</script>

这是 v-checkbox 组件。

<template>
    <div class="cntr">
        <label for="cbx" class="label-cbx">
            <input id="cbx" type="checkbox" :model="val" class="invisible" @change="checked = checkCheckbox(checked)" :checked="checked">
            <div class="checkbox">
                <svg   viewBox="0 0 20 20">
                    <path d="M3,1 L17,1 L17,1 C18.1045695,1 19,1.8954305 19,3 L19,17 L19,17 C19,18.1045695 18.1045695,19 17,19 L3,19 L3,19 C1.8954305,19 1,18.1045695 1,17 L1,3 L1,3 C1,1.8954305 1.8954305,1 3,1 Z"></path>
                    <polyline points="4 11 8 15 16 6"></polyline>
                </svg>
            </div>
            <slot></slot>
        </label>
    </div>
</template>
<script>
    export default 
        props : ['val'],
        data : function() 
            let data = 
                checked : false
            ;
            return data
        ,
        methods : 
            checkCheckbox : function(checkbox) 
                this.$emit('clicked', 
                    value : this.val
                );
                let status = eval(checkbox) == true ? false : true;
                return status;
            
        
    
</script>

问题出在 v-checkbox 中,一切正常,直到我单击 v-for="(v, index) in getVariants(key)" :key="index" 中的动态 v-checkbox 之一,每当我点击其中一个时,the v-checkbox :key="'checkfont'" 被触发,所以 checkFont 道具值发生变化

我正在使用 vue devtools 检查组件,我可以看到 :val 属性具有正确的值,但是当单击事件时会发出一个布尔值,然后触发 @clicked="changeStatus($event)",为什么会发生这种情况?我不能像这样使用组件吗?我该如何解决?

【问题讨论】:

【参考方案1】:

我意识到问题出在checkbox 中的id,每个checkbox 的ID 都是cbx,所以它总是在点击时调用第一个元素

【讨论】:

以上是关于动态添加时第一个组件上的单击组件触发事件的主要内容,如果未能解决你的问题,请参考以下文章

Angular 表单:如何动态添加/删除子表单组件

如何使用 props 动态挂载 vue 组件

向非叶节点动态添加节点不起作用 | J树

在 Vue 中动态添加带有事件的不同组件

在 React 中为动态创建的按钮添加禁用属性

java - 如何在单击时将摆动组件动态添加到 gui?