There are seven or eight buttons in the Vue parent component, each of which manipulates a dialog, how to split the step-by-step form in dialog and dialog into individual components

problem description

I try to split dialog into individual components, but properties already defined by data in subcomponents will still report an error

clipboard.png

the environmental background of the problems and what methods you have tried

try to use vuex, but you may not be in the right posture. These dialog services are complex. The dialog button in this menu column can evoke the dialog display in another menu and display dialog after opening the route

.

related codes

/ / Please paste the code text below (do not replace the code with pictures)
< template >


< el-tabs vMui model = "activeName" >

<el-tab-pane label="" name="socalInfo" :disabled="tabActive1">
  <el-form label-position="top" class="demo-table-expand" :rules="rules"  :model="socalInfo">
    <!-- <el-row :gutter="10">
      <el-col :span="16">
        <el-form-item label="" prop="name">
          <el-input v-model="socalInfo.name"></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item label="" prop="status">
          <el-select v-model="socalInfo.status" placeholder="">
            <el-option v-for="(item,index) in spaceData" :key="index" :label="item.label" :value="item.value"></el-option>
          </el-select>
        </el-form-item>
      </el-col>
    </el-row> -->
    <!-- <el-row :gutter="10">
      <el-col :span="24">
        <el-form-item label="" prop="address">
          <el-col :span="24">
            <el-cascader size="large" :options="AreaOptions" expand-trigger="hover" v-model="socalInfo.address" @change="handleChange">
            </el-cascader>
          </el-col>
        </el-form-item>
        <el-form-item label="" prop="mapPoint" style="margin-top:15px;">
          <el-col :span="24">
            <el-input v-model="socalInfo.mapPoint" placeholder="">
              <i slot="suffix" class="ion-location mapControl" @click="clickMap"><span></span></i>
            </el-input>
          </el-col>
        </el-form-item>
      </el-col>
    </el-row> -->
    <!--  -->
    <!-- <el-dialog width="573px" title="" :visible.sync="innerVisible" append-to-body>
      <el-row>
        <div class="amap-page-container">
          <el-amap-search-box class="search-box" v-model="address" :search-option="searchOption" :on-search-result="onSearchResult"></el-amap-search-box>
          <el-amap vid="amapDialog" :plugin="plugins" :zoom="zoom" :center="center" :events="events">
            <el-amap-marker :position="marker.position" :events="marker.events" :visible="marker.visible" :draggable="marker.draggable"></el-amap-marker>
          </el-amap>
        </div>
      </el-row>
      <span slot="footer" class="dialog-footer">
        <el-button @click="innerVisible = false"> </el-button>
        <el-button type="primary" @click="submit"> </el-button>
    </span>
    </el-dialog> -->
    <!--  -->
    <!-- <el-row :gutter="10">
      <el-col :span="8">
        <el-form-item label="" prop="build">
          <el-input v-model="socalInfo.build"></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item label="" prop="hight">
          <el-input v-model="socalInfo.hight" type="number"></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item label="" prop="floor">
          <el-input v-model="socalInfo.floor" type="number"></el-input>
        </el-form-item>
      </el-col>
    </el-row> -->

    <!-- <el-row :gutter="10">
      <el-col :span="8">
        <el-form-item label="" prop="mianji">
          <el-input v-model="socalInfo.mianji" type="number"></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item label="" prop="dianti">
          <el-input v-model="socalInfo.dianti" type="number"></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item label="" prop="gongwei">
          <el-input v-model="socalInfo.gongwei" type="number"></el-input>
        </el-form-item>
      </el-col>
    </el-row>
    <el-row :gutter="10">
      <el-col :span="8">
        <el-form-item label="" prop="direction">
          <el-select v-model="socalInfo.direction" placeholder="">
            <el-option v-for="(item,index) in libs.direction" :key="index" :label="item.label" :value="item.value"></el-option>
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item label="" prop="window">
          <el-select v-model="socalInfo.window" placeholder="">
            <el-option v-for="(item,index) in libs.window" :key="index" :label="item.label" :value="item.value"></el-option>
          </el-select>
        </el-form-item>
      </el-col>
    </el-row>
    <el-row :gutter="10">
      <el-col :span="16">
        <el-row>
          <el-col :span="12">
            <el-form-item label="" prop="min_lease_rent">
              <el-input placeholder="" v-model="socalInfo.min_lease_rent">
                <template slot="prepend"></template>
              </el-input>
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item label="" prop="max_lease_rent">
              <el-input placeholder="" v-model="socalInfo.max_lease_rent">
                <template slot="prepend"></template>
              </el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-col>
    </el-row>

    <el-row :gutter="10">
      <el-col :span="8">
        <el-form-item label="" prop="beginTime">
          <el-date-picker v-model="socalInfo.beginTime" type="date" placeholder="">
          </el-date-picker>
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item label="" prop="manager">
          <el-select v-model="socalInfo.manager" placeholder="">
            <el-option v-for="(item,index) in manager" :key="index" :label="item.label" :value="item.value"></el-option>
          </el-select>
        </el-form-item>
      </el-col>
    </el-row> -->

    <!-- <el-card class="box-card uploadPic">
      <el-row :gutter="10">
        <el-col :span="24">
          <el-form-item label="" prop="pic">
            <el-upload :headers="headers" :file-list="socalInfo.fileList" :on-success="getPhotoList" accept="image/jpeg,image/gif,image/png,image/bmp" ref="upload" action="`/api/attachment/up?action=community`" list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="handleRemove">
              <i class="el-icon-plus"></i>
            </el-upload>
            <el-dialog :visible.sync="dialogVisible" append-to-body>
              <img width="100%" :src="dialogImageUrl" alt="">
                </el-dialog>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="10">
        <el-col :span="24">
          <el-form-item label="" prop="remarks">
            <el-input v-model="socalInfo.remarks" type="textarea" :rows="8"></el-input>
          </el-form-item>
        </el-col>
      </el-row>
    </el-card> -->
  </el-form>
</el-tab-pane>
<el-tab-pane label="" name="serverInfo" :disabled="tabActive2">
  <!-- form -->
  <el-form label-position="top" class="demo-table-expand" :rules="serverInforules" :model="serverInfo">
    <!-- <el-row :gutter="10">
      <el-col :span="24">
        <div class="server_icon">
          <div class="roleClass" v-for="(roleLine, index) in serverData" :key="index">
            {{roleLine.label}}
            <el-checkbox-group v-model="checkedServe" class="inlineStyle service_inline" @change="(data)=>handleCheckedChange(data,index)">
              <el-checkbox v-for="name in roleLine.children" :key="name.name" :label="name.name" border>
                <span class="small_icon">
                    <img :src="`${API}/up/servers/${name.ico}`" alt="">
                    </span> {{name.name}}
              </el-checkbox>
            </el-checkbox-group>
            <div style="margin: 10px 0;"></div>

          </div>
        </div>
      </el-col>
    </el-row> -->
    <!-- <el-row :gutter="10">
      <el-col :span="24">
        <el-form-item label="" prop="remarks">
          <el-input v-model="serverInfo.remarks" type="textarea" :rows="5" auto-complete="off"></el-input>
        </el-form-item>
      </el-col>
    </el-row> -->
  </el-form>
  <!-- form -->
</el-tab-pane>

< / el-tabs >
< span slot= "footer center" class= "dialog-footer" >

    <el-button v-if="activeName !== "socalInfo"" @click="prePage"></el-button>
    <el-button type="primary" v-if="activeName !=="serverInfo"" @click="saveAndNext">&</el-button>
    <el-button v-show="activeName == "serverInfo"" type="primary" @click="saveAndClose"></el-button>
  </span>

< / div >
< / template >

< script >
import {
API,
ERR_OK
} from "@ / api/api";
import http from "@ / router/axios.js";
import {
provinceAndCityData,
regionData,
provinceAndCityDataPlus,
regionDataPlus,
CodeToText,
TextToCode
} from "element-china-area-data";
import {
validatenull
} from" @ / util/validate.js";
export default {
props: ["dialogVisible"],
data () {

let self = this;
const token = getStore({
  name: "token"
});
return {
  checkedServe: [],
  API,
  provinceAndCityData,
  regionData,
  provinceAndCityDataPlus,
  regionDataPlus,
  CodeToText,
  TextToCode,
  activeName: "socalInfo",
  tabPanel: ["socalInfo", "serverInfo"],
  headers: {
    Authorization: `Bearer ${token}`
  },
  editable: true,
  isDragging: false,
  delayedDragging: false,
  dialogImageUrl: "",
  dialogVisible: false,
  showDouble: false,
  showSigle: true,
  bindGrid: 8,
  formEdit: true,
  mapAddressInfo: "",
  AreaOptions: regionData,
  plugins: ["AMap.Autocomplete"],
  innerVisible: false,
  innerVisible2: false,
  q: "",
  amapManager,
  address: "",
  zoom: 14,
  lng: 0,
  lat: 0,
  center: [113.666226, 34.799998],
  markers: [],
  marker: {
    position: [113.666226, 34.799998],
    visible: true,
    draggable: true,
    events: {
      click: (e) => {
        let o = this.amapManager.getMap();
        let marker = new AMap.Marker({
          position: this.center
        });
        marker.setMap(o);
        console.log(e)
      },
      dragend: (e) => {
        console.log(e)
        this.marker.position = [e.lnglat.lng, e.lnglat.lat];
        let {
          lng,
          lat
        } = e.lnglat;
        self.lng = lng;
        self.lat = lat;
        self.socalInfo.lng = lng;
        self.socalInfo.lat = lat;
        //  SDK 
        var geocoder = new AMap.Geocoder({
          radius: 1000,
          extensions: "all"
        });
        geocoder.getAddress([lng, lat], function (status, result) {
          if (status === "complete" && result.info === "OK") {
            if (result && result.regeocode) {
              self.address = result.regeocode.formattedAddress;
              self.$nextTick();
            }
          }
        });
      }
    }
  },
  events: {
    click: (e) => {
      // this.$notify({
      //   title: "",
      //   message: ""
      // })
      this.marker.position = [e.lnglat.lng, e.lnglat.lat];
      let {
        lng,
        lat
      } = e.lnglat;
      self.lng = lng;
      self.lat = lat;
      self.socalInfo.lng = lng;
      self.socalInfo.lat = lat;
      //  SDK 
      var geocoder = new AMap.Geocoder({
        radius: 1000,
        extensions: "all"
      });
      geocoder.getAddress([lng, lat], function (status, result) {
        if (status === "complete" && result.info === "OK") {
          if (result && result.regeocode) {
            self.address = result.regeocode.formattedAddress;
            self.$nextTick();
          }
        }
      });
      console.log(e);
    }
  },
  getCity: "",
  searchOption: {
    city: String(this.getCity),
    citylimit: true
  },
  serverInfo: {
    device: [],
    remarks: ""
  },

  spaceData: [],
  manager: [],
  socalInfo: {
    name: "",
    status: "",
    managerId: "",
    address: ["410000", "", ""],
    mapPoint: "",
    build: "",
    floor: "",
    hight: "",
    mianji: "",
    dianti: "",
    gongwei: "",
    beginTime: "",
    manager: "",
    lng: "",
    lat: "",
    photo: "",
    fileList: [],
    pic: [],
    direction:"",
    window:"",
    min_lease_rent:"",
    max_lease_rent:""
  },

  buildInfo: {
    buildNum: "",
    buildStart: "",
    buildEnd: "",
    buildSquare: "",
    list: [],
    newList: []
  },

  rules: {
    name: [{
      required: true,
      message: "",
      trigger: "blur"
    }],
    status: [{
      required: true,
      message: "",
      trigger: "change"
    }],
    address: [{
      required: true,
      message: "",
      trigger: "blur"
    }],
    mapPoint: [{
      required: true,
      message: "",
      trigger: "blur"
    }],
    build: [{
      required: true,
      message: "",
      trigger: "blur"
    }],
    floor: [{
      required: true,
      message: "",
      trigger: "blur"
    }],
    hight: [{
      required: true,
      message: "",
      trigger: "blur"
    }],
    mianji: [{
      required: true,
      message: "",
      trigger: "blur"
    }],
    dianti: [{
      required: true,
      message: "",
      trigger: "blur"
    }],
    gongwei: [{
      required: true,
      message: "",
      trigger: "blur"
    }],
    beginTime: [{
      required: true,
      message: "",
      trigger: "blur"
    }],
  },
  serverInforules: {
    buildNum: [{
      required: true,
      message: "",
      trigger: "change"
    }],
    floor_name: [{
      required: true,
      message: ""
    }],
    buildStart: [{
      required: true,
      message: ""
    }],
    buildEnd: [{
      required: true,
      message: ""
    }],
    buildSquare: [{
      required: true,
      message: ""
    }]
  },

  tableSearch: {},
  tableOption: tableOption, //
  tableData: [], //
  tableRow: {},
  tablePage: 1,
  tableLoading: false,
  addDisabled: false,
  addVisdiplay: false,
  tabelObj: {},
  formJson: "",
  user: {},
  options: [],
  page: {
    total: 0, //
    currentPage: 1, //
    pageSize: 10 //
  },

  currentFormId: "", //formid
  serverData: [{
    checkedServe: []
  }],

  tabActive1: false,
  tabActive2: true,
  fullscreenLoading: false,
  isShow: true,
  isDisabled: false,
  dialogState: {
    show: false
  },
  libs:{
    direction:[],
    window:[],
    min_lease_rent:[],
    max_lease_rent:[]
  }
}

},
methods: {

onClose() {
  this.$emit("update:dialogVisible", false)
}

},

}
< / script >

< style lang= "less" scoped >

< / style >

what result do you expect? What is the error message actually seen?

how do you solve the problem when dealing with the split of multiple new editing components in dialog


dialog, since you are doing the component, you should submit it independently, and call the refresh page method of the parent component after the submission is successful. Pass the object in or call the query interface directly in the subcomponent.


I didn't take a closer look at it, but I think so. Put dialog on the common layer, and then use parameters to control the component

.
 <el-dialog
      class="z-dialog"
      :visible.sync="dialogObj.show"
      :width="dialogObj.width"
      append-to-body
      :before-close="handleClose"
    >
      <div slot="title" class="z-dialog-title">
        <i :class="dialogObj.titleIcon||'el-icon-setting'"></i>
        {{ dialogObj.title}}
      </div>
      <keep-alive>
        <component
          v-if="dialogObj.component"
          :is="dialogObj.component"
          @component-even="componentEven"
          :config-data="dialogObj.configData"
        />
      </keep-alive>
    </el-dialog>

for example, write a separate component for new, editing, etc., and then display

through the component component.
Menu