Vue3【六】实现页面简单的增删改查

还是那一句,vue有手就会,vue3的写法有点像当年写jquery的感觉

vue3 + elementPlus 实现简单的增删改查,多选框批量删除

请求拦截器

import axios from 'axios';
import { ElNotification, ElMessageBox, ElMessage, ElLoading } from 'element-plus';
import { saveAs } from 'file-saver';
import store from '@/store';
import { getToken } from '@/utils/token';
import errorCode from '@/utils/errorCode';
import { isBlobData } from '@/utils/common';
import { encodeURIParams } from '@/utils/strUtil';
import cache from '@/plugins/cache';

let downloadLoadingInstance;
// 是否显示重新登录
export const isReLogin = { show: false };

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8';
// 创建axios实例
const service = axios.create({
    // axios中请求配置有baseURL选项,表示请求URL公共部分
    baseURL: import.meta.env.VITE_APP_BASE_API,
    // 超时
    timeout: 30000,
});

// request拦截器
service.interceptors.request.use(
    (config) => {
        // 是否需要设置 token
        const isToken = (config.headers || {}).isToken === false;
        // 是否需要防止数据重复提交
        const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
        if (getToken() && !isToken) {
            config.headers.AuthToken = `Bearer ${getToken()}`; // 让每个请求携带自定义token 请根据实际情况自行修改
        }
        // get请求映射params参数
        if (config.method === 'get' && config.params) {
            let url = `${config.url}?${encodeURIParams(config.params)}`;
            url = url.slice(0, -1);
            config.params = {};
            config.url = url;
        }
        if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
            const requestObj = {
                url: config.url,
                data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
                time: new Date().getTime(),
            };
            const sessionObj = cache.session.getJSON('sessionObj');
            if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
                cache.session.setJSON('sessionObj', requestObj);
            } else {
                const s_url = sessionObj.url; // 请求地址
                const s_data = sessionObj.data; // 请求数据
                const s_time = sessionObj.time; // 请求时间
                const interval = 10; // 间隔时间(ms),小于此时间视为重复提交
                if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
                    const message = 'The request is in processing, please do not repeat the same request.';
                    console.warn(`[${s_url}]: ${message}`);
                    return Promise.reject(new Error(message));
                }
                cache.session.setJSON('sessionObj', requestObj);
            }
        }
        return config;
    },
    (error) => {
        console.log(error);
        Promise.reject(error);
    },
);

// 响应拦截器
service.interceptors.response.use(
    (res) => {
        // 二进制数据则直接返回
        if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
            return res.data;
        } else {
            if (res.data.state === 'S') {
                return Promise.resolve(res.data.payload);
            } else {
               //{"state":"F","errorCode":5001,"error":"User is not exists!"}
                // 未设置状态码则默认成功状态
                const code = res.data.errorCode;
                // 获取错误信息
                const msg = res.data.error;
                if (code == 4004 || code == 4005 || code == 4006 || code == 4007) {
                    if (!isReLogin.show) {
                        isReLogin.show = true;
                        ElMessageBox.confirm('Login state has been expired, Please re-login!', 'System Info', {
                            confirmButtonText: 'Re-Login',
                            cancelButtonText: 'Cancel',
                            type: 'warning',
                        })
                            .then(() => {
                                isReLogin.show = false;
                                store.dispatch('LogOut').then(() => {
                                    location.href = import.meta.env.BASE_URL;
                                });
                            })
                            .catch(() => {
                                isReLogin.show = false;
                            });
                    }
                    return Promise.reject('Please re-login!');
                } else {
                    ElNotification.error({
                        title: msg,
                    });
                    return Promise.reject('error');
                }
            }
        }
        return Promise.resolve(res.data.payload);
    },
    (error) => {
        console.log(`err${error}`);
        let { message } = error;
        ElMessage({
            message,
            type: 'error',
            duration: 5 * 1000,
        });
        return Promise.reject(error);
    },
);

// 通用下载方法
export function download(url, params, filename) {
    downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' });
    return service
        .post(url, params, {
            transformRequest: [(params) => encodeURIParams(params)],
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            responseType: 'blob',
        })
        .then(async (data) => {
            const isLogin = await isBlobData(data);
            if (isLogin) {
                const blob = new Blob([data]);
                saveAs(blob, filename);
            } else {
                const resText = await data.text();
                const rspObj = JSON.parse(resText);
                const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode.default;
                ElMessage.error(errMsg);
            }
            downloadLoadingInstance.close();
        })
        .catch((r) => {
            console.error(r);
            ElMessage.error('下载文件出现错误,请联系管理员!');
            downloadLoadingInstance.close();
        });
}

export default service;

api

import request from '@/utils/request';

export function addAccountSettingsSubscribeType(data) {
    return request({
        url: '/dic/common/accountSettingsSubscribeType',
        method: 'post',
        data
    });
}
export function removeAccountSettingsSubscribeType(data) {
    return request({
        url: `/dic/common/accountSettingsSubscribeType` ,
        method: 'delete',
        data
    });
}
export function updateAccountSettingsSubscribeType(data) {
    return request({
        url: `/dic/common/accountSettingsSubscribeType/` + data.id,
        method: 'put',
        data,
    });
}
export function getAccountSettingsSubscribeType(data) {
    return request({
        url: `/dic/common/accountSettingsSubscribeType/` + data,
        method: 'get'
    });
}
export function getAccountSettingsSubscribeTypeList(data) {
    return request({
        url: '/dic/common/accountSettingsSubscribeType/findPage' + data,
        method: 'get',
        data
    });
}




功能管理

<template>
  <div>
    <div class="card-wrap" style="padding: 0 12px;">
      <el-form :model="state.queryParams" ref="queryRef" :inline="true" class="form-search-wrap">
        <el-form-item label="code">
          <el-input v-model="state.queryParams.code" clearable style="width: 240px" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="Search" @click="getList()">Search</el-button>
          <el-button icon="Refresh" @click="resetSearchForm">Reset</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div class="card-wrap" style="padding-bottom: 100px;">
      <div class="operation-wrap">
        <el-button type="primary" @click="handleEdit(null, 1)">Add</el-button>
        <el-button type="danger" @click="batchRemove" >Remove</el-button>
      </div>
      <el-table :data="state.tableData"
                v-loading="state.loading"
                @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" />
        <el-table-column prop="code" label="Code"></el-table-column>
        <el-table-column prop="value" label="Value"></el-table-column>
        <el-table-column prop="i18n" label="I18n"></el-table-column>
        <el-table-column label="Operation" align="center">
          <template #default="scope">
            <el-button type="primary" icon="Edit" @click="handleEdit(scope.row, 0)" circle />
            <el-button type="danger" icon="Delete" @click="remove(scope.row.id, 0)" circle />
          </template>
        </el-table-column>
      </el-table>
      <div class="pagination">
        <el-pagination
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :current-page="state.queryParams.page"
            :page-sizes="[10, 20, 50, 100]"
            :page-size="state.queryParams.size"
            layout="total, sizes, prev, pager, next, jumper"
            :total="state.queryParams.total">
        </el-pagination>
      </div>
    </div>
    <el-dialog :title="state.type?'add':'update'" v-model="state.dialogVisible" width="30%"  destroy-on-close @close='resetForm'>
      <el-form ref="addForm" :rules="state.rules" :model="state.addFormField" label-width="100px">
        <el-form-item label="code" prop="code">
          <el-input v-model="state.addFormField.code" style="width: 380px;" ></el-input>
        </el-form-item>
        <el-form-item label="value" prop="value">
          <el-input v-model="state.addFormField.value" style="width: 380px;" ></el-input>
        </el-form-item>
        <el-form-item label="i18n" prop="i18n">
          <el-input v-model="state.addFormField.i18n" style="width: 380px;" ></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="state.dialogVisible = false">Cancel</el-button>
          <el-button type="primary" @click="add">Confirm</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { reactive, ref } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import * as api from '@/api/dic/accountSettingsSubscribeType';
const addForm = ref();
const state = reactive({
  multipleSelection: [],
  dialogVisible: false,
  num: 1,
  loading: false,
  type: "add",
  tableData: [],
  addFormField: {
    id: "",
    code: "",
    value: "",
    i18n: "",
  },
  queryParams: {
    code: undefined,
    page: 1,
    size: 10,
    total: 0,
  },
  rules: {
    code: [
      { required: "true", message: "code is not empty", trigger: ["change"] },
    ],
    value: [
      { required: "true", message: "value is not empty", trigger: ["change"] },
    ],
    i18n: [
      { required: "true", message: "i18n is not empty", trigger: ["change"] },
    ],
  },
});

function handleSelectionChange(val) {
  state.multipleSelection = val
}

function commonRemove(idList) {
  ElMessageBox.confirm('Are you sure to remove this data?')
      .then(() => {
        api
            .removeAccountSettingsSubscribeType({idList: idList})
            .then((res) => {
            })
            .finally(() => {
              state.loading = false;
            });
        ElMessage.success("success");
        setTimeout(() => {
          getList();
        }, 300);
      })
  getList();
}

function remove(id){
  let idList = [];
  idList.push(id)
  commonRemove(idList);
}

function batchRemove() {
  if(state.multipleSelection == undefined || state.multipleSelection.length <= 0){
    ElMessage.warning("Please select checkbox");
    return;
  }
  let idList = [];
  state.multipleSelection.forEach((value, index) => {
    idList.push(value.id)
  });
  commonRemove(idList);
}

function handleEdit(row, type){
  if(row){
    state.addFormField = JSON.parse(JSON.stringify(row));
  }
  if (type) {
    state.type = true;
  } else{
    state.type = false;
  }
  state.dialogVisible = true;
}

function resetForm(){
  state.addFormField = {
    id: undefined,
    code: undefined,
    value: undefined,
    i18n: undefined,
  }
}

function resetSearchForm(){
  state.queryParams.code = undefined;
}

function add(){
  addForm.value.validate((valid) => {
    if (valid) {
      let id = state.addFormField.id;
      if (id) {
        api
            .updateAccountSettingsSubscribeType(state.addFormField)
            .then((res) => {
              ElMessage.success("success");
            })
            .finally(() => {
              state.loading = false;
            });
      }else{
        api
            .addAccountSettingsSubscribeType(state.addFormField)
            .then((res) => {
              ElMessage.success("success");
            })
            .finally(() => {
              state.loading = false;
            });
      }
      resetForm();
      state.dialogVisible = false;
      setTimeout(() => {
        getList();
      }, 200);
    } else {
      return false;
    }
  });
}

function getList(){
  state.loading = true;
  let data = {};
  if(state.queryParams){
    data = JSON.stringify(state.queryParams).replace(/:/g, '=').replace(/,/g, '&').replace(/{/g, '?').replace(/}/g, '').replace(/"/g, '');
  }
  api
      .getAccountSettingsSubscribeTypeList(data)
      .then((res) => {
        state.tableData = res.items;
        state.queryParams.page = res.page;
        state.queryParams.size = res.size;
        state.queryParams.total = res.total;
      })
      .finally(() => {
        state.loading = false;
      });
}

function handleSizeChange(val){
  state.queryParams.size = val;
  getList();
}

function handleCurrentChange(val){
  state.queryParams.page = val;
  getList();
}

getList();
</script>
<style scoped >
/deep/ .el-overlay-dialog{
  top:25%
}
.pagination {
  background: #fff;
  padding: 20px 10px 0;
  display: flex;
  justify-content: flex-end;
  box-sizing: border-box;
}
.card-wrap{
  padding: 15px 20px 20px 20px;
  border-radius: 4px;
  border: 1px solid #e6ebf5;
  background-color: #fff;
  overflow: hidden;
  color: #303133;
  -webkit-transition: .3s;
  transition: .3s;
  box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
  margin: 10px;
}
.operation-wrap{
  margin: 0 0 16px 0;
}
.form-search-wrap{
  margin: 10px 0 0 12px;
}
</style>




今天水一篇,祝各位大佬 1024程序员节快乐~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宁漂打工仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值