我有一个基于vue的网络apply.JS2.0.

我有一个基于select2插件显示输入的组件.

默认情况下,它会显示选中的选项,但当用户单击它时,我会显示select2以允许用户修改选项.

代码如下所示:

<template>
<div @click="toggleEdit">
    <span v-show="isEnabled">
        <select
            class="form-control"
            :name="name"
            :multiple="multiple"
        >
            <option v-for="opt in options" :value="opt.id"> {{ opt.text }} </option>
        </select>
    </span>
    <span v-show="!isEnabled">
        <div v-if="selectedOptions.length === 0">
            {{ emptyText }}
        </div>
        <div v-for="opt in selectedOptions">
            {{ opt }}
        </div>
    </span>
</div>
</template>
<script>
export default {
    props: {
        options: {
            type: Array,
            required: false,
            default: function() {
                return []
            }
        },
        name: {
            required: true,
            type: String
        },
        multiple: {
            required: false,
            type: Boolean,
            default: false
        },
        emptyText: {
            required: false,
            type: String,
            default: ""
        },
        sourceUrl: {
            required: false,
            type: String,
            default: ""
        },
        enabled: {
            required: false,
            type: Boolean,
            default: false
        }
    },

    data() {
        return {
            isEnabled: this.enabled
        }
    },

    watch: {
        options: {
            handler: function() {
                console.log(arguments)
            },
            deep: true
        }
    },

    mounted: function() {
        this.select = $(this.$el).find("select");
        this.select.select2();
        var that = this;
        this.select.on("change", function(e) {
            var indexMap = {};
            for(var i = 0; i < that.options.length; i++) {
                that.options[i].selected = false;
                indexMap[that.options[i].id] = i;
            }
            var selected = that.select.select2('val');
            if(typeof selected === "string") {
                selected = [selected];
            }
            for(var i = 0; i < selected.length; i++) {
                var index = indexMap[selected[i]];
                console.log(index)
                console.log(selected[i])
                if(index !== undefined) {
                    var option = that.options[index];
                    option.selected = true;
                    that.$set(that.options, index, option);
                }
            }
        })
        this.select.on("select2:open", function() {
            that.isEnabled = true;
        });
        this.select.on("select2:close", function() {
            that.isEnabled = false;
        });
    },
    methods: {
        toggleEdit() {
            if(this.isEnabled) return; // to pass select2 clicks
            this.isEnabled = !this.isEnabled;
            var that = this;
            this.$nextTick(function() {
                that.select.select2("open");
            });
        }
    },
    computed: {
        selectedOptions: function() {
            console.log(this.options)
            return this.options.filter(function(option) {
                console.log(option.selected);
                if(option.selected === true) return true;
                return false;
            });
        }
    }
}

问题是:我想展示使用这个组件的多个不同的selects.Name属性可以是以下属性之一:model1[field1]model1[field2]、...,model40[field1], ..., model99[field15],其中每个modelN对应于数据库中的表及其各自的字段.

当用户更改选项时,必须将ajax请求发送到服务器,服务器返回如下json对象

{
   "errorText": null or "text with error",
   "disableFields": ["model3[field4]", "model24[field15]"]
}

我想解析"disableFields"数组,并从this个组件中禁用another个组件.

实现这一点的一种方法(伪代码):

foreach field in disableField:
    $(document).trigger("disableField" + field);

mounted种方法中,this种成分

var self = this;
$(document).on("disableField" + this.name, function() {
    self.isEnabled = false
})

有没有更好的方法在没有父组件的情况下实现这一点?

推荐答案

不允许直接与另一个组件通信.您可以使用父组件在组件或some kind of event bus之间进行通信.

var bus = new Vue();

组件A发出一个事件,而组件B可能捕捉到它,反之亦然.

// component A
bus.$emit('cool_event_name', interesting_data)

// component B
bus.$on('cool_event_name', function(interesting_data) {
   console.log(interesting_data)
})

另一个解决方案可能是使用$root,它可以从Vue实例的所有子组件访问.这节省了全局总线的定义(如上所述).请注意,此方法作为一般方法为not recommended,更像是某些边缘情况的解决方案.

// component A
this.$root.$emit('cool_event_name', interesting_data)

// component B
this.$root.$on('cool_event_name', function(interesting_data) {
   console.log(interesting_data)
})

Vue.js相关问答推荐

正在try 访问vutify中v-select(ItemProps)的嵌套json值

为什么我的数组在 onBeforeMount 函数中不为空,但在 onMounted 函数中为空

在哪里可以找到在线沙箱 Vuetify 3 模板来创建最小的可重现示例?

Vue.js 3 运行时挂载组件实例

Vue 3 范围滑块中的多个值

Vuetify/Nuxt 生产环境组件在开发环境中无法正常工作

使用 Nuxt 动态获取文件夹中的图像路径

如何在Typescript语言Vuejs中使用watch功能?

Vue 和 Bootstrap Vue - 动态使用插槽

将检测外部点击自定义指令从 Vue 2 迁移到 Vue 3

Vuetify 容器不会填充高度

如何在 Vue.js 中触发点击 ref

Vuetify 单选按钮未显示为选中状态

在 Vuejs 中计算 DOM 元素之间距离的最佳方法是什么?

我可以修改 Vue.js VNodes 吗?

使用 vue-router 的默认子路由

如何告诉 Vue-cli 我的应用程序的入口点在哪里?

在 .vue 文件中使用 Vue.set() 和 Vue.use()

使用 refs 聚焦元素目标

如何让 vuetify 数据表在卡片内时跨越容器的整个宽度?