vue自定义组件-select组件

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

基于vue自定义select组件

index.html——调用页面


    
    
    

select.js——select组件

Vue.component('yun-select', {
    name: 'ElSelect',
    componentName: 'ElSelect',
    template: '
'+ '
'+ ''+ '
'+ '
'+ '
    '+ ''+ '
'+ '
'+ '
', data: function () { return { currentValue: '', visbale:false, cachedOptions:[], } }, props: { value: { // 必须要使用value      default: '',     }, }, provide() { return { 'select': this }; }, created(){ this.$on('handleOptionClick', this.handleOptionSelect); }, mounted(){ this.setOptionLabel(); }, wathch:{ }, directives: { Clickoutside }, methods: { toggleMenu(){ this.visbale = !this.visbale; }, handleClose(){ this.visbale = false; }, setOptionLabel(){ var flag = false; for(var i =0,j=this.cachedOptions.length;i

option.js——option组件(select子菜单)

Vue.component('yun-option', {
    mixins: [Emitter],
    name: 'ElOption',
    componentName: 'ElOption',
    inject: ['select'],
    template: '
  • '+ ''+ '{{ currentLabel }}'+ ''+ '
  • ', data: function () { return { } }, props: { value: { type: Number, required: true, }, visbale:{ type: Boolean, default:true }, label: [String, Number], }, created() { this.select.cachedOptions.push(this); }, computed: { currentLabel() { return this.label || (this.isObject ? '' : this.value); }, currentValue() { return this.value; }, }, methods: { selectOptionClick(){ if (this.disabled !== true && this.groupDisabled !== true) { this.dispatch('ElSelect', 'handleOptionClick', this); } }, } })

    emitter.js——vue订阅与发布

    function broadcast(componentName, eventName, params) {
        this.$children.forEach(child => {
          var name = child.$options.componentName;
            
          if (name === componentName) {
            child.$emit.apply(child, [eventName].concat(params));
          } else {
            broadcast.apply(child, [componentName, eventName].concat([params]));
          }
        });
      }
    var Emitter = {
        methods: {
          dispatch(componentName, eventName, params) {
            var parent = this.$parent || this.$root;
            var name = parent.$options.componentName;
      
            while (parent && (!name || name !== componentName)) {
              parent = parent.$parent;
      
              if (parent) {
                name = parent.$options.componentName;
              }
            }
            if (parent) {
              parent.$emit.apply(parent, [eventName].concat(params));
            }
          },
          broadcast(componentName, eventName, params) {
            broadcast.call(this, componentName, eventName, params);
          }
        }
      };

    clickoutside.js——vue自定义指令事件

    const nodeList = [];
    const ctx = '@@clickoutsideContext';
    
    let startClick;
    let seed = 0;
    
    !Vue.prototype.$isServer && on(document, 'mousedown', e => (startClick = e));
    
    !Vue.prototype.$isServer && on(document, 'mouseup', e => {
      nodeList.forEach(node => node[ctx].documentHandler(e, startClick));
    });
    
    function createDocumentHandler(el, binding, vnode) {
      return function(mouseup = {}, mousedown = {}) {
        if (!vnode ||
          !vnode.context ||
          !mouseup.target ||
          !mousedown.target ||
          el.contains(mouseup.target) ||
          el.contains(mousedown.target) ||
          el === mouseup.target ||
          (vnode.context.popperElm &&
          (vnode.context.popperElm.contains(mouseup.target) ||
          vnode.context.popperElm.contains(mousedown.target)))) return;
    
        if (binding.expression &&
          el[ctx].methodName &&
          vnode.context[el[ctx].methodName]) {
          vnode.context[el[ctx].methodName]();
        } else {
          el[ctx].bindingFn && el[ctx].bindingFn();
        }
      };
    }
    
    /**
     * v-clickoutside
     * @desc 点击元素外面才会触发的事件
     * @example
     * ```vue
     * 
    * ``` */ var Clickoutside = { bind(el, binding, vnode) { nodeList.push(el); const id = seed++; el[ctx] = { id, documentHandler: createDocumentHandler(el, binding, vnode), methodName: binding.expression, bindingFn: binding.value }; }, update(el, binding, vnode) { el[ctx].documentHandler = createDocumentHandler(el, binding, vnode); el[ctx].methodName = binding.expression; el[ctx].bindingFn = binding.value; }, unbind(el) { let len = nodeList.length; for (let i = 0; i < len; i++) { if (nodeList[i][ctx].id === el[ctx].id) { nodeList.splice(i, 1); break; } } delete el[ctx]; } };

    dom.js——dom事件绑定

    const isServer = Vue.prototype.$isServer;
    /* istanbul ignore next */
     var  on  = (function() {
      if (!isServer && document.addEventListener) {
        return function(element, event, handler) {
          if (element && event && handler) {
            element.addEventListener(event, handler, false);
          }
        };
      } else {
        return function(element, event, handler) {
          if (element && event && handler) {
            element.attachEvent('on' + event, handler);
          }
        };
      }
    })();
    

     

    转载于:https://my.oschina.net/sunshineS/blog/1609566

    你可能感兴趣的:(vue自定义组件-select组件)