笔杆刀锋 2024-08-15 11:39 采纳率: 0%
浏览 24

vue3中跨页面勾选

vue3+ts+element-plus跨页勾选,如何解决在弹框里面当我第一次勾选中数据我也使用了row-keyreserve-selection属性,以及监听selection-change事件来管理选中行,这样确实让我第一次勾选中的数据在第二次打开弹窗的时候可以实现跨页勾选,但是我该如何在第一次选中后第二次打开弹窗把第一次勾选的数据中的一条取消勾选,然后点击弹框的取消按钮当我再次打开弹窗的时候不会被改变,还有就是在我的页面中当我的表格点击删除数据的时候如何解决弹框的数据也被更改

这是封装的表格

<template>
  <div class="table-wrapper" v-loading="loading">
    <!-- 表格 -->
    <el-table
      center
      :data="list"
      style="width: 100%"
      :row-key="getRowKey"
      :header-cell-style="{
        background: '#f9f9f9',
        color: '#000000',
        height: '45px'
      }"
      @selection-change="handleSelectionChange"
    >
      <el-table-column v-if="ids" type="selection" :reserve-selection="true" />
      <slot />
    </el-table>
    <!-- 分页 -->
    <div class="pagination">
      <el-pagination
        hide-on-single-page
        :current-page="page"
        :page-size="pageSize"
        :page-sizes="[5, 10, 20, 50]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <slot name="footer" />
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, defineProps, watch } from 'vue';
interface IProps {
  listRequest: Function;
  searchParams?: AnyObject;
}

const props = withDefaults(defineProps<IProps>(), { searchParams: () => ({}) });
const ids = defineModel('ids');
const idsAll = defineModel('idsAll');
const list = ref<AnyObject[]>([]); // 当前页面数据
const page = ref(1); // 当前页码
const pageSize = ref(10); // 每页条数
const total = ref(0); // 总条数
const loading = ref(true); // 加载状态

const getList = async () => {
  loading.value = true;
  props.listRequest!({
    page: page.value,
    pageSize: pageSize.value,

    ...props.searchParams
  }).then((res: ListRes<AnyObject>) => {
    loading.value = false;
    console.log(res);
    total.value = res.data.counts;
    list.value = res.data.list;
  });
};
onMounted(getList);
// 切换了每页条数
const handleSizeChange = (val: number) => {
  // console.log(`${val} items per page`);
  page.value = 1;
  pageSize.value = val;
  getList();
};
// 翻页:页码发生变化
const handleCurrentChange = (val: number) => {
  // console.log(`current page: ${val}`);
  page.value = val;
  getList();
};

//多选
const handleSelectionChange = (val: any) => {
  ids.value = val.map((item: any) => item.id);
};

// 获取row的key
const getRowKey = (row: any) => {
  return row.id;
};

watch(
  () => props.searchParams,
  () => {
    console.log('父组件传入的searchParams发生变化了', props.searchParams);
    page.value = 1;
    getList();
  }
);

// 暴露内部属性方法
defineExpose({
  getList
});
</script>

<style scoped>
.el-table {
  margin-top: 20px;
}

.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}
</style>

这是我的页面

<template>
  <!-- 后勤管理/创建采购申请 -->
  <el-card>
    <div class="btn">
      <div class="btnstyle">
        <el-button type="primary" size="large" @click="selectFoods"
          >选择食材</el-button
        >
        <sup style="background-color: green" class="is-fixed">{{
          TableData.length
        }}</sup>
      </div>
    </div>
    <!-- 备注/到货日期 -->
    <div class="title-image">
      <div v-if="TableData.length">
        <el-table :data="TableData">
          <el-table-column label="序号" prop="id"></el-table-column>
          <el-table-column label="物料名称" prop="name"></el-table-column>
          <el-table-column label="单位" prop="unit"></el-table-column>
          <el-table-column label="供应商" prop="supplierName"></el-table-column>
          <el-table-column label="批发价" prop="wholePrice"></el-table-column>
          <el-table-column label="零售价" prop="sellPrice"></el-table-column>
          <el-table-column
            label="采购价"
            prop="purchasePrice"
          ></el-table-column>
          <el-table-column label="操作">
            <template #default="{ row }">
              <el-button type="danger" size="small" @click="deleteFood(row)"
                >删除</el-button
              >
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div>
        合计:采购品种数{{ TableData.length }},采购总成本:{{ PriceFoods }}</div>
      <div class="image">
        <el-form>
          <el-form-item label="请输入备注">
            <el-input
              type="textarea"
              v-model="formData.remarks"
              placeholder="请输入"
              style="width: 400px; height: 100px"
            ></el-input>
          </el-form-item>
          <el-form-item label="登记日期:" prop="addTime">
            <el-date-picker
              v-model="formData.receiveTime"
              placeholder="请选择"
              type="datetime"
              unlink-panels
              value-format="YYYY-MM-DD"
              format="YYYY-MM-DD"
              size="large"
            ></el-date-picker>
          </el-form-item>
        </el-form>
      </div>
    </div>
  </el-card>
  <div class="button-body">
    <el-button @click="$router.go(-1)">返回</el-button>
    <el-button @click="save" type="primary">保存</el-button>
    <el-button @click="saveAndSubmit" type="primary">保存并提交</el-button>
  </div>
  <SelectFood v-model="isOpen" @sure="handleSure" />
</template>

<script setup lang="ts">
//跳转
import { useRouter, useRoute } from 'vue-router';
//选择食物弹窗
import SelectFood from './SelectFood.vue';
//API
import { getFoodInfo } from '@/apis/foods/apis';
import { submitPurchase } from '@/apis/purchase/apis';

import { ref, computed, reactive, onMounted } from 'vue';
//element-plus
import { ElMessageBox } from 'element-plus';
import { Message } from '@element-plus/icons-vue';

interface Food {
  receiveTime: string;
  remarks: string;
  foods: any[];
}
// v-model
let formData = ref<Food>({
  receiveTime: '',
  remarks: '',
  foods: []
});

const isOpen = ref(false);
const TableDataId = ref<any>([]);
const selectFoods = () => {
  if(TableData){
    TableData.value.forEach((row: any)=>{
      TableDataId.value.push(row.id)
    })
  }
  isOpen.value = true;
  console.log('选择食材');
};

const router = useRouter();
const route = useRoute();
//保存
const save = () => {
  formData.value.foods = TableData.value.map((item: any) => {
    return {
      ...item,
      foodName: item.name
    };
  });
  sessionStorage.setItem('PurchaseInfo', JSON.stringify(formData.value));
  console.log(formData.value);
  router.go(-1);
};
//保存并提交
const saveAndSubmit = () => {
  formData.value.foods = TableData.value.map((item: any) => {
    return {
      ...item,
      foodName: item.name
    };
  });
  sessionStorage.setItem('PurchaseInfo', JSON.stringify(formData.value));
  submitPurchase(formData.value).then((res) => {
    console.log(res);
    if (res.code === 10000) {
      Message.success('添加成功');
      router.go(-1);
    }
  });
};

//删除
const deleteFood = (row: any) => {
  ElMessageBox.confirm('此操作将永久删除该数据, 是否继续?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    TableData.value = TableData.value.filter((item: any) => item.id !== row.id);
    PriceFoods.value = TableData.value.reduce((total: number, item: any) => {
      return total + item.purchasePrice;
    }, 0);
  });
};

const PriceFoods = ref<any>(0);
const TableData = ref<any>([]);
const handleSure = (ids: any) => {
  Promise.all(ids.map((item: any) => getFoodInfo(item))).then((res: any[]) => {
    TableData.value = res.map((item) => item.data);
    const totalPurchasePrice = computed(() => {
      return TableData.value.reduce((total: number, item: any) => {
        return total + item.purchasePrice;
      }, 0);
    });
    PriceFoods.value = totalPurchasePrice;
  });
};

onMounted(() => {
  const PurchaseInfo = sessionStorage.getItem('PurchaseInfo');
  if (PurchaseInfo) {
    formData.value = JSON.parse(PurchaseInfo);
    TableData.value = formData.value.foods;
    console.log('formData', formData.value.foods instanceof Array);
    PriceFoods.value = TableData.value.reduce((total: number, item: any) => {
      return total + item.purchasePrice;
    }, 0);
    console.log('formData', PriceFoods.value);
  }
});
</script>

<style lang="sass" scoped>
.btn
  margin: 10px 0
.btnstyle
  width: 95.6px
  position: relative
  --el-badge-size: 18px
.is-fixed
  position: absolute
  top: -10px
  right: -10px
  align-items: center
  border: 1px solid #fff
  border-radius: 10px
  color: #fff
  display: inline-flex
  font-size: 12px
  height: 18px
  justify-content: center
  white-space: nowrap
  padding: 6px
.title-image
  margin-top: 20px
  .image
    margin:50px 0px
.button-body
  margin-top: 70px
  text-align: center
</style>

这是我页面中的弹框

<template>
  <!-- 选择食物 -->
  <el-dialog v-model="isOpen" title="选择喜欢的食材">
    <Table
      :list-request="getFoods"
      v-model:ids="ids"
      v-model:idsAll="idsAll"
    >
      <el-table-column label="序号" prop="id"></el-table-column>
      <el-table-column label="物料名称" prop="name"></el-table-column>
      <el-table-column label="单位" prop="unit"></el-table-column>
      <el-table-column label="供应商" prop="supplierName"></el-table-column>
      <el-table-column label="批发价" prop="wholePrice"></el-table-column>
      <el-table-column label="零售价" prop="sellPrice"></el-table-column>
      <el-table-column label="采购价" prop="purchasePrice"></el-table-column>
      <template #footer>
        <div class="btn">
          <el-button @click="Cancel">取消</el-button>
          <el-button type="primary" @click="sure">确定</el-button>
        </div>
      </template>
    </Table>
  </el-dialog>
</template>

<script setup lang="ts">
//API
import { getFoods } from '@/apis/foods/apis';
//表格
import Table from '@/components/table/Table.vue';
//ref
import { ref } from 'vue';

const isOpen = defineModel({
  type: Boolean,
  default: false
});

const ids = ref<number[]>([]);
const idsAll = ref<number[]>([]);

//确定
const emit = defineEmits(['sure']);
const sure = () => {
  console.log(ids.value);
  emit('sure', ids.value);
  isOpen.value = false;
};
//取消
const Cancel = () => {
  isOpen.value = false;
};
</script>

<style lang="sass" scoped>
.btn
  margin-top: 20px
  display: flex
  justify-content: flex-end
</style>


  • 写回答

2条回答 默认 最新

  • 一直免费一直爽 2024-08-15 11:42
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    你可以在弹框关闭时重置ids数组,这样当你再次打开弹框时,之前选中的项会被取消选中。你可以在Cancel函数中添加一行代码来实现这个功能:

    const Cancel = () => {
      ids.value = []; // 重置ids数组
      isOpen.value = false;
    };
    

    另外,为了解决在表格中删除数据后弹框的数据也被更改的问题,你需要在删除数据时同步更新弹框中的ids数组。你可以在deleteFood函数中添加一行代码来实现这个功能:

    const deleteFood = (row: any) => {
      ElMessageBox.confirm('此操作将永久删除该数据, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        TableData.value = TableData.value.filter((item: any) => item.id !== row.id);
        ids.value = ids.value.filter((id: number) => id !== row.id); // 同步更新ids数组
        PriceFoods.value = TableData.value.reduce((total: number, item: any) => {
          return total + item.purchasePrice;
        }, 0);
      });
    };
    

    这样,无论是在弹框中取消选中还是从表格中删除数据,都会保持数据的一致性。

    评论

报告相同问题?

问题事件

  • 创建了问题 8月15日