You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

255 lines
5.9 KiB

2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
  1. <template>
  2. <!-- 表格容器 -->
  3. <div class="table-container">
  4. <!-- 题目数据表格 -->
  5. <table>
  6. <!-- 表头部分 -->
  7. <thead>
  8. <tr>
  9. <th>ID</th>
  10. <th>题干</th>
  11. <th>题目类型</th>
  12. <th @click="sort('errorCount')" class="sortable">
  13. <div class="sort-header">
  14. 出错次数
  15. <span v-if="sortField === 'errorCount'" class="sort-icon">
  16. <svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  17. <path d="M7 10L12 15L17 10" stroke="#e74c3c" stroke-width="2" />
  18. <path d="M12 15V3" stroke="#e74c3c" stroke-width="2" />
  19. </svg>
  20. </span>
  21. </div>
  22. </th>
  23. <th @click="sort('errorRate')" class="sortable">
  24. <div class="sort-header">
  25. 出错率
  26. <span v-if="sortField === 'errorRate'" class="sort-icon">
  27. <svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  28. <path d="M7 10L12 15L17 10" stroke="#e74c3c" stroke-width="2" />
  29. <path d="M12 15V3" stroke="#e74c3c" stroke-width="2" />
  30. </svg>
  31. </span>
  32. </div>
  33. </th>
  34. <th>推荐课程</th>
  35. <th>操作</th>
  36. </tr>
  37. </thead>
  38. <!-- 表格主体部分 -->
  39. <tbody>
  40. <!-- 示例数据行 -->
  41. <tr v-for="item in sortedItems" :key="item.id">
  42. <td>{{ item.id }}</td>
  43. <td>{{ item.questionText }}</td>
  44. <td>{{ item.type }}</td>
  45. <td>{{ item.errorCount }}</td>
  46. <td>{{ item.errorRate }}</td>
  47. <td>{{ item.recommendedCourse }}</td>
  48. <td>
  49. <button class="btn-red small">查看</button>
  50. <button class="btn-red small">修改</button>
  51. <button class="btn-red small">删除</button>
  52. </td>
  53. </tr>
  54. </tbody>
  55. </table>
  56. </div>
  57. </template>
  58. <script>
  59. export default {
  60. name: 'QuestionTable',
  61. data() {
  62. return {
  63. sortField: '', // 当前排序字段
  64. sortDirection: 'asc', // 排序方向:asc 或 desc
  65. items: [
  66. {
  67. id: 1,
  68. questionText: '以下哪项不是股票的基本特征?',
  69. type: '股票知识',
  70. errorCount: 50,
  71. errorRate: '50%',
  72. recommendedCourse: '量能擒牛'
  73. },
  74. {
  75. id: 2,
  76. questionText: '基金的风险主要来源于?',
  77. type: '基金知识',
  78. errorCount: 30,
  79. errorRate: '30%',
  80. recommendedCourse: '基本面分析'
  81. }
  82. ],
  83. sortedItems: [] // 用于存储排序后的结果
  84. }
  85. },
  86. // computed: {
  87. // sortedItems() {
  88. // if (!this.sortField) {
  89. // // 默认按 ID 升序
  90. // return this.items.sort((a, b) => a.id - b.id)
  91. // }
  92. //
  93. // return this.items.sort((a, b) => {
  94. // const aValue = a[this.sortField]
  95. // const bValue = b[this.sortField]
  96. //
  97. // // 处理数字和字符串
  98. // if (typeof aValue === 'number' && typeof bValue === 'number') {
  99. // return this.sortDirection === 'asc' ? aValue - bValue : bValue - aValue
  100. // } else {
  101. // const strA = String(aValue).toLowerCase()
  102. // const strB = String(bValue).toLowerCase()
  103. // return this.sortDirection === 'asc'
  104. // ? strA.localeCompare(strB)
  105. // : strB.localeCompare(strA)
  106. // }
  107. // })
  108. // }
  109. // },
  110. watch: {
  111. sortField: {
  112. handler() {
  113. this.updateSortedItems()
  114. },
  115. immediate: true // 初始时执行一次
  116. },
  117. sortDirection: {
  118. handler() {
  119. this.updateSortedItems()
  120. },
  121. immediate: true
  122. }
  123. },
  124. methods: {
  125. updateSortedItems() {
  126. if (!this.sortField) {
  127. this.sortedItems = [...this.items].sort((a, b) => a.id - b.id)
  128. return
  129. }
  130. const sorted = [...this.items].sort((a, b) => {
  131. const aValue = a[this.sortField]
  132. const bValue = b[this.sortField]
  133. if (typeof aValue === 'number' && typeof bValue === 'number') {
  134. return this.sortDirection === 'asc' ? aValue - bValue : bValue - aValue
  135. } else {
  136. const strA = String(aValue).toLowerCase()
  137. const strB = String(bValue).toLowerCase()
  138. return this.sortDirection === 'asc'
  139. ? strA.localeCompare(strB)
  140. : strB.localeCompare(strA)
  141. }
  142. })
  143. this.sortedItems = sorted
  144. },
  145. sort(field) {
  146. if (this.sortField === field) {
  147. this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc'
  148. } else {
  149. this.sortField = field
  150. this.sortDirection = 'asc'
  151. }
  152. }
  153. }
  154. }
  155. </script>
  156. <style scoped>
  157. /* 修改操作列按钮间距 */
  158. td:last-child {
  159. display: flex;
  160. gap: 16px; /* 将间距设置为16px */
  161. }
  162. th {
  163. display: table-cell !important;
  164. vertical-align: middle !important;
  165. }
  166. /* sort-header 样式 */
  167. .sort-header {
  168. display: flex;
  169. align-items: center;
  170. gap: 6px;
  171. }
  172. /* 排序图标样式 */
  173. .sort-icon svg {
  174. width: 12px;
  175. height: 12px;
  176. fill: none;
  177. stroke: #e74c3c;
  178. stroke-width: 2;
  179. transition: transform 0.2s;
  180. }
  181. /* 表格容器样式 */
  182. .table-container {
  183. width: 100%;
  184. border-collapse: collapse;
  185. margin-top: 10px;
  186. }
  187. /* 表格样式 */
  188. table {
  189. width: 100%;
  190. border-collapse: collapse;
  191. background-color: white;
  192. }
  193. /* 表格单元格样式 */
  194. th,
  195. td {
  196. padding: 12px;
  197. text-align: left;
  198. border-bottom: 1px solid #ddd;
  199. }
  200. /* 表头样式 */
  201. th {
  202. background-color: #f2f2f2;
  203. font-weight: normal;
  204. color: #333;
  205. cursor: pointer; /* 添加鼠标指针 */
  206. user-select: none; /* 防止文字选中 */
  207. }
  208. /* 可排序列样式 */
  209. .sortable {
  210. display: flex;
  211. align-items: center;
  212. gap: 6px;
  213. }
  214. /* 排序图标样式 */
  215. .sortable svg {
  216. width: 12px;
  217. height: 12px;
  218. fill: none;
  219. stroke: #e74c3c;
  220. stroke-width: 2;
  221. transition: transform 0.2s;
  222. }
  223. /* 悬停效果 */
  224. th:hover {
  225. background-color: #e0e0e0;
  226. }
  227. /* 表格行悬停效果 */
  228. tr:hover {
  229. background-color: #f9f9f9;
  230. }
  231. </style>