preface

I just took over an internal background system project of the company. At the beginning, it was really a pit step by step. After working overtime for a week, I basically completed all the commonly used functions and components, and basically relieved myself.

Technology stack: IVEW + VUE + VUE – CLI

Without further ado, here is a summary of some of the problems with encapsulated components

Component encapsulation

  • Implement input SELECT radio checkbox date component encapsulation
1. Because VUE needs a data-driven view, all properties need to be initialized in the page
export default {
    data() {
      return {
        list: [
          {name: 'applicationNo', title: 'Purchase Application No. :'.type: 'input', placeholder: ' '.disable: true, value: '111'},
          {name: 'createUserName', title: 'Applicant :'.type: 'input', value: ' '.disable: true},
          {name: 'organLeaderName', title: 'Head of Organization'.type: 'input', value: ' '.disable: true},
          {name: 'expectTime', title: 'Expected arrival time'.type: 'input', value: ' ', data: [], placeholder: ' '.disable: true},
          {name: 'transportOrganName', title: 'Distribution organization'.type: 'input', value: ' ', placeholder: ' '.disable: true},
          {name: 'receive', title: 'Pickup address'.type: 'input', value: ' '.disable: true},
          {name: 'detailAddress', title: 'Full address'.type: 'input', value: ' ', data: [], col: '12'.disable: true},
          {name: 'contract', title: 'Contacts'.type: 'input', value: ' ', data: [], disable: true},
          {name: 'telphone', title: 'Contact Number'.type: 'input', value: ' ', data: [], disable: true},
          {name: 'remark', title: 'note'.type: 'input', value: ' ', data: [], disable: true, col: '20'}].Copy the code
1.1 Encapsulate components to implement submit button judgments as defined by initializationtypeAccording to thetypeTo determine what the submit button is (e.g. Input, SELECT…)
<template>
  <div class="form-input-group">
    <template v-if="type == 'text'">
      <span class="form-list-text">{{ value }}</span>
    </template>
    <template v-else-if="type == 'input'">
      <Input class="input-item" v-model="inputValue" :placeholder="placeholder" :disabled="disable"></Input>
      <template v-if="detail">
        <span class="input-detail">{{detail}}</span>
      </template>
    </template>
    <template v-else-if="type == 'select'">
      <Select class="input-item" v-model="inputValue" :placeholder="placeholder" :disabled="disable">
        <Option v-for="item in selectData" :value="item" :key="item.value">{{item }}</Option>
      </Select>
    </template>
    <template v-else-if="type == 'date'">
      <DatePicker type="date" :placeholder="placeholder" @on-change="setDate" :disabled="disable"></DatePicker>
    </template>
    <template v-else-if="type == 'city'">
      <city-select :value="value" @setCity="SetCity"></city-select>
    </template>
    <template v-else-if="type == 'model'">
      <Input class="input-model-hidden" v-model="modelValue.code"></Input>
      <Input class="input-item input-model" :placeholder="modelValue.name" readonly></Input>
      <div class="input-shadow" @click="showModel = true"></div>
    </template>
    <template v-else-if="type == 'cars'">
      <car-select :value="value" @setCar="SetCar"></car-select>
    </template>
    <FormModel v-if="showModel" @closeModel="closeModel" @confirmModel="confirmModel"></FormModel> </div> </template>type: Input box type, name: attribute name to bind, data: drop-down menu or cascading menu data] *typeValue: [text: normal text, input: normal input box, select: drop-down box, date: city: province, cascader: cascading menu] * Accept method: [getValue: obtain attribute name and return value] * Return value: {name: Name, value: value} * Cascading menu Returned value: {name: name, value: [value1, value2]} * Example: <input-group V-bind ="propsData"></input-group>
   */
Copy the code

We can’t just pass the type value in the parent component to determine the submit button type. We also need to pass the value to the child component to display when viewing the order and cannot change it, and set the Disabled property to be uneditable. Other attributes (eg: placeholder, disable, name) need to be passed as well

1.2 Thus two things need to be done in the parent and child components
 <Row class="form-list-search">
      <Col :span="item.col ? item.col : '6'" v-for="(item,index) in list" :key="index">
      <span class="form-list-title">{{item.title}}</span>
      <input-group v-bind="item" @setCarCode="setCarCode" @setValue="setValue"></input-group>
      </Col>
    </Row>
Copy the code

Pass attribute values using V-bind =”item”. So how do you receive under the Input component? Look at the code

// input.vue
 export default {
    data() {
      return {
        inputValue: ' ',
        selectData: [],
        modelValue: {},
        showModel: false,
        dateData: ' '
      }
    },
    props: {
      data: {
        default: ' '
      },
      value: {
        default: ' '
      },
      type: {
        required: true
      },
      name: {
        required: true
      },
      disable: {
        type: Boolean
      },
      detail: {
        default: ' '
      },
      placeholder: String,
      index: Number
    },
    components: {
      CitySelect,
      FormModel,
      CarSelect
    }
Copy the code
1.3 When the child component changes, we need to listen in the componentvalueChanges the view and passes the value to the parent component.$emit()
    created() {
      this.inputValue = this.value
      this.selectData = this.data
      this.inputkey = this.key
    },
    methods: {
      setDate(date) {
        this.inputValue = date
        // this.dateData = date
        // let returnData = {name: this.name, value: this.dateData}
        // this.$emit('dateData'.returnData)
      },
      SetCity(val) {
        let returnData = {name: this.name, value: val}
        this.$emit('setCityCode'.returnData)
      },
      SetCar(val) {
        console.log(val, 'input.vue')
        this.$emit('setCarCode', val)
      },
      confirmModel(data) {
        if (data) {
          this.showModel = false
          this.modelValue = data
        }
      },
      closeModel(data) {
        if (data) {
          this.showModel = false
        }
      }
    },
    watch: {
      value(val) {
        this.inputValue = val
      },
      data(val) {
        this.selectData = val
      },
      inputValue(val) {
        // console.log(val)
        let returnData = {name: this.name, value: val}
        if(this.index ! = undefined) {returnData.index = this.index
        }
        if (this.type == 'date') {
          returnData.value = Util.unixTime(val)
        }
        this.$emit('setValue'.returnData)
      }
    }
  }
Copy the code
1.4 Three-level Linkage Components

General train of thought

  • Cascader cascade selection with iView component, dynamic loading, if there is a next level menu, defined inside the objectchildren[]And push the new secondary object structure,loading: falseThe next level is calledloadDatamethods
<template>
  <div>
    <Cascader :data="cascaderData" :load-data="loadData" v-model="cascader" @on-change="setValue"></Cascader>
  </div>
</template>
<script>
  import Util from '.. /.. /libs/util.js'
  import {getBrand, getSeriesList, getModelList} from '.. /.. /api/index'

  export default {
    data() {
      return {
        cascaderData: [],
        cascader: []
      }
    },
    async mounted() {// Returns level 1 menu dataletBrandList = await getBrand() // Render view Util.CommonCascader(this, brandlist.result, this.cascaderdata)},created() {
    },
    methods: {
      loadData(item, callback) {
        item.loading = trueThen ((res) => {Util.CascaderChild(this, res.result, item.children,'name'.'code')
          callback()
          item.loading = false}).then(() => { Pass id getModelList(item.value). Then ((res) => {Util.CascaderChild(this, res.result, item.children,'name'.'code'.true)
            callback()
            item.loading = false})})},setValue(val) {
        this.$emit('setCar', val)
      }
    },
    watch: {
      value(val) {
        this.cascader = val
      }
    },
    components: {}
  }
</script>
<style scoped>
</style>

Copy the code