//需要: jquery.js + lodash.js + selectize.js //注意: 选项改变时激发的事件为input //https://github.com/selectize/selectize.js/blob/master/docs/api.md //https://github.com/selectize/selectize.js/blob/master/docs/usage.md const vueSelectize = (function () { const instance = {}; function clean(options) { return options.map(option => ({ text: option.text, value: option.value })); } var _suppressTime = 0; instance.create = function () { return { props: { key: { default: 0 }, value: { default: '' }, settings: { type: Object, default: () => ({}) }, disabled: { type: Boolean, default: false } }, data: function () { return { options: [], createdOptions: [] }; }, mounted: function () { var self = this; var settings = $.extend(true, {}, self.settings); if (settings.create) { const create = settings.create; settings.create = function (input, callback) { let option = null; if (create === true) { option = { text: input, value: input }; } else { option = create(input, callback); } self.createdOptions.push(option); return option; }; } var refactorEvents = ['onFocus', 'onBlur']; refactorEvents.forEach(function (x) { var callback = settings[x]; if (callback) { settings[x] = function () { callback(self.$el.selectize); }; } }); var $el = $(self.$el), _value; $el.selectize({ onInitialize() { _value = self.value + ""; self.setValue(); }, onChange(value) { //值相同不要激发事件 if (_value === value) return; //全局禁止不要激发事件 var now = new Date().getTime(); if (_suppressTime - now > 0) { return _value = value; } //元素数据禁止不要激发事件 var silent = new Date($el.data('silent')).getTime() || 0; if (silent && now - silent < 300) { return _value = value; } _value = value; self.$emit('input', value); }, items: self.value ? [self.value] : settings.items, ...settings }); self.makeOptions(true); self.toggleDisabled(self.disabled); }, destroyed() { if (this.$el.selectize) { this.$el.selectize.destroy(); } }, watch: { value(value, old) { if ("" + value !== "" + old) { this.setValue(); } }, disabled(value) { this.toggleDisabled(value); } }, methods: { toggleDisabled(value) { if (value) { this.$el.selectize.disable(); } else { this.$el.selectize.enable(); } }, makeOptions(justLocal = false) { const old = this.options; let _new = []; const nodes = this.$slots.default; if (this.settings.options === undefined && nodes) { _new = nodes.filter(node => node.tag && node.tag.toLowerCase() === 'option').map(node => { return { text: node.children ? node.children[0].text.trim() : null, value: node.data.domProps ? node.data.domProps.value : node.data.attrs.value }; }).concat(this.createdOptions); } if (!_.isEqual(clean(old), clean(_new))) { this.options = _new; if (!justLocal) { this.$el.selectize.clearOptions(); const optionValues = this.options.map(o => o.value); Object.keys(this.$el.selectize.options) //IE11 fix, Object.values is not supported .map(key => this.$el.selectize.options[key]).filter(option => optionValues.every(v => !_.isEqual(v, option.value))).forEach(option => this.$el.selectize.removeOption(option.value)); this.$el.selectize.addOption(this.options); this.$el.selectize.refreshOptions(false); this.setValue(); } } }, setValue() { this.$el.selectize.setValue(this.value); } }, beforeUpdate() { this.makeOptions(); }, template: '' }; }; //timeout:超时时间(毫秒) instance.suppressEvent = function (timeout) { if (timeout === true) { _suppressTime = new Date().getTime() + 500; } else if (timeout === false || timeout === 0) { _suppressTime = 0; } else { timeout = parseInt(timeout); _suppressTime = timeout > 0 ? new Date().getTime() + timeout : 0; } }; return instance; }());