目录结构
index
<template> <div style="padding: 15px;"> <h2> vue复杂联动表单需求</h2> {{formData}} <h2>投放区域</h2> <el-select v-model="selectArr" @change="selectChange" multiple> <el-option v-for="option in optionArr" :value="option.value" :label="option.label" :key="index"></el-option> </el-select> <!-- <el-select filterable v-model="form.level" placeholder="请选择项目级别" >--> <!-- <template v-for="item in Object.keys(levelMap)" :key="item">--> <!-- <el-option :label="levelMap[item]" :value="parseInt(item)"></el-option>--> <!-- </template>--> <!-- </el-select>--> <DetailTable :formData="formData" :optionMap="optionMap" /> <CrowEdit ref="crowRef" /> <div> <el-button type="primary" @click="sub">提交</el-button> </div> </div> </template> <script setup> import requestUtil from "@/util/request"; import store from '@/store' import {ref, computed , onMounted,nextTick , reactive,onBeforeMount, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted} from 'vue' import {ElMessage} from 'element-plus' import router from '@/router' import Cookies from "js-cookie"; import { encrypt, decrypt } from "@/util/jsencrypt"; import {Check, Delete, Edit, Message, Search, Star,} from '@element-plus/icons-vue' import DetailTable from "./detaiTable" import CrowEdit from "./crowEdit" const optionArr = [ { value:"app-head", label:"app头部" }, { value:"app-banner", label:"首页banner" }, { value:"msg", label:"消息推送" }, ] //转成对象 后面好取用。 可以直接使用 optionMap[app-banner] 取到对应的文字。如果不用这种, arr就要使用下标,我们又不知道 下标是多少。 const optionMap = {} optionArr.forEach((item)=>{ optionMap[item.value] = item.label }); console.log(optionMap); const crowRef = ref(null); const formData = ref([]);//这里面放的数据是 // { // name : valueCode, // details:{ // duty:"" // }, // crowd:[] // } //当我们选择一个选项 之后,formData就会添加一个对象。 const selectChange = (value)=>{ // value是个数组:["app-head", "app-banner"] const arr_ = value.map((valueCode)=>{ let isExit = false;//默认当前不存在。 formData.value.forEach((item)=>{ if(item.name==valueCode){ //如果相等 就代表当前这个值存在于formData 无需新建 直接使用当前 isExit = item; } }) if(isExit){ return isExit;//返回之前的item 复用。 }else{ return { name : valueCode, details:{ duty:"" }, crowd:[] } } }) formData.value = arr_; } //这个代码 删除也不会报错,因为默认就是显示 我们选择的东西。 const selectArr = computed(() => { //这个地方是让select显示 选择的东西。 return formData.value.map((item)=>{ return item.name; }) }); const sub = ()=>{ console.log(crowRef.value.crowArr); console.log(crowRef.value.crowArr[0]); console.log(crowRef.value.crowArr[0].crowName); const crowArr = crowRef.value.crowArr; formData.value.forEach((item)=>{ item.crowd = crowArr; }); console.log(formData.value); } onMounted(()=>{ //设置回显示功能。 // setTimeout(()=>{ // const res = [ { "name": "app-head", "details": { "duty": "11" }, "crowd": [ { "crowName": "111", "crowSize": "333" }, { "crowName": "222", "crowSize": "33" } ] }, { "name": "msg", "details": { "duty": "222" }, "crowd": [ { "crowName": "111", "crowSize": "333" }, { "crowName": "222", "crowSize": "33" } ] } ]; // formData.value = res; // //res[0].crowd 是数组。 就是全部的数据。5行或者10行。 因为0 1 2 3 他们都是重复,使用哪一个都行。 // crowRef.value.setCrow(res[0].crowd); // },800) }) </script> <style scoped> h2{ font-size: 30px; padding: 10px 0px; font-weight: bold; } </style>
detailTalbe
<template> <div> <h2>投放详细</h2> <el-table :data="formData"> <el-table-column label="区域名称" prop="name"> <template #default="scope"> {{optionMap[scope.row.name]}} </template> </el-table-column> <el-table-column label="投放负责人"> <template #default="scope"> <el-input v-model="scope.row.details.duty" /> </template> </el-table-column> </el-table> </div> </template> <script setup> const {formData ,optionMap } = defineProps(['formData','optionMap']) // const props=defineProps( // { // id:{ // type:Number, // default:-1, // required:true // }, // dialogTitle:{ // type:String, // default:'', // required:true // }, // //这是是否显示 。窗口 // dialogVisible:{ // type:Boolean, // default:false, // required:true // } // } // ) </script> <style scoped> h2{ font-size: 30px; padding: 10px 0px; font-weight: bold; } </style>
crowEdit
<template> <div> {{crowArr}} <h2>目标人群</h2> <el-table :data="crowArr"> <el-table-column label="人群名称" prop="name"> <template #default="scope"> <el-input v-model="scope.row.crowName" /> </template> </el-table-column> <el-table-column label="目标量记"> <template #default="scope"> <el-input v-model="scope.row.crowSize" /> </template> </el-table-column> </el-table> <el-button @click="add">添加目标人群</el-button> </div> </template> <script setup> import {ref, computed , onMounted,nextTick , reactive,onBeforeMount, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted} from 'vue' const crowArr = ref([]); const setCrow = (crowd) =>{ crowArr.value = crowd; } defineExpose({ crowArr ,setCrow });// 将方法 或者 数据 爆露给父组件。 //console.log(crowRef.value.crowArr); 这样调用我们需要的数据。 const add=()=>{ crowArr.value.push ({ crowName:"", crowSize:"", }); } </script> <style scoped> h2{ font-size: 30px; padding: 10px 0px; font-weight: bold; } </style>
<DetailTable :formData="formData" :optionMap="optionMap" /> formData 这个组件内部修改 父组件 也是 实时显示的。 我们之前用了。emits('update:modelValue',false) 为什么之前要这样用。 不是实时通讯的吗。 是不是dialog有关? 这个需要验证一下。 const optionArr = [ { value:"app-head", label:"app头部" }, { value:"app-banner", label:"首页banner" }, { value:"msg", label:"消息推送" }, ] //转成对象 后面好取用。 可以直接使用 optionMap[app-banner] 取到对应的文字。如果不用这种, arr就要使用下标,我们又不知道 下标是多少。 const optionMap = {} optionArr.forEach((item)=>{ optionMap[item.value] = item.label }); 数组转对象这个技巧我之前 不会。 这个需要学习一下。
站长微信:xiaomao0055
站长QQ:14496453