前言
使用vue3的语法糖以及elementPlus的组件实现表格增加部分;
编辑还没想到如何更好地获取编辑数据和关闭弹窗后清除编辑数据。
之前是用export default写的表格数据的增删改查;今天想尝试使用setup语法糖,但是在实际使用过程中,不知道使用语法糖该如何更好的编辑数据。
export default的方式可以使用*** $refs *** 直接操作,并把数据或者id传入组件中
<add-dict ref="addDictPop"></add-dict>
handleClick(index,item){
this.$refs.addDictPop.open(item)
},
处理数据和销毁数据也很方便
methods:{
// 打开弹出窗
open(row){
this.is_show = true
if(row){
this.handleEdit(row)
}
},
// 编辑时,设置默认值
handleEdit(row) {
this.title = "修改字典";
this.formVal.id = row.id;
this.formVal.dictKey = row.dictKey;
this.formVal.dictValue = row.dictValue;
this.formVal.code = row.code;
},
// 提交表单
async onSumbit(){
var _this = this
try {
// 1、表单验证
await this.$refs.ruleFormRef.validate()
console.log(_this.formVal)
// 2、请求
const { data } = await addDict(_this.formVal)
// 3、响应处理
_this.$message.success(data.msg)
_this.$parent.changePage(1)
_this.closeDialog()//关闭
} catch (err) {
console.log('验证失败', err)
}
},
// 关闭前的事件
closeDialog(){
// 清空数据
this.title = "添加字典";
this.formVal.id = ''
this.formVal.dictKey = ''
this.formVal.dictValue = ''
this.formVal.code = ''
this.is_show = false
},
},
以下是使用vue3的语法糖以及elementPlus的组件实现表格增加的演示部分(代码在下面)
点击‘添加字典’后
1、表格
主要采用了props传is_show来控制 ‘添加字典弹窗’ 的弹出和关闭;
通过refreshTable控制添加完成后的刷新事件;
通过closeDialog控制关闭弹窗事件;
<template>
<div class="com-table-contaier">
<!-- 头部搜索栏 -->
<view class="com-header">
<el-form
ref="ruleFormRef"
:inline="true"
:model="formHeader"
>
<el-form-item label="字典键值">
<el-input v-model="formHeader.code" placeholder="请输入字典键值" />
</el-form-item>
<el-form-item label="字典名称">
<el-input v-model="formHeader.dictValue" placeholder="请输入字典名称" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSearch">
<svg-icon name="icon-search" class="icon-svg icon-btn" />
搜索
</el-button>
</el-form-item>
</el-form>
</view>
<view class="com-header">
<el-button type="primary" @click="handleClick">
<svg-icon name="icon-add" class="icon-svg icon-btn" />
添加字典
</el-button>
</view>
<!-- 表格内容 -->
<el-table
:data="tableData"
style="width: 100%;"
border
header-cell-class-name="table-header-line"
>
<el-table-column prop="id" label="id" sortable></el-table-column>
<el-table-column prop="dictValue" label="字典名称"></el-table-column>
<el-table-column prop="code" label="字典编码"></el-table-column>
<el-table-column prop="dictKey" label="字典键值"></el-table-column>
<el-table-column label="操作">
<template #default="scope">
<el-button type="primary" size="small" @click="handleClick(scope.row.id)">
<!-- <svg-icon name="icon-edit" class="icon-svg icon-btn" /> -->
编辑
</el-button>
<el-button type="danger" size="small" @click="clickdel(scope.row)">
<!-- <svg-icon name="icon-del" class="icon-svg icon-btn" /> -->
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 底部分页 -->
<el-pagination
background
layout="prev, pager, next"
:total="total"
@current-change="changePage"
/>
<!-- 弹出窗 -->
<add-dict
@closeDialog="add_show = false"
:visible="add_show"
@refreshTable="changePage(1)"
></add-dict>
</div>
</template>
<script setup>
import addDict from './addDict.vue'
import { dictList,delDict } from '@/utils/api/user.js'
import { ElMessage,ElMessageBox } from 'element-plus'
import {reactive,ref} from 'vue'
var formHeader = reactive({code:'',dictValue:'',})
var tableData = ref([])
var page = ref(1)
var size = ref(30)
var total = ref(1)
const initTableData = async () => {
const { data } = await dictList({
current: page.value,
size: size.value,
code:formHeader.code,
dictValue: formHeader.dictValue,
})
// 请求每次得到的是新一段数据,只需要展示,不需要push
total.value = Math.ceil(data.data.total/size.value)
tableData.value = data.data.records
}
initTableData()
const onSearch = () => {
changePage(1)
}
// 改变page
const changePage = (event) => {
page.value = event
initTableData()
}
// 删除
const clickdel = (item) => {
ElMessageBox.confirm(
'你确定要删除吗?',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
}
)
.then(async () => {
const { data } = await delDict(item.id)
ElMessage({
message: data.msg,
type: 'success',
})
changePage(1)
})
.catch(() => {
// catch error
})
}
const add_show = ref(false)
// 打开添加弹出窗
const handleClick = (id) => {
add_show.value = true
}
</script>
2、弹出窗
<template>
<el-dialog
v-model="visible"
:close-on-click-modal="false"
:before-close="closeDialog"
:destroy-on-close="true"
:title="title"
width="850px"
>
<el-form ref="ruleFormRef" :model="formVal" :rules="formRule">
<el-form-item label="字典名称" prop="dictValue">
<el-input v-model="formVal.dictValue" placeholder="如:男"></el-input>
</el-form-item>
<el-form-item label="字典键值" prop="dictKey">
<el-input v-model="formVal.dictKey" placeholder="如:1"></el-input>
</el-form-item>
<el-form-item label="字典编码" prop="code">
<el-input v-model="formVal.code" placeholder="如:sex"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSumbit">提交</el-button>
<el-button v-if="!isEdit" @click="resetForm">重置</el-button>
<el-button @click="closeDialog">取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
</template>
子传父的主要方式为:emits
<script setup>
import { addDict } from '@/utils/api/user.js'
import { ElMessage } from 'element-plus'
import {reactive,ref} from 'vue'
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
})
var formVal = reactive({id:'',dictKey:'',dictValue:'',code:''})
var formRule = reactive({
dictKey: [
{ required: true, message: '请输入字典键值', trigger: 'blur' },
],
dictValue: [
{ required: true, message: '请输入字典名称', trigger: 'blur' },
],
code: [
{ required: true, message: '请输入字典编码', trigger: 'blur' },
{ pattern: /^[^\u4e00-\u9fa5]*$/, message: '不可输入中文' }
],
})
var title = ref('添加字典')
const ruleFormRef = ref(null)
const emits = defineEmits(['closeDialog','refreshTable'])
// 提交表单
const onSumbit = async () => {
const valid = await ruleFormRef.value.validate().catch(err => err)
if (valid == true){
const { data } = await addDict(formVal)
// 3、响应处理
ElMessage({
message: data.msg,
type: 'success',
})
emits('refreshTable')
closeDialog()//关闭
}
}
// 关闭前的事件
const closeDialog = () => {
// 清空数据
title.value = "添加字典"
resetForm()// 重置
emits('closeDialog')
}
// 重置
const resetForm = () => {
ruleFormRef.value.resetFields()
}
</script>
<style scoped>
.el-autocomplete{
width: 100%;
}
.el-form-item__content{
flex-wrap: nowrap;
}
</style>