title: vue.js + element-ui form validation rules in dialog
body: <p>I'm using vue.js(4.3.1) and element-ui.
  I would like to define the validation rules of my form in dialog.</p>
  
  <p><strong>eg:</strong></p>
  
  <p><a href="https://codepen.io/xmcx/pen/XWmMXKp" rel="nofollow noreferrer">https://codepen.io/xmcx/pen/XWmMXKp</a></p>
  
  <p><strong>Code</strong></p>
  
  <pre><code>&lt;script src="//unpkg.com/vue/dist/vue.js"&gt;&lt;/script&gt;
  &lt;script src="//unpkg.com/element-ui@2.13.1/lib/index.js"&gt;&lt;/script&gt;
  &lt;div id="app"&gt;
      &lt;template&gt;
          &lt;div&gt;
              &lt;div class="top-5"&gt;
                  &lt;el-row&gt;
                      &lt;el-button class="search-btn" type="primary" @click="initOperationData({},'new')"&gt;New&lt;/el-button&gt;
                  &lt;/el-row&gt;
              &lt;/div&gt;
              &lt;div id="dt" class="top-5"&gt;
                  &lt;el-table :data="dataList" stripe border highlight-current-row show-overflow-tooltip&gt;
                      &lt;el-table-column label="Name" prop="name" header-align="center" align="center"&gt;&lt;/el-table-column&gt;
                      &lt;el-table-column label="Age" prop="age" header-align="center" align="center"&gt;&lt;/el-table-column&gt;
                      &lt;el-table-column label="Gender" prop="gender" header-align="center" align="center"&gt;
                          &lt;template slot-scope="scope"&gt;{{genderConverter(scope.row.gender)}}&lt;/template&gt;
                      &lt;/el-table-column&gt;
                      &lt;el-table-column label="State" prop="state" header-align="center" align="center"&gt;
                          &lt;template slot-scope="scope"&gt;{{stateConverter(scope.row.state)}}&lt;/template&gt;
                      &lt;/el-table-column&gt;
                      &lt;el-table-column label="Operation" width="144px" fixed="right" header-align="center" align="center"&gt;
                          &lt;template slot-scope="scope"&gt;
                              &lt;el-row&gt;
                                  &lt;el-button @click="initOperationData(scope.row, 'edit')" type="text" size="small"&gt;Edit
                &lt;/el-button&gt;
                              &lt;/el-row&gt;
                          &lt;/template&gt;
                      &lt;/el-table-column&gt;
                  &lt;/el-table&gt;
              &lt;/div&gt;
              &lt;div class="dialog"&gt;
                  &lt;el-dialog :title="operationConverter(operation) + 'User'" :visible.sync="operationDialogVisible"
                   width="400px" modal :close-on-press-escape="false" :close-on-click-modal="false"
                   @closed="dialogClosed('operationData')"&gt;
                      &lt;el-form :model="operationData" ref="operationData" :rules="rules" label-width="80px"&gt;
                          &lt;el-form-item label="Name" prop="name"&gt;
                              &lt;el-input v-model="operationData.name" placeholder="please enter name" clearable/&gt;
                          &lt;/el-form-item&gt;
                          &lt;el-form-item label="Age" prop="age"&gt;
                              &lt;el-input v-model="operationData.age" placeholder="please enter age" clearable/&gt;
                          &lt;/el-form-item&gt;
                          &lt;el-form-item label="Gender" prop="gender"&gt;
                              &lt;el-select v-model="operationData.gender" placeholder="please choice gender" filterable clearable&gt;
                                  &lt;el-option v-for="item in genderList" :key="item.value" :label="item.label"
                           :value="item.value"/&gt;
                              &lt;/el-select&gt;
                          &lt;/el-form-item&gt;
                          &lt;el-form-item label="State" prop="state"&gt;
                              &lt;el-select v-model="operationData.state" placeholder="please choice state" filterable clearable&gt;
                                  &lt;el-option v-for="item in stateList" :key="item.value" :label="item.label"
                           :value="item.value"/&gt;
                              &lt;/el-select&gt;
                          &lt;/el-form-item&gt;
                      &lt;/el-form&gt;
                      &lt;span slot="footer" class="dialog-footer"&gt;
                          &lt;el-button type="primary" @click="save('operationData')"&gt;Save&lt;/el-button&gt;
                          &lt;el-button @click="operationDialogVisible = false"&gt;Close&lt;/el-button&gt;
                      &lt;/span&gt;
                  &lt;/el-dialog&gt;
              &lt;/div&gt;
          &lt;/div&gt;
      &lt;/template&gt;
  &lt;/div&gt;
  
  var Main = {
    data () {
      return {
        operationList: Object.freeze([
          {value: 'new', label: 'New'},
          {value: 'edit', label: 'Edit'}
        ]),
        stateList: Object.freeze([
          {value: 'enabled', label: 'Enabled'},
          {value: 'disabled', label: 'Disabled'}
        ]),
        genderList: Object.freeze([
          {value: 'male', label: 'Male'},
          {value: 'female', label: 'Female'}
        ]),
        dataList: [
          {name: 'Peter', age: undefined, state: 'enabled', gender: 'male'},
          {name: 'Rocky', age: null, state: 'enabled', gender: 'male'},
          {name: 'Bill', state: 'enabled', gender: 'male'},
          {name: 'Alice', state: undefined, age: 12, gender: 'female'},
          {name: 'Amy', state: null, age: 12, gender: 'female'},
          {name: 'Lucy', age: 12, gender: 'female'}
        ],
        total: 2,
        operationData: {},
        operation: null,
        operationDialogVisible: false,
        rules: {
          name: [
            {required: true, message: 'Name is required', trigger: 'change'},
            {required: true, message: 'Name is required', trigger: 'clear'}
          ],
          age: [
            {required: true, message: 'Age is required', trigger: 'change'},
            {required: true, message: 'Age is required', trigger: 'clear'}
          ],
          state: [
            {required: true, message: 'State is required', trigger: 'change'},
            {required: true, message: 'State is required', trigger: 'clear'}
          ],
          gender: [
            {required: true, message: 'Gender is required', trigger: 'change'},
            {required: true, message: 'Gender is required', trigger: 'clear'}
          ]
        }
      }
    },
    methods: {
      initOperationData (data, operation) {
        this.operationData = JSON.parse(JSON.stringify(data))
        this.operation = operation
        this.operationDialogVisible = true
      },
      save (formName) {
        this.$refs[formName].validate((valid) =&gt; {
          if (!valid) {
            return false
          } else {
            this.$message({showClose: true, message: 'Save success', type: 'success'})
          }
        })
      },
      dialogClosed (formName) {
        this.operation = null
        this.resetFields(formName)
      },
      resetFields (formName) {
        this.$refs[formName].resetFields()
      },
      operationConverter (value) {
        for (let item of this.operationList) {
          if (value === item.value) return item.label
        }
        return null
      },
      stateConverter (value) {
        for (let item of this.stateList) {
          if (value === item.value) return item.label
        }
        return null
      },
      genderConverter (value) {
        for (let item of this.genderList) {
          if (value === item.value) return item.label
        }
        return null
      }
    }
      }
  var Ctor = Vue.extend(Main)
  new Ctor().$mount('#app')
  </code></pre>
  
  <p><strong>Problem</strong></p>
  
  <p>If I operate in the following order, there will be verification failure message in the dialog(I hope it will not appear):</p>
  
  <p>order-1: Edit -> Close -> New(or edit) ...</p>
  
  <p>If I operate in the following order, it's ok:</p>
  
  <p>order-2: New -> Close -> New(or edit) ...</p>
  
  <p><strong>Note</strong></p>
  
  <p>Before operating in the order of order-1 or order-2, please refresh the page.</p>