H5W3
当前位置:H5W3 > 其他技术问题 > 正文

【element-ui】Vue 父组件里有七八个按钮,每个按钮都会操作一个dialog,如何将dialog及dialog里分步骤的表单拆分为单个组件

问题描述

我尝试把dialog拆分为单个组件,但是在子组件里data已经定义过的属性还是会报错

clipboard.png

问题出现的环境背景及自己尝试过哪些方法

尝试用vuex来,可能姿势不对,这几个dialog业务复杂,此菜单栏目的dialog按钮可以唤起另一个菜单里的dialog显示及打开路由后显示dialog

相关代码

// 请把代码文本粘贴到下方(请勿用图片代替代码)
<template>
<div>
<el-tabs v-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’;
import {
setStore,
getStore,
removeStore
} from “@/util/store”;
import {
AMapManager
} from “vue-amap”;
let amapManager = new AMapManager();
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: '', //创建完成后第一步form的id
  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>

你期待的结果是什么?实际看到的错误信息又是什么?

各位在处理多个dialog新增编辑组件拆分的时候 是如何解决的

回答:

dialog里面既然是做组件,就要独立,独立提交,提交成功后调用父组件的刷新页面方法。传对象进来或者直接在子组件里面调用查询接口。

回答:

没细看,但我觉得是吧dialog放在公共层,然后通过参数去控制组件

 <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>

比如这样,把新建,编辑啥的写个单独组件后引入,然后通过component组件来显示

本文地址:H5W3 » 【element-ui】Vue 父组件里有七八个按钮,每个按钮都会操作一个dialog,如何将dialog及dialog里分步骤的表单拆分为单个组件

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址