1. 程式人生 > 實用技巧 >vue——【v-model實現原理】

vue——【v-model實現原理】

1.使用v-model封裝一個自定義元件:inputTableForm.vue

<template>
  <el-form
    label-position="top"
    size="mini"
    :rules="rules"
    :model="form"
  >
    <el-form-item
      prop="name"
      style="margin-bottom:0"
    >
      <el-input
        :disabled="disabled"
        @change="
handleChange" v-model="form.name" /> <template slot="error" slot-scope="scope" > <span style="color:#f56c6c;font-size:12px">{{ scope.error }}</span> </template> </el-form-item> </el-form> </template> <script> import _
from "lodash"; export default { data() { // eslint-disable-next-line let partten = /^[a-zA-Z\$_][a-zA-Z\d_]*$/; let reg = /^t\d+$/; var validateName = (rule, value, callback) => { if (!value) { callback(new Error("請輸入表名")); this.backToOriginName(); } else {
if (value == this.oldValue) { callback(); } else { if (!partten.test(value)) { callback(new Error("表名格式不正確")); this.backToOriginName(); } else if (this.tableData.map(v=>v.tablename==value).length >= 2) { callback(new Error("表名重複")); this.backToOriginName(); } else if (reg.test(value)) { callback(new Error("t+數字是系統預設名稱,不能使用")); this.backToOriginName(); } else { callback(); } } } }; var rules = { name: [ { required: true, message: "請輸入表名", trigger: "change" }, { validator: validateName, trigger: "blur" }, ], }; return { oldValue: "", rules: rules, form: { name: "", }, }; }, props: { value: { type: String, default: "", }, tableData: { type: Array, default() { return []; }, }, }, computed: { disabled() { return false; }, }, created() { this.form.name = this.value; this.oldValue = _.cloneDeep(this.value); // console.log(this.value, 111); }, watch: { value(val) { this.form.name = val; // console.log(val, '監聽更新'); }, // value: { // immediate: true, // handler(val) { // this.form.name = val || ''; // this.oldValue = _.cloneDeep(val || ''); // console.log(val, '監聽更新111'); // } // }, }, methods: { handleChange(val) { this.$emit("input", val); // console.log(val, 222); }, backToOriginName() { setTimeout(() => { this.$emit("input", this.oldValue); // console.log(this.oldValue, 333); }, 1000); }, }, }; </script>

2.引用元件:

<template>
  <div>
    <el-form
      label-position="top"
      :model="forn"
      :rules="rules"
    >
      <el-form-item
        label="接入元件:"
        prop="table"
      >
        <el-table
          :data="inputtable"
          :show-header="false"
          border
        >
          <el-table-column prop="tablename">
            <template slot-scope="scope">
              <inputTableForm
                :table-data="inputtable"
                :key="scope.row.$index"
                v-model="scope.row.tablename"
              />
            </template>
          </el-table-column>
          <el-table-column prop="tablevalueText">
            <template slot-scope="scoped">
              <span>{{ inputtableMatch[scoped.row.tablevalue] }}</span>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
 import inputTableForm from './inputTableForm.vue'
  components: {
      inputTableForm ,
  },
  data () {
    return {
      inputtable:[],
      inputtableMatch:{},
      form:{ table:[]},
      rules: {
        table: [
          { type: 'array', required: true, message: '接入元件不可為空', trigger: 'change' }
        ],
      },
    } 
</script> 

-end-