自研国产零依赖前端UI框架实战007封装编辑和删除相关的功能组件

Python私教 2024-12-30 22:12:46
前言

前面我们已经实现了一个表格, 能够展示用户的信息, 一个分页能够执行分页获取用户信息.

到目前为止, 数据的渲染, 我们基本就做的差不多了, 接下来我们来扩展一下表格, 让其支持添加按钮, 我们在里面添加编辑按钮和删除按钮.

表格样式调整

我调整了一下表格的样式, 增加了操作列, 目前看起来是这样的:

在这里插入图片描述

代码里面增加了操作这一列:

在这里插入图片描述

操作这一列可以根据一个叫做operator的属性进行控制, 默认是true, 如果改成false, 则不显示操作列.

稍微调整一下删除按钮的样式

在这里插入图片描述暴露按钮点击方法

首先是在组件中添加要暴露的方法:

const emit = defineEmits(['edit', 'delete']);const onEdit = (index, item) => emit('edit', index, item) // 编辑const onDelete = (index, item) => emit('delete', index, item) // 删除

接着给按钮绑定:

<button @click.stop="onEdit(k, v)">编辑</button><button class="delete" @click.stop="onDelete(k,v)">删除</button>

在App.vue中监听编辑和删除这两个事件:

<zdp_table1        :columns="columns"        :data="data"        @edit="onEdit"        @delete="onDelete"    />

再简单的实现事件的监听:

const onEdit = (index, item) => {  console.log("编辑", index, item)}const onDelete = (index, item) => {  console.log("删除", index, item)}

此时, 当我们点击编辑按钮的删除按钮的时候, 控制台会输出对应的内容.

在这里插入图片描述

此时页面效果如下:

在这里插入图片描述

App.vue的完整代码如下:

<script setup>import zdp_table1 from "./zdpui/components/zdp_table1.vue";import zdp_page1 from "./zdpui/components/zdp_page1.vue";import random from "./zdpui/js/random.js";import {ref} from "vue";const columns = [  {    title: "员工编号",    key: "id",    width: 80,    align: "center"  },  {    title: "姓名",    key: "name",    width: 100,    align: "center"  },  {    title: "年龄",    key: "age",    width: 100,    align: "center"  }]const page = ref(1);const size = ref(10);const total = ref(100);const data = ref(random.users(size.value))const onChangePage = (v) => {  page.value = v  const newData = random.getPageUser(      page.value,      size.value,  )  data.value = newData.data  total.value = total.value}const onEdit = (index, item) => {  console.log("编辑", index, item)}const onDelete = (index, item) => {  console.log("删除", index, item)}</script><template>  <div>    <zdp_table1        :columns="columns"        :data="data"        @edit="onEdit"        @delete="onDelete"    />    <zdp_page1        :page="page"        :size="size"        :total="total"        @change="onChangePage"    />  </div></template>

删除确认

当我们点击删除的时候, 希望能够弹出一个确认删除的对话框, 比如像下面这样.

在这里插入图片描述

这个我已经封装好了, 比想象中要简单的多, 完整代码如下:

<script setup>import {defineEmits, defineProps} from 'vue';const props = defineProps({  show: {    type: Boolean,    default: false  },  title: {    type: String,    default: '确认删除'  },  content: {    type: String,    default: '你确定要删除该项目吗?此操作不可逆。'  },  ok: {    type: String,    default: '确认'  },  cancel: {    type: String,    default: '取消'  }});const emit = defineEmits(['confirm', 'close']);const onClose = () => emit('close')const onConfirm = () => emit('confirm')</script><template>  <div class="confirm-delete-dialog" v-if="props.show">    <div class="dialog-overlay" @click.self="onClose"></div>    <div class="dialog-content">      <h2>{{ props.title }}</h2>      <p>{{ props.content }}</p>      <div class="dialog-buttons">        <button @click="onConfirm">{{ props.ok }}</button>        <button @click="onClose">{{ props.cancel }}</button>      </div>    </div>  </div></template><style scoped>.confirm-delete-dialog {  position: fixed;  top: 0;  left: 0;  width: 100%;  height: 100%;  display: flex;  justify-content: center;  align-items: center;  z-index: 1000;}.dialog-overlay {  position: absolute;  top: 0;  left: 0;  width: 100%;  height: 100%;  background-color: rgba(0, 0, 0, 0.5);}.dialog-content {  background-color: #fff;  padding: 20px;  border-radius: 10px;  box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);  z-index: 1001;  text-align: center;}.dialog-content h2 {  margin-top: 0;  color: #009FFF;}.dialog-content p {  margin-bottom: 20px;}.dialog-buttons button {  padding: 10px 20px;  margin: 0 10px;  border: none;  border-radius: 5px;  cursor: pointer;  font-weight: bold;  color: white;  transition: all 0.3s ease-in-out;}.dialog-buttons button:first-child {  background: linear-gradient(45deg, #C70039, #FF5733);  box-shadow: 0 5px 10px rgba(199, 0, 57, 0.4);}.dialog-buttons button:first-child:hover {  transform: translateY(-3px);  box-shadow: 0 8px 15px rgba(199, 0, 57, 0.6);  background: linear-gradient(45deg, #FF5733, #FF8C00);}.dialog-buttons button:first-child:active {  transform: translateY(1px);  box-shadow: 0 3px 8px rgba(199, 0, 57, 0.8);  background: linear-gradient(45deg, #900C3F, #C70039);}.dialog-buttons button:last-child {  background: linear-gradient(45deg, #009FFF, #0066CC);  box-shadow: 0 5px 10px rgba(0, 159, 255, 0.4);}.dialog-buttons button:last-child:hover {  transform: translateY(-3px);  box-shadow: 0 8px 15px rgba(0, 159, 255, 0.6);  background: linear-gradient(45deg, #00BFFF, #0088EE);}.dialog-buttons button:last-child:active {  transform: translateY(1px);  box-shadow: 0 3px 10px rgba(0, 159, 255, 0.8);  background: linear-gradient(45deg, #0077DD, #0055AA);}</style>

在App.vue中的使用代码如下:

在这里插入图片描述编辑弹窗

效果预览:

在这里插入图片描述

此时App.vue代码如下:

<script setup>import zdp_table1 from "./zdpui/components/zdp_table1.vue";import zdp_page1 from "./zdpui/components/zdp_page1.vue";import random from "./zdpui/js/random.js";import {ref} from "vue";import zdp_confirm1 from "./zdpui/components/zdp_confirm1.vue";import zdp_modal1 from "./zdpui/components/zdp_modal1.vue";import Zdp_input1 from "./zdpui/components/zdp_input1.vue";const columns = [  {    title: "员工编号",    key: "id",    width: 80,    align: "center"  },  {    title: "姓名",    key: "name",    width: 100,    align: "center"  },  {    title: "年龄",    key: "age",    width: 100,    align: "center"  }]const page = ref(1);const size = ref(10);const total = ref(100);const data = ref(random.users(size.value))const onChangePage = (v) => {  page.value = v  const newData = random.getPageUser(      page.value,      size.value,  )  data.value = newData.data  total.value = total.value}const onEdit = (index, item) => {  console.log("编辑", index, item)  showEditDialog.value = true;}const onDelete = (index, item) => {  console.log("删除", index, item)  showDeleteDialog.value = true;}const showDeleteDialog = ref(false);const onConfirmDelete = () => {  console.log("确认删除");  showDeleteDialog.value = false;};const onCloseDeleteDialog = () => {  console.log("取消删除");  showDeleteDialog.value = false;};const showEditDialog = ref(false);const formData = ref({name: "张三", age: 23});const handleEditConfirm = (userData) => {  console.log('确认编辑操作,用户数据:', userData);  // 在这里添加编辑逻辑,如发送编辑请求等};const handleCloseDialog = () => {  showEditDialog.value = false;};</script><template>  <div>    <zdp_table1        :columns="columns"        :data="data"        @edit="onEdit"        @delete="onDelete"    />    <zdp_page1        :page="page"        :size="size"        :total="total"        @change="onChangePage"    />    <zdp_confirm1        :show="showDeleteDialog"        @confirm="onConfirmDelete"        @close="onCloseDeleteDialog"    />    <zdp_modal1        :show="showEditDialog"        @confirm="handleEditConfirm"        @close="handleCloseDialog"    >      <zdp_input1          label="姓名"          v-model="formData.name"          placeholder="请输入姓名"      />      <zdp_input1          label="年龄"          v-model="formData.age"          placeholder="请输入年龄"      />    </zdp_modal1>  </div></template>

继续封装按钮

到这一步的时候, 发现按钮有很多地方都是一样的, 重复的, 所以决定对按钮进行封装.

按钮组件的内容如下:

<script setup>import {defineProps, defineEmits} from 'vue';const props = defineProps({  text: {    type: String,    default: '按钮',  },  type: {    type: String,    // primary,danger    default: 'primary',  }})const emits = defineEmits(['click'])</script><template>  <button      @click="emits('click')"      :class="props.type"  >    {{ props.text }}  </button></template><style scoped>button {  padding: 10px 20px;  margin: 0 10px;  border: none;  border-radius: 5px;  cursor: pointer;  font-weight: bold;  color: white;  transition: all 0.3s ease-in-out;}button.danger {  background: linear-gradient(45deg, #C70039, #FF5733);  box-shadow: 0 5px 10px rgba(199, 0, 57, 0.4);}button.danger:hover {  transform: translateY(-3px);  box-shadow: 0 8px 15px rgba(199, 0, 57, 0.6);  background: linear-gradient(45deg, #FF5733, #FF8C00);}button.danger:active {  transform: translateY(1px);  box-shadow: 0 3px 8px rgba(199, 0, 57, 0.8);  background: linear-gradient(45deg, #900C3F, #C70039);}button.primary {  background: linear-gradient(45deg, #009FFF, #0066CC);  box-shadow: 0 5px 10px rgba(0, 159, 255, 0.4);}button.primary:hover {  transform: translateY(-3px);  box-shadow: 0 8px 15px rgba(0, 159, 255, 0.6);  background: linear-gradient(45deg, #00BFFF, #0088EE);}button.primary:active {  transform: translateY(1px);  box-shadow: 0 3px 10px rgba(0, 159, 255, 0.8);  background: linear-gradient(45deg, #0077DD, #0055AA);}</style>

使用方法如下:

<zdp_button1/><zdp_button1 type="danger"/>

在界面中的显示效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

总结

现在, 我们已经有了自己的按钮组件, 确认框组件, 编辑表单组件, 组件越来越多了.

不过这个时候, 组件之间的拆分, 组合也变得越来越复杂了, 比如这个编辑表单组件, 就因为有输入框组件, 按钮组件, 确认框组件等多个组件的组合, 显得很复杂, 样式调整稍微麻烦了一点点.

不过一切都还比较顺利!!!

继续做吧!!!

0 阅读:3
Python私教

Python私教

全栈工程师,目标人工智能.抖音同理想国真恵玩.