封装双击编辑组件,包含input(单行,多行),select(单选,多选),date(日期间隔,单个日期)

组件代码

思想就是根据父组件传值的type属性来显示不同的功能

<template>
   <div>
       <span v-show="!show" @dblclick="dblclick"  :style="`display:inline-block;width:${width};height:23px;`">{{arryToString(data)}}</span>
       <!-- 输入框 -->
       <el-input v-if="type==='input'&&show"  v-model.trim="data" :size="size" :clearable="clearable" ref='ipt' @blur="valueChange"></el-input>
       <!-- 多行文本输入 -->
       <el-input v-if="type==='textarea'&&show" type="textarea"  v-model.trim="data"  :size="size" :rows="rows" ref='ipt' @blur="valueChange"></el-input>
       <!-- 下拉选择器 -->
       <el-select v-if="type==='select'&&show"  v-model="data"  ref='slt' :size="size"   @visible-change="visibility($event)" :filterable="filterable"  :multiple="multiple" @change="valueChange">
           <el-option v-for="(e,i) in options" :key="i" :label="e.label" :value="e.value"></el-option>
       </el-select>
      <!-- 日期时间间隔选择器-->
      <el-date-picker v-if="type==='datetimerange'&&show" :size="size" v-model="data" value-format="yyyy-MM-dd HH:mm:ss" ref='ipt' type="datetimerange" :picker-options="pickerOptions" range-separator="至" start-placeholder="开始日期"  end-placeholder="结束日期" align="right"  @blur="valueChange"></el-date-picker>
      <!-- 日期选择器 -->
      <el-date-picker v-if="type==='date'&&show" ref='ipt' :size="size" v-model="data" value-format="yyyy-MM-dd HH:mm:ss" type="date" placeholder="选择日期"  @blur="valueChange"></el-date-picker>
   </div>
</template>

<script>
let that;
export default {
 props:{
     type:{
        type:String,
        default:""
     },
     value:{
         type:[String,Array],
         default:""
     },
     options:{
         type:Array,
         default:()=>[]
     },
     filterable:{
         type:Boolean,
         default:false
     },
     multiple:{
         type:Boolean,
         default:false
     },
     width:{
         type:String,
         default:"100%"
     },
     rows:{
         type:Number,
         default:2
     },
     size:{
         type:String,
         default:"mini",
     },
    clearable:{
          type:Boolean,
          default:true
    },
    hookFunction:{//父组件中传入的判断,用做双击编辑时候的判断,有时候可能当前的角色不允许他进行编辑,这时候就需要传入一个判断条件来判断,可以是一个boolean类型的值,或者直接把判断的逻辑传进去。
        type:[Function,Boolean],
        default:true
    }
 },
 data(){
     return{
        data:"",
        show:false,
        selectOptions:[],
        pickerOptions:[]
     }
 },
 beforeCreate(){
     that=this;
 },
 created(){
     if(Array.isArray(this.value)){
        this.data=this.value;
        // console.log(this.value,2222)
     }else if(this.type=='select'&&this.multiple){
        this.data=this.value.split(',');
        this.selectOptions=JSON.parse(JSON.stringify(this.options));
        // console.log(this.data,666)
     }else if(this.type=='input'||this.type=="textarea") {
        this.data=this.value;
     }else if(this.type=='select'&&!this.multiple){
         this.data=this.value;
     }
 },
 methods:{
    arryToString(e){
        if(this.type=="input"||this.type=="textarea"&&Object.prototype.toString.call(e)=="[object String]"){
            return e;
        }else if(this.type=="select"&&this.multiple&&Array.isArray(e)){
            const arr=[];
               e.forEach(item => {
                  this.options.forEach(val=>{
                       if(val.value==item){
                           arr.push(val.label);
                       }
                   })
               });
              return arr.join();
        }else if(this.type=="select"){
          if(e) return this.options.filter(item=>{return e==item.value;})[0].label;
        }else if(this.type=="datetimerange"){
           if(e) return e.join('-');
        }else if(this.type=="date"){
            return e;
        }
    },
    dblclick(){
        if(this.hookFunction){
            this.show=true;
            this.$nextTick(()=>{
               if(this.type=="select") this.$refs.slt.$el.click();
               else  this.$refs.ipt.focus();
            })
        }
    },
    valueChange(){
       let newValue;
       if(this.type=='select'&&this.multiple) newValue=this.data.join(",");
       if(this.data!==this.value) {
        //    console.log(this.data,this.value,8888888)
           this.$emit("update:value",this.data);
           if(this.type=='select'&&this.multiple) this.$emit("updateValue");
           else this.$emit("updateValue");
       }
       if(!this.multiple) this.show=false;
    },
    visibility(e){
       if(!e) this.show=false;
    }
 }
}
</script>

<style>

</style>

父组件中使用

<template>
  <div>
    <h1>常用组件</h1>
    <el-col :span="12">
      <p>
        <span>input框的</span>
        <Editspan
          type="input"
          :value.sync="uu"
          @updateValue="updateValue(uu)"
        />
      </p>
      <p>
        <span>input框多行文本编辑的</span>
        <Editspan
          type="textarea"
          :value.sync="uu"
          :rows="6"
          @updateValue="updateValue(uu)"
        />
      </p>
      <p>
        <span>select选择器(多选)</span>
        <Editspan
          type="select"
          :options="options"
          :value.sync="ss"
          :multiple="true"
          :filterable="true"
          @updateValue="updateValue(ss)"
        />
      </p>
     

      <p>
        <span>select选择器(单选)</span>
        <Editspan
          type="select"
          :options="options"
          :value.sync="ss"
          @updateValue="updateValue(ss)"
        />
      </p>
      <p>
        <span>日期间隔选择器</span>
        <Editspan
          type="datetimerange"
          :value.sync="date"
          @updateValue="updateValue(date)"
        />
      </p>
      <p>
        <span>日期选择器</span>
        <Editspan
          type="date"
          :value.sync="date"
          @updateValue="updateValue(date)"
        />
      </p>
    </el-col>
  </div>
</template>

<script>
import Editspan from "@/components/pageComponents/Editspan";
export default {
  components: {
    Editspan,
  },
  data() {
    return {
      uu: "2",
      ss: "3,2",
      options: [
        { label: "niaho", value: "1" },
        { label: "222", value: "2" },
        { label: "333", value: "3" },
        { label: "444", value: "4" },
        { label: "5555", value: "5" },
      ],
      nihao: "",
      date: "2020-10-10",
    };
  },
  methods: {
    btn() {
      console.log(this.uu, this.ss, 888888);
      this.$refs.slt.focus();
    },
    updateValue(e) {
      console.log(e, "更新之后的值");
      //写更新的操作
    },
  },
};
</script>

<style>
</style>

封装的插件的传值方式根据我在项目中常用的方式,日期格式和多选分别用的横杠和逗号间隔,可二次改造,使用的时候在父组件中传一个:key="传下去的value值"这样每次,使用updatevalue的时候就会刷新,传到子组件的值也就是最新的了,如果不加的话,缓存在判断当前值和更新之前的值是否一样的时候,可能会存在偏差(在el-table中使用的时候会刷新会用问题,单独使用可能没有这个问题)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值