组件代码
思想就是根据父组件传值的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中使用的时候会刷新会用问题,单独使用可能没有这个问题)。