Vue uses element-ui upload, input input box, single-select multiple-select button and other components

1. Introduce element-ui --- checkbox + upload + input box

// element-ui
import {Checkbox, Input, Upload, CheckboxGroup } from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.component( 'checkbox', Checkbox );
Vue.component( 'el-input', Input);
Vue.component( 'upload', Upload );
Vue.component( 'CheckboxGroup');

[Upload component] 

​
<template>
    <div>
        <!--上传头像 type:img-->
        <template  v-if="type == 'img'">
            <el-upload
                    class="upload-demo"
                    action="111"
                    :limit="limit"
                    :file-list="fileList"
                    :show-file-list=showFileList
                    :before-upload="beforeUpload"
                    :on-remove="handleRemove"
                    accept = "image/png,image/jpg,image/jpeg,image/gif">
                <button class="dc-common-default-btn">
                    <img src="../assets/img/common/upload-icon.png" alt="">
                    <span>{
   
   {placeholder}}</span>
                </button>
                <div class="el-upload__tip" slot="tip">{
   
   {tip}}</div>
            </el-upload>
        </template>
        <!--上传文件 type:file-->
        <template  v-else-if="type == 'file'">
            <el-upload
                    class="upload-demo"
                    action="111"
                    :limit="limit"
                    :show-file-list=showFileList
                    :file-list="fileList"
                    :before-upload="beforeUpload"
                    :on-remove="handleRemove"
                    accept = "application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,application/vnd.ms-powerpoint,text/plain">
                <!--accept = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/pdf,application/vnd.ms-powerpoint,text/plain,application/vnd.ms-works">-->
                <button class="dc-common-default-btn">
                    <img src="../assets/img/common/upload-icon.png" alt="">
                    <span>{
   
   {placeholder}}</span>
                </button>
                <div class="el-upload__tip" slot="tip">{
   
   {tip}}</div>
            </el-upload>
        </template>
    </div>
</template>

​

accept: Restrict the uploaded file format

action="111": The uploaded interface address can be written here, but because writing directly here in the project will cause cross-domain problems, so my interface is written in

 

[Related method]:

1.beforeUpload in the method before uploading. It is judged here whether to obtain the data, and then the interface is uploaded. After the image is uploaded, the preview image is displayed.

2.handleRemove Click the delete method to delete the selected data from showList.

public beforeUpload(val): any {
    this.checkImg = true;
    const me = this;
    if ((this as any).type === 'file') { // 上传简历
        const isLt10M = val.size / 1024 / 1024 < 10;
        if (!isLt10M) {
            // this.$message.error('上传头像图片大小不能超过 10MB!');
        }
        const form = new FormData();
        form.append( 'file' , val);
        (this as any).$api.uploadResume(form).then( (resp) => {
            (this as any).$commonFun.axiosSuccessFun( {
                callBack: ( response ) => {
                    const res = response.data;
                    res.name = val.name;
                    const data = {
                        name: res.name,
                        url: res.fullPath,
                    };
                    this.fileList.push(data);
                    this.$emit('before-upload', res, (me as any).str);
                },
                this: me,
            }, resp.data);
        } ).catch( ( error ) => {
            ( this as any ).$commonFun.axiosFailFun( {
                this: me,
            }, error );
        });
    } else { // 上传图片
        this.imageUrl = URL.createObjectURL(val);
        this.imageDefaultUrlData = URL.createObjectURL(val);
        const form = new FormData();
        form.append( 'file' , val);
        (this as any).$api.uploadImage(( this as any).$commonFun.deleteEmpty(form)).then( (resp) => {
            (this as any).$commonFun.axiosSuccessFun( {
                callBack: ( response ) => {
                    const res = response.data;
                    const data = {
                        name: res.fileName,
                        url: res.fullPath,
                    };
                    this.fileList.push(data);
                    this.$emit('before-upload', res, (me as any).str);
                },
                this: me,
            }, resp.data);
        } ).catch( ( error ) => {
            ( this as any ).$commonFun.axiosFailFun( {
                this: me,
            }, error );
        });
    }
    return false;  // 屏蔽了action的默认上传
}

// 点击删除方法之后将选择的数据中showList中删除。
public handleRemove(value): any {
    const me = this;
    if (value.status !== 'ready') {
        // this.fileList = [];
        this.fileList.forEach( (item, i) => {
            if (this.fileList[i].uid === value.uid) {
                this.fileList.splice (i, 1);
            }
        });

    }
    me.$emit('on-remove', value, (me as any).str);
}

【input】:

1. The input box will be filled automatically. In order to cancel the status

Write a default input first: <input type="text" autocomplete="off" style="display: none">

Then write attributes in the component: readonly; οnfοcus="this.removeAttrbute('readonly')"

2.Textarea type:

Because textarea can't set the height by width and height. You can only use the row row attribute to calculate how many rows.

3.maxlength, minlength limit the maximum and minimum input words

4.handleBlur: a method to check the validity of the input value after input

<template>
    <div class="dc-input-wrapper">
        <template v-if="type !== 'textarea'">
            <input type="text" autocomplete="off" style="display: none">
            <el-input
                    class="input-area"
                    :type="type"
                    readonly
                    onfocus="this.removeAttribute('readonly');"
                    :placeholder="placeholder"
                    :maxlength="maxlength"
                    :minlength="minlength"
                    :require="require"
                    ref="input"
                    :autofocus="autofocus"
                    v-model="inputValue"
                    :style="{width:width,height:height}"
                    @focus="handleFocus"
                    @blur="handleBlur"
                    @input="handleInput">
                <img v-if="iconType" :src="iconSrcData" slot="prefix" class="el-input__icon img" alt="">
            </el-input>
            <p class="error-msg" v-if="showTips" ref="error">{
   
   {tipMsg}}</p>
        </template>
        <template v-else>
            <div class="area-box" :style="{width:width,height:textHeight}">
                <el-input
                        class="input-area"
                        type="textarea"
                        readonly
                        onfocus="this.removeAttribute('readonly');"
                        :placeholder="placeholder"
                        v-model="inputValue"
                        :maxlength="maxlength"
                        :minlength="minlength"
                        :rows="rows"
                        @focus="handleFocus"
                        @blur="handleBlur"
                        @input="handleInput">
                </el-input>
                <span class="input-suggest" v-if="maxlength">{
   
   {inputLength}}/{
   
   {maxlength}}</span>
                <p class="error error-msg" ref="error" v-if="showTips&&tipMsg!=''">{
   
   {tipMsg}}</p>
            </div>
        </template>

    </div>
</template>
<script lang="ts">
    import Vue from 'vue';
    import Component from 'vue-class-component';
    import { Input } from 'element-ui';
    @Component({
        components: {
            'el-input': Input,
        },
        props: {
            type: {
                default: 'input',
                type: String,
            },
            placeholder: {
                default: '请输入',
                type: String,
            },
            inputType: {
                default : '',
                type: String,
            },
            require: {
                default : true,
                type: Boolean,
            },
            maxlength: String,
            minlength: {
                default : '0',
                type: String,
            },
            msg: String,
            value: String,
            width: String,
            height: String,
            validated: String,
            iconType: {
                default: '',
                type: String,
            },
            className: String,
            number: Boolean,
            autofocus: Boolean,
            validType: {
                default: 'string',
                type: String,
            },
            rows: String,
            str: String,
        },
    })
    export default class DcInput extends Vue {
        public inputLength: string  = '0';
        public inputValue: any = (this as any).value || '';
        // public textHeight: string = (parseInt((this as any).height , 10) + 12) + 'px';
        public textHeight: string = ((this as any).rows * 20 + 12) + 'px';
        public iconType: any;
        public iconSrcData: any = (this.iconType ?
            require('../assets/img/user/login_alert/' + this.iconType + '_icon.png') :
            '');
        public showTips: boolean = false;
        public tipMsg: string = '';

        public handleKeyDown(): void {
            this.$emit('handleKeyDown');
        }

        public handleKeyUp(e): void {
            this.$emit('handleKeyUp', e);
        }

        public handleBlur(): void {
            if ((this as any).require) {
                if (!this.inputValue) {
                    this.showTips = true;
                    this.tipMsg = (this as any).msg ? '请输入' + (this as any).msg : '请输入';
                } else {
                    switch ( (this as any).validType) {
                        case 'number':
                            if (this.inputValue.length > (this as any).maxlength
                                || this.inputValue.length < (this as any).minlength) {
                                this.showTips = true;
                                if ((this as any).minlength && (this as any).maxlength) {
                                    this.tipMsg = '请输入' + (this as any).minlength + '-'
                                        + (this as any).maxlength + '位' + (this as any).msg;
                                } else if (!(this as any).minlength && (this as any).maxlength) {
                                    this.tipMsg = '请输入不超过' + (this as any).maxlength + '位' + (this as any).msg;
                                } else {
                                    this.tipMsg = '请输入正确的' + (this as any).msg;
                                }
                            }
                            break;
                        case 'phone':
                            const telephoneExc = /^1[3|5|7|8|][0-9]{9}$/;
                            if (!telephoneExc.test(this.inputValue)) {
                                this.showTips = true;
                                this.tipMsg = '请输入正确的' + (this as any).msg;
                            }
                            break;
                        case 'email':
                            const emailExc = /^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/ ;
                            if (!emailExc.test(this.inputValue)) {
                                this.showTips = true;
                                this.tipMsg = '请输入正确的' + (this as any).msg;
                            }
                            break;
                        default:
                            break;
                    }
                }
            }
            this.iconSrcData = (this.iconType ?
                require('../assets/img/user/login_alert/' + this.iconType + '_icon.png') :
                '');
            this.$emit('handleBlur');
        }

        public handleInput(): void {
            const me = this;
            if ((me as any).inputType === 'integer') {
                me.inputValue = me.inputValue.replace(/^(0+)|[^\d]+/g, '');
            }
            me.inputLength = me.inputValue.length;
            me.inputValue = me.inputValue.replace(/(^\s*)|(\s*$)/g, '');
            this.$emit('handleInput', me.inputValue, (me as any).str);
        }

        public handleChange(): void {
            this.$emit('handleChange');
        }

        public handleFocus(): void {
            this.showTips = false;
            this.iconSrcData = (this.iconType ?
                require('../assets/img/user/login_alert/' + this.iconType + '_icon_active.png') :
                '');
            this.$emit('handleFocus');
        }

        public mounted() {
            this.inputValue = (this as any).value || '';
            this.inputLength = this.inputValue.length;
        }
    }
</script>
<style scoped lang="scss">
  .dc-input-wrapper {
    display: inline-block;
    content: '';
    box-sizing: border-box;
    position: relative;
    float: left;
  }

  .textarea {
    display: inline-block;
    position: relative;
    font-size: 14px;
  }

  textarea {
    border: 1px solid #bdc1cb;
    color: #4a596d;
    transition: all 0.4s;
    outline: none;
    resize: none;
    width: 100%;
    height: 95px;
    padding: 5px;
  }

  textarea:focus {
    border: 1px solid #3aa3ff;
  }

  .num-tip {
    color: #d7dbe7;
    font-size: 12px;
    position: absolute;
    right: 20px;
    top: 70px;
  }

  .img {
    position: absolute;
    width: 42px;
    height: 42px;
    top: 1px;
    left: 1px;
  }

  input {
    border: 1px solid #E3E7ED;
    transition: all 0.4s;
    box-sizing: border-box;
    outline: none;
    resize: none;
    width: 220px;
    height: 44px;
    padding: 0 13px 0 42px;
    font-size: 14px;
    color: #414A60;
  }

  .input-focus:focus {
    border: 1px solid #4C88FF !important;
  }

  i {
    /*background: url(/DCTrain/static/img/user/common/input-enter.png) no-repeat -10px -30px;*/
    display: inline-block;
    width: 14px;
    height: 14px;
    position: absolute;
    right: 5px;
    top: 10px;
    cursor: pointer;
  }

  i:hover {
    background-position: -8px -6px;
  }

  p.error {
    color: #FC784A;
    text-align: left;
    line-height: 18px;
    position: relative;
    padding-left: 19px;
    font-size: 14px;
    margin-top: 2px;
  }

  .search {
    width: 30px;
    height: 40px;
    right: 0;
    top: 0;
    background-position: -7px -86px;
  }

  .search:hover {
    background-position: -7px -49px;
  }

</style>
<style lang="scss">
  .input-area{
    .el-input__inner{
      height: 44px;
      line-height: 44px;
    }
    .el-input__prefix{
      left: 0;
    }
    .el-input__icon{
      display: block;
    }
  }
  .input-area.el-input--prefix .el-input__inner{
    padding-left: 42px;
  }
  textarea {
    resize: none;
    border-radius: 0;
  }
  .el-textarea__inner{
    resize: none;
    border-radius: 0;
    line-height: 20px;
  }
  .area-box{
    position: relative;
    .input-suggest{
      width: auto;
      position: absolute;
      bottom: 10px;
      right: 10px;
      font-size: 14px;
      color: #D2D6DE;
    }
  }

</style>

 [Checkbox--check box]

// 全选
<dc-checkbox v-model="checkAll" @change="handleCheckAllChange"></dc-checkbox>

// 单选
<checkbox-group v-model="checkArray" @change="handleChecked">
    <dc-checkbox :label="item"></dc-checkbox>
 </checkbox-group>


// 方法
public checkArray: any = []; // 选中数组
public checkAll: boolean = false; // 全选
public listArray: any = []; // 列表数据

// 全选
public handleCheckAllChange(val) {
  this.checkArray = val ? this.companyList : [];
}
// 单选
public handleChecked(val) {
  const checkedCount = val.length;
  this.checkAll = checkedCount === this.listArray.length;
}

 

Guess you like

Origin blog.csdn.net/qq_42269433/article/details/90177779