The model outputs a lot of meaningless 666666 endings.
Hi
I’ve recently been testing the chat model using Qwen2-72B-instruct. In some specific cases, after outputting a segment of normal content, it ends up outputting a large amount of meaningless “66666” content.
I ran the model with newest llama.cpp and followed the manual with the -fa parameter, tried all the Qwen/Qwen2-72B-Instruct-GGUF files from Q4 to Q8.
The current feeling for me is that Qwen/Qwen2-72B-Instruct may output a lot of meaningless 666 endings when the context is too long, but the strange thing is that I use this badcase to hugging face Qwen2-72B-Instruct playground without the same problem? I guess this might be an issue caused by the model being incompatible with llama.cpp?
Here's my badcase curl:
curl -L 'http://$IP:$PORT/completions' \
-H 'accept: application/jsonstream' \
-H 'Content-Type: application/json' \
--data-raw '{
"n_predict": 1920,
"temperature": 0.1,
"presence_penalty": 0.0,
"system_prompt": "You are a helpful assistant.",
"prompt": "```<template>\n\n <div\n\n class=\\\"ns-senior-table\\\"\n\n :class=\\\"[\n\n {\n\n [customClass]: customClass\n\n }\n\n ]\\\"\n\n >\n\n <div class=\\\"ns-senior-table__toolbox\\\">\n\n <div class=\\\"toolbox__top\\\">\n\n <div class=\\\"toolbox__left\\\">\n\n <div class=\\\"content\\\">\n\n <slot name=\\\"header-prepend\\\" />\n\n <div class=\\\"search\\\">\n\n <el-input\n\n v-if=\\\"useSearch\\\"\n\n ref=\\\"searchInput\\\"\n\n v-model.trim=\\\"keywords\\\"\n\n :placeholder=\\\"searchText\\\"\n\n :suffix-icon=\\\"Search\\\"\n\n clearable\n\n v-bind=\\\"filterInputProps\\\"\n\n
@input
=\\\"(...args) => handleInputEvent('\''input'\'', ...args)\\\"\n\n
@change
=\\\"(...args) => handleInputEvent('\''change'\'', ...args)\\\"\n\n
@focus
=\\\"(...args) => handleInputEvent('\''focus'\'', ...args)\\\"\n\n
@clear
=\\\"handleClear\\\"\n\n >\n\n <!-- <template #append>\n\n <el-button @click=\\\"handleShowSeniorSearch\\\" >高级查询</el-button>\n\n </template> -->\n\n </el-input>\n\n </div>\n\n </div>\n\n <slot name=\\\"header-append\\\" />\n\n </div>\n\n <div class=\\\"toolbox__right\\\">\n\n <slot name=\\\"toolbox-prepend\\\" />\n\n <el-tooltip v-if=\\\"useRefresh\\\" effect=\\\"dark\\\" content=\\\"刷新\\\" placement=\\\"top\\\">\n\n <div class=\\\"operation\\\" @click=\\\"handleRefresh\\\">\n\n <el-icon>\n\n <Refresh />\n\n </el-icon>\n\n </div>\n\n </el-tooltip>\n\n\n\n <el-tooltip v-if=\\\"useExport\\\" effect=\\\"dark\\\" content=\\\"导出表格\\\" placement=\\\"top\\\">\n\n <div class=\\\"operation\\\" @click=\\\"exportExcelFile\\\">\n\n <el-icon>\n\n <Download />\n\n </el-icon>\n\n </div>\n\n </el-tooltip>\n\n\n\n <el-tooltip v-if=\\\"useCustomColumn\\\" effect=\\\"dark\\\" content=\\\"自定义列\\\" placement=\\\"top\\\">\n\n <div ref=\\\"customColumnsTriggerRef\\\" class=\\\"operation\\\" @click=\\\"handleOpenCustomColumns\\\">\n\n <el-icon>\n\n <Grid />\n\n </el-icon>\n\n </div>\n\n </el-tooltip>\n\n\n\n <el-popover\n\n placement=\\\"bottom\\\"\n\n title=\\\"自定义列\\\"\n\n :width=\\\"180\\\"\n\n trigger=\\\"click\\\"\n\n virtual-triggering\n\n :virtual-ref=\\\"customColumnsTriggerRef\\\"\n\n :disabled=\\\"!useCustomColumn\\\"\n\n >\n\n <div class=\\\"custom-columns\\\">\n\n <el-checkbox\n\n v-model=\\\"customColumnsAll\\\"\n\n label=\\\"all\\\"\n\n value=\\\"all\\\"\n\n :indeterminate=\\\"notCompleteCheckAll\\\"\n\n
@change
=\\\"checkAllColumns\\\"\n\n >显示全部</el-checkbox\n\n >\n\n <el-checkbox-group v-model=\\\"customColumnsValues\\\"
@change
=\\\"handleCheckColumn\\\">\n\n <ul>\n\n <li v-for=\\\"(col, i) in customShowColumns\\\" :key=\\\"i\\\">\n\n <el-checkbox :label=\\\"col.props.prop\\\" :value=\\\"col.props.prop\\\" :title=\\\"col.props.label\\\">\n\n {{ col.props.label }}\n\n </el-checkbox>\n\n </li>\n\n </ul>\n\n </el-checkbox-group>\n\n </div>\n\n </el-popover>\n\n <slot name=\\\"toolbox-append\\\" />\n\n </div>\n\n </div>\n\n <div class=\\\"toolbox__bottom\\\">\n\n <slot name=\\\"header-bottom\\\" />\n\n <slot name=\\\"advance-query\\\">\n\n <NsLogicalQuery v-if=\\\"logicalQueryVisible\\\" class=\\\"mb-[10px]\\\" :fields=\\\"logicalFields\\\" />\n\n </slot>\n\n <ul v-if=\\\"filters.length\\\" class=\\\"filter-tags\\\">\n\n <li v-for=\\\"(filter, i) in filters\\\" :key=\\\"i\\\">\n\n <span class=\\\"filter-tag__label\\\">{{ filter.label }}</span>\n\n <span class=\\\"filter-tag__value\\\">\n\n {{ filterMethods[filter.type].getShowValue(filter.value, filter.config.valueFormat) }}\n\n </span>\n\n <el-icon class=\\\"filter-tag__close\\\" @click=\\\"filterMethods[filter.type].removeFilter(filter.key)\\\">\n\n <Close />\n\n </el-icon>\n\n </li>\n\n <li v-if=\\\"filters?.length\\\" class=\\\"clear-filter-btn\\\" @click=\\\"handleClearFilters\\\">清除</li>\n\n </ul>\n\n </div>\n\n </div>\n\n\n\n <el-card\n\n v-loading=\\\"isLoading\\\"\n\n class=\\\"table-card ns-senior-table__body\\\"\n\n :element-loading-text=\\\"loadingText\\\"\n\n :element-loading-spinner=\\\"LoadingIcon\\\"\n\n element-loading-svg-view-box=\\\"0, 0, 32, 32\\\"\n\n >\n\n <div class=\\\"ns-senior-table__body\\\">\n\n <el-table\n\n id=\\\"tableId\\\"\n\n ref=\\\"tableRef\\\"\n\n class=\\\"table-body\\\"\n\n :class=\\\"[\n\n {\n\n [elTableClass]: elTableClass\n\n }\n\n ]\\\"\n\n :data=\\\"paginData\\\"\n\n :empty-text=\\\"emptyText\\\"\n\n :show-overflow-tooltip=\\\"showOverflowTooltip\\\"\n\n :tooltip-options=\\\"tooltipOptions\\\"\n\n :height=\\\"tableHeight\\\"\n\n @sort-change=\\\"handleSortChange\\\"\n\n @selection-change=\\\"handleSelectionChange\\\"\n\n @row-click=\\\"handleRowClick\\\"\n\n >\n\n <el-table-column v-if=\\\"$slots.expand\\\" type=\\\"expand\\\">\n\n <template #default=\\\"args\\\">\n\n <slot name=\\\"expand\\\" :row=\\\"args.row\\\" />\n\n </template>\n\n </el-table-column>\n\n <el-table-column v-if=\\\"selectMode === '\''multiple'\''\\\" type=\\\"selection\\\" :width=\\\"selectionWidth\\\" fixed=\\\"left\\\" />\n\n <slot name=\\\"columns\\\">\n\n <template v-for=\\\"(col, i) in tableColumns\\\" :key=\\\"i\\\">\n\n <el-table-column v-bind=\\\"col.props\\\">\n\n <template #header=\\\"scope\\\">\n\n <div class=\\\"ns-senior-table__cell\\\" @click.stop>\n\n <VNode v-if=\\\"col.headerRender\\\" :content=\\\"col.headerRender\\\" :params=\\\"[scope]\\\" />\n\n <div v-else class=\\\"cell-content\\\">\n\n {{ scope.column.label }}\n\n </div>\n\n <template v-if=\\\"col.filter\\\">\n\n <el-popover placement=\\\"bottom\\\" :width=\\\"col.filter.layout?.width ?? 200\\\" trigger=\\\"click\\\">\n\n <template v-if=\\\"col.filter.type === '\''input'\''\\\">\n\n <el-input\n\n v-model.trim=\\\"filterState[col.props.prop].value\\\"\n\n v-bind=\\\"col.filter.props\\\"\n\n
@input
=\\\"(value) => handleFilterValueChange(col, value)\\\"\n\n />\n\n </template>\n\n <template v-if=\\\"col.filter.type === '\''checkbox'\''\\\">\n\n <el-checkbox-group\n\n v-model=\\\"filterState[col.props.prop].value\\\"\n\n
@change
=\\\"(value) => handleFilterValueChange(col, value)\\\"\n\n >\n\n <ul>\n\n <li v-for=\\\"(option, j) in col.filter.options ?? []\\\" :key=\\\"j\\\">\n\n <el-checkbox\n\n :label=\\\"option.value\\\"\n\n :value=\\\"option.value\\\"\n\n :disabled=\\\"!!option.disabled\\\"\n\n >{{ option.label }}</el-checkbox\n\n >\n\n </li>\n\n </ul>\n\n </el-checkbox-group>\n\n </template>\n\n <template #reference>\n\n <div\n\n class=\\\"filter-arrow\\\"\n\n :class=\\\"[\n\n {\n\n '\''is-active'\'': filterMethods[filterState[col.props.prop].type].isActive(\n\n filterState[col.props.prop].value\n\n )\n\n }\n\n ]\\\"\n\n >\n\n <el-icon><Filter /></el-icon>\n\n </div>\n\n </template>\n\n </el-popover>\n\n </template>\n\n </div>\n\n </template>\n\n <template #default=\\\"scope\\\">\n\n <VNode v-if=\\\"col.render\\\" :content=\\\"col.render\\\" :params=\\\"[scope]\\\" />\n\n <NsTableOperations\n\n v-else-if=\\\"col.props.prop === '\''opt'\''\\\"\n\n :operations=\\\"col.moreOperations?.operations ?? col.moreOperations(scope.row)\\\"\n\n :data=\\\"scope.row\\\"\n\n
@action
=\\\"(value) => handleAction(value, scope.row)\\\"\n\n />\n\n <span v-else class=\\\"ns-senior-table__text\\\">\n\n {{ _.get(scope.row, col.props.prop) }}\n\n </span>\n\n </template>\n\n <template #empty>\n\n <slot name=\\\"empty\\\">\n\n <div class=\\\"ns-senior-table__empty\\\">\n\n <div class=\\\"message\\\">{{ emptyText }}</div>\n\n </div>\n\n </slot>\n\n </template>\n\n </el-table-column>\n\n </template>\n\n </slot>\n\n </el-table>\n\n </div>\n\n <div ref=\\\"tableFooterRef\\\" class=\\\"ns-senior-table__footer\\\">\n\n <el-pagination\n\n v-model:current-page=\\\"paginIndex\\\"\n\n v-model:page-size=\\\"pageSize\\\"\n\n :page-sizes=\\\"sizeList\\\"\n\n :background=\\\"false\\\"\n\n small\n\n :layout=\\\"plugins\\\"\n\n :total=\\\"total\\\"\n\n @current-change=\\\"handleCurrentPageChange\\\"\n\n @size-change=\\\"sizeChange\\\"\n\n />\n\n </div>\n\n </el-card>\n\n </div>\n\n</template>\n\n\n\n<script setup>\n\nimport { computed, onMounted, ref, watch } from '\''vue'\''\n\nimport { Filter, Download, Grid, Refresh, Search, Close } from '\''@element-plus/icons-vue'\''\n\nimport { useDebounceFn, useElementBounding } from '\''@vueuse/core'\''\n\nimport _ from '\''lodash'\''\n\nimport VNode from '\''../vnode'\''\n\nimport {\n\n COMPONENT_NAME,\n\n LoadingIcon,\n\n TableConfig,\n\n seniorTableEmits,\n\n seniorTableProps,\n\n useFilter,\n\n usePagination\n\n} from '\''./__var__'\''\n\nimport { exportExcel } from '\''@/hooks'\''\n\nimport NsTableOperations from '\''@/components/common/table-operations.vue'\''\n\nimport NsLogicalQuery from '\''@/components/common/logical-query/logical-query.vue'\''\n\n\n\ndefineOptions({\n\n name: COMPONENT_NAME\n\n})\n\n\n\n// const tableInstance = getCurrentInstance()\n\nconst tableRef = ref()\n\nconst tableFooterRef = ref()\n\nconst props = defineProps(seniorTableProps)\n\nconst emit = defineEmits(seniorTableEmits)\n\n\n\nconst sortInfo = ref({})\n\nconst handleSortChange = (info) => {\n\n sortInfo.value = info\n\n}\n\n\n\nconst userData = computed(() => {\n\n const { column, order, prop } = sortInfo.value\n\n const sortMethod = _.get(column, '\''sortMethod'\'', null)\n\n const fn = sortMethod ? sortMethod : (a, b) => (JSON.stringify(a[prop]) > JSON.stringify(b[prop]) ? 1 : -1)\n\n const xs = _.cloneDeep(props.data)\n\n if (order === '\''ascending'\'') {\n\n xs.sort(fn)\n\n } else if (order === '\''descending'\'') {\n\n xs.sort((a, b) => -fn(a, b))\n\n }\n\n return xs\n\n})\n\nconst exceptColKeys = ['\''render'\'', '\''moreOperations'\'', '\''filter'\'']\n\n\n\nconst filterState = ref({})\n\nconst initFilterState = () => (filterState.value = {})\n\nconst handleClearFilters = () => {\n\n initFilterState()\n\n handleFilter()\n\n}\n\nconst filterMethods = {\n\n string: {\n\n isActive: (value) => !!value,\n\n getShowValue: (value, format) => {\n\n return _.isFunction(format) ? format(value) : value\n\n },\n\n removeFilter: (prop) => {\n\n filterState.value[prop].value = '\'''\''\n\n handleFilter()\n\n }\n\n },\n\n array: {\n\n isActive: (value) => !!value?.length,\n\n getShowValue: (values, format) => {\n\n const _values = values.map((val) => (_.isFunction(format) ? format(val) : val))\n\n return _values.join('\'', '\'')\n\n },\n\n removeFilter: (prop) => {\n\n filterState.value[prop].value = []\n\n handleFilter()\n\n }\n\n }\n\n}\n\nconst activatedFilters = computed(() => {\n\n return Object.keys(filterState.value).filter((key) => {\n\n return filterMethods[filterState.value[key].type].isActive(filterState.value[key].value)\n\n })\n\n})\n\nconst filters = computed(() => {\n\n return activatedFilters.value.map((key) => {\n\n return {\n\n key,\n\n ...filterState.value[key]\n\n }\n\n })\n\n})\n\nconst filterConditions = computed(() => {\n\n return filters.value.reduce((conditions, current) => {\n\n conditions[current.key] = current.value\n\n return conditions\n\n }, {})\n\n})\n\nwatch(\n\n () => filterConditions.value,\n\n (value) => {\n\n setConditions(value)\n\n }\n\n)\n\nconst initFilterFunc = {\n\n input: (colConf) => {\n\n const { filter, prop, label } = colConf\n\n const { defaultValue } = filter\n\n filterState.value[prop] = {\n\n type: '\''string'\'',\n\n value: defaultValue ?? '\'''\'',\n\n label: label ?? prop,\n\n config: filter\n\n }\n\n },\n\n checkbox: (colConf) => {\n\n const { filter, prop, label } = colConf\n\n const { defaultValue } = filter\n\n filterState.value[prop] = {\n\n type: '\''array'\'',\n\n value: _.isArray(defaultValue) ? defaultValue : [],\n\n label: label ?? prop,\n\n config: filter\n\n }\n\n }\n\n}\n\nconst userColumnsMappings = ref({})\n\nconst filterReturn = useFilter(userData, {\n\n strategy: '\''debounce'\'',\n\n props,\n\n userColumnsMappings,\n\n userFilterMethod: props.filterMethod\n\n})\n\nconst { keywords, data: filteredData, handleFilter, setConditions } = filterReturn\n\n\n\nconst handleFilterValueChange = useDebounceFn((col, value) => {\n\n const colName = col.props.prop\n\n filterState.value[colName].value = value\n\n handleFilter()\n\n})\n\n\n\nconst userColumns = computed(() => {\n\n const columns = props.columns ?? []\n\n return columns.map((col) => {\n\n const enableBindingProps = _.pickBy(col, (v, k) => !exceptColKeys.includes(k))\n\n const columnNode = {\n\n props: enableBindingProps\n\n }\n\n if (col.filter) {\n\n initFilterFunc[col.filter.type]?.(col)\n\n columnNode.filter = col.filter\n\n }\n\n if (col.render) columnNode.render = col.render\n\n if (col.headerRender) columnNode.headerRender = col.headerRender\n\n if (col.prop === '\''opt'\'') {\n\n let operations = []\n\n if (_.isFunction(col.moreOperations.getter)) {\n\n operations = col.moreOperations.getter\n\n } else if (_.isArray(col.moreOperations?.operations)) {\n\n operations = col.moreOperations\n\n }\n\n columnNode.moreOperations = operations\n\n }\n\n if (['\''datetime'\'', '\''date'\'', '\''time'\''].includes(col.type)) {\n\n const dtConfig = TableConfig.fields[col.type]\n\n columnNode.props.width = dtConfig.width\n\n columnNode.props.maxWidth = dtConfig.width\n\n }\n\n if (col.sortable) {\n\n columnNode.sortable = '\''custom'\''\n\n }\n\n userColumnsMappings.value[col.prop] = columnNode\n\n return columnNode\n\n })\n\n})\n\n\n\nconst logicalFields = computed(() =>\n\n props.columns?.map((column) => ({\n\n key: column.prop,\n\n label: column.label ?? column.prop\n\n }))\n\n)\n\n\n\nconst handleInputEvent = useDebounceFn((name, ...args) => {\n\n if (['\''input'\'', '\''change'\''].includes(props.filterTrigger) && (props.filterTrigger === name || name === '\''blur'\'')) {\n\n if (_.isFunction(props.filterMethod)) {\n\n props.filterMethod?.(keywords.value)\n\n } else {\n\n handleFilter?.(...args)\n\n }\n\n }\n\n if (name === '\''clear'\'') handleFilter?.(...args)\n\n emit(`search-${name}`, keywords.value, ...args)\n\n})\n\nconst handleClear = () => handleFilter()\n\n\n\nconst pagination = usePagination(filteredData, props)\n\nconst { index: paginIndex, data: paginData, pageSize, sizeList, plugins, total, handleSizeChange } = pagination\n\n\n\nconst handleCurrentPageChange = (...args) => {\n\n emit('\''page-change'\'', ...args)\n\n}\n\n\n\nconst sizeChange = (...args) => {\n\n handleSizeChange(...args)\n\n emit('\''page-size-change'\'', ...args)\n\n}\n\n\n\nwatch(\n\n userData,\n\n (newUserData) => {\n\n if (newUserData?.length) {\n\n initFilterState()\n\n }\n\n },\n\n {\n\n immediate: true\n\n }\n\n)\n\n\n\n// Loading\n\nconst isLoading = computed(() => props.loading)\n\n\n\n// Check rows\n\nconst toggleAllSelection = (isChecked) => {\n\n if (isChecked) {\n\n tableRef.value?.toggleAllSelection(isChecked)\n\n } else {\n\n tableRef.value?.clearSelection()\n\n }\n\n}\n\n\n\nconst getSelections = () => {\n\n return tableRef.value?.getSelectionRows()\n\n}\n\n\n\nconst handleSelectionChange = (...args) => {\n\n emit('\''selection-change'\'', ...args)\n\n}\n\n\n\nconst logicalQueryVisible = ref(false)\n\n// const handleShowSeniorSearch = () => {\n\n// logicalQueryVisible.value = !logicalQueryVisible.value\n\n// }\n\n\n\n// Table functions\n\nconst handleRefresh = () => {\n\n emit('\''refresh'\'')\n\n}\n\n\n\nconst exportData = computed(() => {\n\n const selections = getSelections()\n\n if (selections?.length) return selections\n\n return filteredData.value\n\n})\n\n\n\nconst exportColumns = computed(() => {\n\n if (props.exportColumn === '\''visible'\'') return tableColumns.value\n\n return userColumns.value\n\n})\n\n\n\nconst exportExcelFile = () => {\n\n if (_.isFunction(props.exportMethod)) {\n\n props.exportMethod?.()\n\n return\n\n }\n\n\n\n // :export-filename=\\\"exportFilename\\\"\n\n const exportParams = [\n\n exportData.value,\n\n exportColumns.value,\n\n `${props.exportFilename ? `${props.exportFilename}` : '\'''\''}${Date.now()}`\n\n ]\n\n if (props.beforeExport && _.isFunction(props.beforeExport)) {\n\n const result = props.beforeExport(...exportParams)\n\n if (!result) return\n\n if (result.then) {\n\n result.then((userParams) => {\n\n emit('\''export'\'')\n\n exportExcel(...userParams)\n\n emit('\''after-export'\'')\n\n })\n\n return\n\n }\n\n }\n\n emit('\''export'\'')\n\n exportExcel(...exportParams)\n\n emit('\''after-export'\'')\n\n}\n\n\n\n// Custom columns\n\nconst customColumnsTriggerRef = ref()\n\nconst customColumnsVisible = ref(false)\n\nconst handleOpenCustomColumns = () => {\n\n customColumnsVisible.value = !customColumnsVisible.value\n\n}\n\nconst customColumnsConfig = computed(() => props.customColumnsConfig)\n\n\n\n// 可以通过”自定义列“功能控制的列\n\nconst customShowColumns = computed(() => {\n\n const excludes = customColumnsConfig.value.excludes ?? []\n\n const showColumns = customColumnsConfig.value.showColumns\n\n if (_.isArray(showColumns)) return showColumns\n\n return userColumns.value.filter((col) => {\n\n return !excludes.includes(col.props.prop)\n\n })\n\n})\n\n\n\nconst customColumnsAll = ref(false)\n\nconst customColumnsValues = ref([])\n\nconst notCompleteCheckAll = computed(() => {\n\n const checkedLength = customColumnsValues.value.length\n\n return checkedLength !== 0 && checkedLength !== customShowColumns.value.length\n\n})\n\nconst checkAllColumns = (isCheckAll) => {\n\n customColumnsValues.value = isCheckAll ? customShowColumns.value.map((col) => col.props.prop) : []\n\n emit('\''custom-columns-change'\'', customColumnsValues.value)\n\n}\n\nconst handleCheckColumn = (columnProps) => {\n\n customColumnsValues.value = columnProps\n\n customColumnsAll.value = columnProps.length === customShowColumns.value.length\n\n emit('\''custom-columns-change'\'', customColumnsValues.value)\n\n}\n\nconst handleAction = (...args) => emit('\''operate'\'', ...args)\n\n\n\nconst tableColumns = computed(() => {\n\n const excludes = customColumnsConfig.value.excludes ?? []\n\n return props.useCustomColumn\n\n ? userColumns.value.filter((col) => {\n\n return customColumnsValues.value.includes(col.props.prop) || excludes.includes(col.props.prop)\n\n })\n\n : userColumns.value\n\n})\n\nconst columnsProps = computed(() => {\n\n return userColumns.value.map((col) => col.props.prop)\n\n})\n\n\n\nif (props.useCustomColumn) {\n\n watch(\n\n () => {\n\n const config = customColumnsConfig.value\n\n if (_.isArray(config?.defaultChecked)) {\n\n return config.defaultChecked\n\n }\n\n if (_.isArray(config?.defaultChecked?.value)) {\n\n return config.defaultChecked.value\n\n }\n\n },\n\n (value) => {\n\n if (!value?.length) {\n\n handleCheckColumn(columnsProps.value)\n\n return\n\n }\n\n handleCheckColumn(value ?? [])\n\n },\n\n {\n\n immediate: true\n\n }\n\n )\n\n}\n\n\n\n// table events\n\nconst handleRowClick = (...args) => {\n\n emit('\''row-click'\'', ...args)\n\n}\n\n\n\n// 检测页面高度\n\nconst tableBounding = ref()\n\nconst tableHeight = ref('\''100%'\'')\n\nconst bindingTest = () => {\n\n tableBounding.value = useElementBounding(tableRef.value.$el)\n\n}\n\nconst tableBundingWatcher = useDebounceFn((tableTop) => {\n\n const { height } = useElementBounding(tableFooterRef.value)\n\n tableHeight.value = `calc(100vh - ${height.value + 24}px - ${tableTop}px)`\n\n})\n\nwatch(() => tableBounding.value?.top, tableBundingWatcher, { immediate: true })\n\n\n\n// Vue mounts\n\n\n\nonMounted(() => {\n\n if (props.fixed) bindingTest()\n\n})\n\n\n\ndefineExpose({\n\n getSelections,\n\n toggleAllSelection\n\n})\n\n</script>\n\n\n\n<style lang=\\\"less\\\">\n\n@table: ns-senior-table;\n\n\n\n.@{table} {\n\n --st-search-input-width: 300px;\n\n .el-table__header-wrapper {\n\n position: sticky;\n\n top: 0;\n\n z-index: 3;\n\n }\n\n &__toolbox {\n\n display: flex;\n\n flex-direction: column;\n\n align-items: flex-start;\n\n border-top: solid 1px transparent;\n\n border-bottom: solid 1px transparent;\n\n transition: var(--el-transition-all);\n\n padding-right: 20px;\n\n .toolbox__top {\n\n display: flex;\n\n width: 100%;\n\n margin-bottom: 10px;\n\n & > .toolbox__left,\n\n & > .toolbox__right {\n\n display: flex;\n\n align-items: flex-start;\n\n flex: 1;\n\n }\n\n & > .toolbox__left {\n\n .content {\n\n display: flex;\n\n padding: 0;\n\n .search {\n\n .el-input {\n\n width: var(--st-search-input-width);\n\n }\n\n }\n\n }\n\n }\n\n & > .toolbox__right {\n\n display: flex;\n\n justify-content: flex-end;\n\n align-items: center;\n\n .operation {\n\n font-size: 16px;\n\n cursor: pointer;\n\n &:not(&:first-child) {\n\n margin-left: var(--n-small-space);\n\n }\n\n }\n\n }\n\n }\n\n .toolbox__bottom {\n\n .filter-tags {\n\n display: flex;\n\n margin-bottom: 10px;\n\n li {\n\n display: inline-flex;\n\n align-items: center;\n\n margin-right: 10px;\n\n border: solid 1px var(--el-color-primary);\n\n border-radius: var(--el-border-radius-round);\n\n padding-left: 10px;\n\n font-size: var(--el-font-size-base);\n\n &.clear-filter-btn {\n\n padding: 0 5px;\n\n cursor: pointer;\n\n border: none;\n\n &:hover {\n\n color: var(--el-color-danger);\n\n }\n\n }\n\n .filter-tag__label {\n\n color: var(--el-text-color-secondary);\n\n margin-right: 4px;\n\n }\n\n .filter-tag__value {\n\n color: var(--el-color-primary);\n\n }\n\n .filter-tag__close {\n\n margin: 0 4px;\n\n cursor: pointer;\n\n transition: var(--el-transition-all);\n\n &:hover {\n\n color: var(--el-color-primary);\n\n }\n\n }\n\n }\n\n }\n\n }\n\n &.is-fixed {\n\n background-color: #f3f4f7;\n\n border-color: #f3f4f7;\n\n margin-left: -20px;\n\n margin-right: -20px;\n\n padding: 20px 40px 20px 20px;\n\n }\n\n }\n\n &__body {\n\n border-top: solid 1px transparent;\n\n transition: var(--el-transition-all);\n\n &.is-fixed {\n\n background-color: #f3f4f7;\n\n border-color: #f3f4f7;\n\n margin-left: -20px;\n\n margin-right: -20px;\n\n margin-top: 20px;\n\n padding: 0 20px;\n\n }\n\n }\n\n &__footer {\n\n display: flex;\n\n justify-content: flex-end;\n\n height: 50px;\n\n padding-right: var(--n-large-space);\n\n z-index: 3;\n\n background-color: white;\n\n border-top: solid 1px #eee;\n\n border-bottom: solid 1px #eee;\n\n transition: var(--el-transition-all);\n\n &.is-fixed {\n\n background-color: white;\n\n border-color: #eee;\n\n margin-left: -20px;\n\n margin-right: -20px;\n\n padding: 0 40px;\n\n }\n\n }\n\n &__empty {\n\n display: flex;\n\n justify-content: center;\n\n align-items: center;\n\n flex-direction: column;\n\n line-height: normal;\n\n height: 80px;\n\n color: var(--el-color-primary);\n\n .icon {\n\n margin-bottom: 4px;\n\n }\n\n }\n\n &__text {\n\n display: -webkit-box;\n\n text-overflow: ellipsis;\n\n overflow: hidden;\n\n -webkit-line-clamp: 3;\n\n -webkit-box-orient: vertical;\n\n white-space: pre-line;\n\n font-size: 12px;\n\n }\n\n &__cell {\n\n display: inline-flex;\n\n align-items: center;\n\n .filter-arrow {\n\n display: inline-flex;\n\n justify-content: center;\n\n align-items: center;\n\n margin-left: 10px;\n\n cursor: pointer;\n\n &.is-active {\n\n color: var(--el-color-primary);\n\n }\n\n }\n\n }\n\n}\n\n\n\n.custom-columns {\n\n ul {\n\n list-style: none;\n\n margin: 0;\n\n padding: 0;\n\n li {\n\n .el-checkbox {\n\n width: 100%;\n\n }\n\n .el-checkbox__label {\n\n overflow: hidden;\n\n white-space: nowrap;\n\n text-overflow: ellipsis;\n\n }\n\n }\n\n }\n\n}\n\n\n\n.table-cell-tooltip {\n\n width: 300px;\n\n}\n\n\n\n.table-cell-tooltip--large {\n\n width: 800px;\n\n}\n\n</style>\n\n```\n给这段代码实现打个分,评价一下编写水平\n"
}'
The returned content is stable with a large number of nonsensical 6666 endings, and I'll put one of them here:
这段代码是一个基于Vue 3和Element Plus的高级表格组件的实现,它包含了丰富的功能,如搜索、过滤、分页、排序、导出、自定义列显示等。以下是对这段代码实现的评价:
1. **组件化和模块化**:代码使用了Vue 3的Composition API,这使得状态管理和逻辑处理更加清晰和模块化。通过`defineProps`和`defineEmits`定义了组件的属性和事件,这有助于组件的复用和维护。
2. **状态管理**:使用了`ref`和`computed`来管理组件的状态,这使得状态的响应式和计算逻辑更加直观。例如,`userData`和`filteredData`的计算逻辑清晰地展示了数据的过滤和排序过程。
3. **事件处理和交互**:事件处理逻辑清晰,如`handleFilter`、`handleSelectionChange`等,这些函数的命名和实现都遵循了良好的实践,易于理解和维护。
4. **性能优化**:使用了`useDebounceFn`来防抖搜索和过滤操作,这有助于提高组件在大量数据下的性能。同时,通过`watch`监听数据变化,确保了组件状态的实时更新。
5. **自定义和扩展性**:组件提供了丰富的自定义选项,如`filterMethod`、`exportMethod`等,这使得组件可以适应不同的业务需求。同时,通过`useCustomColumn`支持了列的000066666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666 6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666 6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666 66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666 66666666666666666666666666666666666666666666666666666666666666666666666666166666666666666666666666666666666666666666666666666666666666666666666666 666666666666666666666636666666666666666666666666 66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666 666666666666666666666666666666666666666666666666666666 6666666666666666666666666616666666666666666666666666 66666666666666666666616666666666666666666666666666666666666666666666666666666