preface

The one-click import function is proposed during user use. The requirements are as follows: Click the import button to display a prompt box, followed by a single box and the upload button. The ELEMent-UI component is often used on the PC side, but this project is an old one for VUe1 and does not have an element-UI component. So you need to do your own radio function and upload function.

Radio properties and methods

  • Name: Used to define radio of the same type. Only one radio of the same name can be selected (single option implementation).
  • Id: Used to associate with the label label so that clicking on the element within the label can also select radio
  • Value: indicates the value of a radio button. Tip: Identifies the selected radio button in the group.
  • Checked is used to set the radio selected by default
  • V-model creates two-way data binding. The initial values of the Value, Checked, and Selected features of all form elements are ignored and the Vue instance data is always used as the data source.
// html
 <div v-for="day in weekSelectList"
    :key="day.id"
    class="select__day">
    <input type="radio"
      name="week"
      :id="day.label"
      :value="day.value"
      v-model="selectedDay">
    <label :for="day.label">{{day.label}}({{day.value}})</label>
  </div>
Copy the code
// Tentative datadata() {return {
  weekSelectList: [
      { label: 'Monday', value: '2018-12', id: 1 },
      { label: 'on Tuesday', value: '2018-13', id: 2 },
      { label: 'on Wednesday', value: '2018-14', id: 3 },
      { label: 'on Thursday, value: '2018-15', id: 4 },
      { label: 'on Friday', value: '2018-16', id: 5 }
    ]
  },
  selectedDay: '2018-12',}Copy the code

By binding selectedDay to v-Model, the radio will be selected when matching the same value. When changing the selection of radio, selectedDay will also dynamically change to the value of the selected radio

Upload a file

attribute

  • The accept attribute accepts a comma-separated string (if multiple values) such as accept=”image/ PNG, image/ JPEG”
  • id
  • name
  • Note: The Accept attribute does not verify the type of the selected file, only the specified file type is displayed when the user browses it

disadvantages

  1. If no file is uploaded, “Not selected file” is displayed. The user interface is unfriendly and cannot be configured
  2. Even if the content of the same file name changes, re-uploading does not trigger the change event
  3. If the user clicks “Cancel” during the upload process, the uploaded files will be removed

The solution

  <div class="upload__button"
    :class="{'upload__button--uploaded':isUploaded}"
    @click="onUploadClick"> Click upload </div> <inputtype="file"
    class="upload__file"
    v-el:upload
    accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
    @change="onFileChange" />
Copy the code
methods:{
  onUploadClick() {
    if(! this.isUploaded) { this.$els.upload.click()
    }
  },
  onFileChange(e) {
  const file = e.target.files[0]
  if (file === undefined) {
    return
  }
  this.fileName = file.name
  const result = /[xls|xlsx]$/.test(this.fileName)
    if (result) {
      this.isUploaded = true
      this.showAlert('Upload successful')
      this.$els.upload.value = null
    } else {
      this.showAlert('File format error, please confirm and try again. ')}}}Copy the code

When the onUploadClick event is triggered by clicking the upload button, Get the DOM of the Upload binding (because the old project uses $els,vue2 uses ref) and manually trigger the click event and can receive a file information object by default in the change event where target.files[0] contains more information about the file, as shown below:

Determine the file type

You can see that the return value of the change event contains the file attributes. Here we need to determine whether the file name is Excel, using the test method of the re.

Reset the change event

This.$refs. uploadfile. value = null; Removing a file ensures that the change event is triggered when the same file is uploaded

Optimization of style

At this point, the functionality of the form has been implemented, because the original Radio style is ugly and cannot be changed. Now let’s figure out how to make it beautiful.

// template
 <label v-for="(item,index) in radioList"
        :key="item.value"
        :for="item.linkLabel"
        :accesskey="index">
        <span class="content__input">
          <span class="radio__replace"
            :class="{'radio__replace--checked':selectedRadio===item.value,'radio__replace--disable':item.isDisabled}">
          </span>
          <input v-model="selectedRadio"
            type="radio"
            class="radio__button"
            name="radio"
            :id="item.linkLabel"
            :tabindex="index"
            :value="item.value"
            :disabled="item.isDisabled"
            @focus="item.isFocus = true"
            @blur="item.isFocus = false" />
        </span>
        <span class="content__text">{{item.label}}</span>
      </label>
Copy the code
// data
  data() {
    return {
      radioList: [
        {
          linkLabel: 'label1',
          value: '1',
          isDisabled: false,
          isFocus: false,
          label: 'label 1'
        },
        {
          linkLabel: 'label2',
          value: '2',
          isDisabled: false,
          isFocus: false,
          label: 'label 2'
        },
        {
          linkLabel: 'label3',
          value: '3',
          isDisabled: true,
          isFocus: false,
          label: 'label 3'
        }
      ],
      selectedRadio: '1'
    }
Copy the code
  1. Here, multiple radios are defined in data by traversal. We have talked about the basic usage of radio before, which is realized by using the for attribute of label and the for attribute of inputassociate. Here I put the input inside the label so that clicking on the entire label will highlight it, with no label and radio elementsclearance).
  2. nameThe same radio will be implementedEffect of radio.tabindexOn behalf of the use ofTraversal order of the "Tab" keyIf value is selected, the selectedRadio bound to the V-Model will change accordingly
  3. Implement personalized styleThe key is structureIt’s just a class namecontent__inputThe tag will be the class nameradio__replaceWrap it up with radio. Set the location hierarchy (i.e. radio is overwritten, but as long as you click on LabelRadio it will be selected)
  4. throughselectedRadioThe selected value is compared to the current radio value and isDisabledBoolean valuetoDynamically bound classImplement our custom Radio style switch

The effect is as follows:

In fact, the label corresponding to the class name of Radio__replace is our custom radio, where the white origin is the CSS code generated by the pseudo class at the end, if you are interested, you can take a look

Pseudo class style modification

If you want to change the style of the white origin by class name, you can change it by weight. Add the test class name to the outer layer using isShow. The initial weight is set to two layers, and then add one layer to change the style. (ps: pseudo-classes cannot be styled by a preset class name.) example code:

 <div :class="{test:isShow}"
      @click="onRedClick">
      <div class="text__item"></div>
    </div>
Copy the code
.text__item {
  &:after {
    content: ' ';
    width: 30px;
    height: 30px;
    background-color: #f00;
    position: absolute;
    bottom: 20px;
  }
}
.test {
  .text__item {
    &:after {
      background-color: #ff0;}}}Copy the code
// css
 .radio {
        &__replace {
          border: 1px solid #dcdfe6;
          border-radius: 100%;
          width: 14px;
          height: 14px;
          background-color: #fff;position: relative; cursor: pointer; display: inline-block; box-sizing: border-box; z-index: 999; The transition: 0.15 s ease - in; &--checked { border-color:#409eff;
            background-color: #409eff;
          }
          &--disable {
            cursor: not-allowed;
          }
          &:after {
            width: 4px;
            height: 4px;
            border-radius: 100%;
            background-color: #fff;
            content: ' '; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } } &__button { opacity: 0; outline: none; position: absolute; z-index: -1; top: 0; left: 0; right: 0; bottom: 0; margin: 0; }}Copy the code

conclusion

  1. This paper introduces the radioBasic attributes, use cases andOptimized the style of radio
  2. Of the original uploaded file elementdisadvantagesAs well asTo improve the method