vue2自定义指令,dom嵌套组件

1、insertDom.js

insertDom.js

import {
  verifyString,
  extractStringVariables
} from "@/utils";
import store from '@/store';
import {
  Input,
  DatePicker,
  Message
} from 'element-ui'
import Vue from 'vue'
export default {
  inserted(el, binding, vnode) {
    const {
      value,
      readonly
    } = binding.value
    console.log(value);
    console.log(readonly,"readonly+++");
    let _curStrArr = extractStringVariables(value);
    let _protocolData = store.getters && store.getters.protocolData;
    console.log(_curStrArr);
    let _modifiedStr = value;
    (_curStrArr || []).forEach(item => {
      _modifiedStr = _modifiedStr.replace(item.key, `--$--${item.id}--$--`);
    });
    let _domConArr = _modifiedStr.split('--$--');
    console.log(_domConArr);
    let _currentCase="";
    if (_protocolData?.length) {
      _currentCase=store.getters && store.getters.currentCase;
    }
    let _editStrArr=["ready","text","date","money"];
    (_domConArr || []).forEach(item => {
      if (_protocolData.some(v => v.id == item)) {
        // let _childInput = document.createElement('input');
        // _childInput.setAttribute('type', 'text');
        // _childInput.setAttribute('placeholder', '请输入内容');
        // _childInput.setAttribute('id', item);
        // _childInput.addEventListener('change', (event) => {
        //     console.log(event.target.value);
        //     console.log(event.target.id);
        //     console.log(_protocolData, "_protocolData");
        //   });
        // el.appendChild(_childInput);
        // let instance = new Vue(Input).$mount();
        // 创建一个新的 Vue 实例,基于 Input 组件,并传入选项对象
        // 创建一个新的 Vue 实例,并传入选项对象  
        let _curDomObj = _protocolData.find(v => v.id == item);
        let instance = null;
        if (readonly) {
          if (item.indexOf("ready") > -1) {
            let _valStr="";//变量参数
            if (item.indexOf("readyName")>-1) {
              //案件人姓名
              _valStr=_currentCase?.case_name||"";
            }else if (item.indexOf("readyIdCard")>-1) {
              //身份证
              _valStr=_currentCase?.case_idcard||"";
            }else if (item.indexOf("readyCaseId")>-1) {
              //案号
              _valStr=_currentCase?.case_number||"";
            }else if (item.indexOf("readyPlatform")>-1) {
              //借款平台
              _valStr=_currentCase?.platform||"";
            }else if (item.indexOf("readyUnit")>-1) {
              //调解受理单位
              _valStr=_currentCase?.accept_unit||"";
            }else if (item.indexOf("readyMoney")>-1) {
              //调解金额
              _valStr=_currentCase?.amount||"";
            }else if (item.indexOf("readyReason")>-1) {
              //案由
              _valStr=_currentCase?.reason||"";
            }
            instance = new Vue({
              // el: document.createElement('view'), // 创建一个临时的 div 元素作为挂载点  
              render(h) {
                // 使用 render 函数渲染 Input 组件  
                return h('span', {
                  attrs: {
                    id: item, // 将 id 属性绑定到 Vue 实例的 data 中的 inputId
                  },
                  class: "text_custom_val"
                }, [
                  _valStr||"________________"
                ]);
              },
            }).$mount(); // 手动挂载实例
          } else {
            instance = new Vue({
              // el: document.createElement('view'), // 创建一个临时的 div 元素作为挂载点  
              render(h) {
                // 使用 render 函数渲染 Input 组件  
                return h('span', {
                  attrs: {
                    id: item, // 将 id 属性绑定到 Vue 实例的 data 中的 inputId
                  },
                  class: _curDomObj?.value?"text_custom_box":null
                }, [
                  _curDomObj?.value ? _curDomObj?.value : '________________'
                ]);
              },
            }).$mount(); // 手动挂载实例
          }

        } else {
          if (item.indexOf("text_") > -1 || item.indexOf("money_") > -1) {
            instance = new Vue({
              //   el: document.createElement('div'), // 创建一个临时的 div 元素作为挂载点  
              render(h) {
                // 使用 render 函数渲染 Input 组件  
                return h(Input, {
                  attrs: {
                    id: item, // 将 id 属性绑定到 Vue 实例的 data 中的 inputId
                  },
                  class: readonly ? "is_readonly" : "",
                  props: {
                
                    type: "text",
                    readonly: readonly, //是否仅读
                    placeholder: "请输入内容",
                    //   value: this.value,
                  },
                  model: {
                    value: this.value, // 将 value 属性绑定到 Vue 实例的 data 中的 value
                    callback: this.handleInput, // 绑定 input 事件到 handleInput 方法
                    expression: 'value',
                  },
                  on: {
                    // input: this.handleInput,
                    change: this.handleChange, // 添加 change 事件处理器
                  },
                });
              },
              data() {
                return {
                  // 在这里添加组件的属性  
                  value: _curDomObj?.value ? _curDomObj?.value : '',
                  placeholder: readonly ? "" : item.indexOf("text_") > -1 ? '请输入内容' : '请输入金额',
                };
              },
              methods: {
                // 在这里添加组件的事件处理函数  
                handleInput(newValue) {
                  this.value = newValue; // 更新 Vue 实例的 data 中的 value
                    console.log('输入内容:', this.value);
                },
                handleChange(event) {
                  console.log('值已更改:', event);
                  if (item.indexOf("money_") > -1) {
                    let _regex = /^(\d+(\.\d{1,7})?)$/;
                    if (!_regex.test(event)) {
                      Message.error("请输入正确的金额格式");
                      this.value = "";
                      return
                    }
                  }
                  //   console.log(this.$el);
                  let inputElement = this.$el.querySelector('input');
                  let _tempId = inputElement.getAttribute('id');
                  console.log('当前 input 的 id:', _tempId);
                  let _tempProtocolData = JSON.parse(JSON.stringify(store.getters && store.getters.protocolData));
                  let _tempEditArr = (_tempProtocolData || []).map(t => {
                    if (t.id == _tempId) {
                      t.value = event;
                    }
                    return t;
                  })
                  store.dispatch("changeStateValue", {
                    key: "protocolData",
                    value: _tempEditArr
                  });
                },
              },
              mounted() {
                // 通常不需要手动添加事件监听器,因为我们在 render 函数中已经做了这件事  
              },
              beforeDestroy() {
                // 通常不需要手动移除事件监听器,因为 Vue 会自动处理  
              },
            }).$mount(); // 手动挂载实例
          } else if (item.indexOf("date_") > -1) {
            instance = new Vue({
              //   el: document.createElement('div'), // 创建一个临时的 div 元素作为挂载点  
              render(h) {
                // 使用 render 函数渲染 Input 组件  
                return h(DatePicker, {
                  attrs: {
                    id: item, // 将 id 属性绑定到 Vue 实例的 data 中的 inputId
                  },
                  class: readonly ? "is_readonly" : "",
                  props: {
                    placeholder: this.placeholder,
                    type: "date",
                    valueFormat: "yyyy-MM-dd",
                    readonly: readonly
                    // value: this.value,
                  },
                  model: {
                    value: this.value, // 将 value 属性绑定到 Vue 实例的 data 中的 value
                    callback: this.handleDate, // 绑定 input 事件到 handleDate 方法
                    expression: 'value',
                  },
                  on: {
                    // input: this.handleDate,
                    change: this.handleChange, // 添加 change 事件处理器
                  },
                });
              },
              data() {
                return {
                  // 在这里添加组件的属性  
                  value: _curDomObj?.value ? _curDomObj?.value : '',
                  placeholder: readonly ? "" : '请选择日期',
                };
              },
              methods: {
                // 在这里添加组件的事件处理函数  
                handleDate(newValue) {
                  this.value = newValue; // 更新 Vue 实例的 data 中的 value
                  //   console.log('输入内容:', this.value);
                },
                handleChange(event) {
                  console.log('值已更改:', event);
                  //   console.log(this.$el);
                  let inputElement = this.$el.querySelector('input');
                  let _tempId = inputElement.getAttribute('id');
                  console.log('当前 input 的 id:', _tempId);
                  let _tempProtocolData = JSON.parse(JSON.stringify(store.getters && store.getters.protocolData));
                  let _tempEditArr = (_tempProtocolData || []).map(t => {
                    if (t.id == _tempId) {
                      t.value = event;
                    }
                    return t;
                  })
                  store.dispatch("changeStateValue", {
                    key: "protocolData",
                    value: _tempEditArr
                  });
                },
              },
              mounted() {
                // 通常不需要手动添加事件监听器,因为我们在 render 函数中已经做了这件事  
              },
              beforeDestroy() {
                // 通常不需要手动移除事件监听器,因为 Vue 会自动处理  
              },
            }).$mount(); // 手动挂载实例
          }else if (item.indexOf("ready") > -1) {
            let _valStr="";//变量参数
            if (item.indexOf("readyName")>-1) {
              //案件人姓名
              _valStr=_currentCase?.case_name||"";
            }else if (item.indexOf("readyIdCard")>-1) {
              //身份证
              _valStr=_currentCase?.case_idcard||"";
            }else if (item.indexOf("readyCaseId")>-1) {
              //案号
              _valStr=_currentCase?.case_number||"";
            }else if (item.indexOf("readyPlatform")>-1) {
              //借款平台
              _valStr=_currentCase?.platform||"";
            }else if (item.indexOf("readyUnit")>-1) {
              //调解受理单位
              _valStr=_currentCase?.accept_unit||"";
            }else if (item.indexOf("readyMoney")>-1) {
              //调解金额
              _valStr=_currentCase?.amount||"";
            }else if (item.indexOf("readyReason")>-1) {
              //案由
              _valStr=_currentCase?.reason||"";
            }
            instance = new Vue({
              // el: document.createElement('view'), // 创建一个临时的 div 元素作为挂载点  
              render(h) {
                // 使用 render 函数渲染 Input 组件  
                return h('span', {
                  attrs: {
                    id: item, // 将 id 属性绑定到 Vue 实例的 data 中的 inputId
                  },
                  class: "text_custom_val"
                }, [
                  _valStr||"________________"
                ]);
              },
            }).$mount(); // 手动挂载实例
          }
        }


        // let parent = el.parentNode;
        // 将新创建的实例插入到指令所在的元素之后
        if (instance) {
          el.appendChild(instance.$el);
        }

        // parent.insertBefore(instance.$el, el.nextSibling);

      } else {
      
        if (_editStrArr.some(v=>item.indexOf(v)>-1&&item.indexOf("_")>-1)) {
           el.appendChild(document.createTextNode("________________"));
        }else{
          el.appendChild(document.createTextNode(item));
        }
      }
    });

    // const all_permission = '*:*:*'
    // const permissions = store.getters && store.getters.permisaction
    // // console.log(permissions,"permissions122");
    // // console.log(store.getters);
    // if (value && value instanceof Array && value.length > 0) {
    //   const permissionFlag = value

    //   const hasPermissions = permissions.some(permission => {
    //     return all_permission === permission || permissionFlag.includes(permission)
    //   })

    //   if (!hasPermissions) {
    //     el.parentNode && el.parentNode.removeChild(el)
    //   }
    // } else {
    //   throw new Error(`请设置操作权限标签值`)
    // }
  },
  unbind(el) {
    // 销毁组件实例
    if (el.firstChild && el.firstChild.$destroy) {
      el.firstChild.$destroy();
    }
  }
}

2、index.js

index.js
 import insertDom from "./insertDom";
import Vue from 'vue'

const install=function(Vue){
    Vue.directive('insertDom', insertDom)
}

if (window.Vue) {
    window['insertDom'] = insertDom
    Vue.use(install)
}
insertDom.install=install;
export default insertDom;

3、main.js

import insertDom from "@/utils/insertDom";
Vue.use(insertDom);
4、引用
 

 

posted @ 2024-06-05 11:32  春春&  阅读(87)  评论(0)    收藏  举报