Paperxie 智能写作新体验:本科毕业论文一键定稿,告别熬夜晚稿难题
2026/5/14 9:45:04
v-bind绑定属性,v-on绑定事件(替代$(el).on())。ref/reactive),替代 jQuery 全局变量 / 数据缓存。<template> <div class="table-container"> <!-- 筛选栏 --> <div class="table-filter"> <input v-model="searchKey" @input="handleSearch" placeholder="搜索..." /> </div> <!-- 表格主体 --> <table class="vue-table"> <thead> <tr> <th v-for="col in columns" :key="col.key" @click="handleSort(col.key)"> {{ col.label }} <span v-if="sortKey === col.key">{{ sortOrder === 'asc' ? '↑' : '↓' }}</span> </th> </tr> </thead> <tbody> <tr v-for="(item, index) in tableData" :key="index"> <td v-for="col in columns" :key="col.key">{{ item[col.key] }}</td> </tr> </tbody> </table> <!-- 分页 --> <div class="table-pagination"> <button @click="prevPage" :disabled="currentPage === 1">上一页</button> <span>{{ currentPage }}/{{ totalPages }}</span> <button @click="nextPage" :disabled="currentPage === totalPages">下一页</button> </div> </div> </template> <script setup> import { ref, computed } from 'vue'; // 接收父组件传参(替代jQuery插件配置项) const props = defineProps({ columns: { type: Array, required: true, default: () => [] // 格式:[{ key: 'id', label: 'ID' }, ...] }, dataSource: { type: Array, required: true, default: () => [] }, pageSize: { type: Number, default: 10 } }); // 响应式状态(替代jQuery数据缓存) const searchKey = ref(''); const sortKey = ref(''); const sortOrder = ref('asc'); // asc/desc const currentPage = ref(1); // 计算属性(筛选+排序+分页后的数据) const filteredData = computed(() => { return props.dataSource.filter(item => Object.values(item).some(val => val.toString().includes(searchKey.value)) ).sort((a, b) => { if (!sortKey.value) return 0; return sortOrder.value === 'asc' ? a[sortKey.value] - b[sortKey.value] : b[sortKey.value] - a[sortKey.value]; }); }); // 分页相关计算 const totalPages = computed(() => Math.ceil(filteredData.value.length / props.pageSize)); const tableData = computed(() => { const start = (currentPage.value - 1) * props.pageSize; return filteredData.value.slice(start, start + props.pageSize); }); // 方法封装(替代jQuery插件方法) const handleSearch = () => { currentPage.value = 1; // 搜索后重置页码 }; const handleSort = (key) => { if (sortKey.value === key) { sortOrder.value = sortOrder.value === 'asc' ? 'desc' : 'asc'; } else { sortKey.value = key; sortOrder.value = 'asc'; } }; const prevPage = () => currentPage.value--; const nextPage = () => currentPage.value++; </script> <style scoped> /* 保留原jQuery组件样式,去除兼容前缀(如-webkit-),优化选择器 */ .table-container { width: 100%; overflow-x: auto; } .vue-table { width: 100%; border-collapse: collapse; } .vue-table th, .vue-table td { padding: 8px; border: 1px solid #eee; text-align: left; } .vue-table th { cursor: pointer; background: #f5f5f5; } .table-filter { margin-bottom: 16px; } .table-pagination { margin-top: 16px; text-align: right; } </style>| jQuery 实现方式 | Vue 3 替代方案 |
|---|---|
| $(el).html()渲染表格 | v-for模板渲染 + 响应式数据驱动 |
| $(el).on(‘click’, 排序) | @click事件绑定 + 响应式sortKey/sortOrder |
| 全局变量存储分页信息 | ref定义currentPage/pageSize |
| $.ajax请求数据后更新 DOM | 父组件传参dataSource+ 计算属性自动响应 |
| $(input).val()获取筛选值 | v-model绑定searchKey |
vue-virtual-scroller只渲染可视区域行,避免一次性渲染所有 DOM:<template> <virtual-scroller :items="tableData" :item-size="40" class="table-body"> <template #default="{ item }"> <tr> <td v-for="col in columns" :key="col.key">{{ item[col.key] }}</td> </tr> </template> </virtual-scroller> </template> <script setup> import { VirtualScroller } from 'vue-virtual-scroller'; import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'; </script>v-memo="[item.id]"缓存,仅当数据变化时重新渲染。import{debounce}from'lodash';// 或自定义防抖函数consthandleSearch=debounce(()=>{currentPage.value=1;},300);currentPage和pageSize请求接口),前端仅渲染当前页数据。event.stopPropagation()阻止冒泡,避免不必要的事件触发。defineAsyncComponent按需加载对应模块。ref+el.value(谨慎使用,优先数据驱动)。Vue 2+@vue/composition-api迁移,或添加polyfill。