$emit(update:xxx)
时间: 2023-11-21 09:55:34 浏览: 120
`$emit(update:xxx)`是Vue.js中的一个自定义事件,用于在子组件中向父组件传递数据。其中`xxx`是自定义的事件名称,可以根据需要进行更改。在子组件中使用`$emit(update:xxx)`触发该事件,并将需要传递的数据作为参数传入。在父组件中,可以通过在子组件上使用`.sync`修饰符来监听该事件,并在事件触发时更新父组件中的数据。以下是一个简单的示例:
子组件中触发自定义事件:
```javascript
this.$emit('update:count', this.count)
```
父组件中监听自定义事件:
```html
<template>
<div>
<child-component :count.sync="parentCount"></child-component>
<p>Parent Count: {{ parentCount }}</p>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
data() {
return {
parentCount: 0
}
}
}
</script>
```
在上面的示例中,子组件中触发了一个名为`update:count`的自定义事件,并将`this.count`作为参数传入。在父组件中,我们使用`.sync`修饰符将`parentCount`与子组件中的`count`进行双向绑定。当子组件中触发了`update:count`事件时,父组件中的`parentCount`会自动更新为子组件中的`count`。
阅读全文
相关推荐













<script setup lang="tsx"> import { DataTableSortState,NButton, NPopconfirm, NTag, SelectOption } from "naive-ui"; import { fetchGetChangeLedgerList,fetchBatchDeleteChange,fetchDeleteChange,clearDeptCache } from "@/service/api"; import { $t } from "@/locales"; import { useAppStore } from "@/store/modules/app"; import { useTable, useTableOperate } from "@/hooks/common/table"; import { useAuth } from "@/hooks/business/auth"; import LedgerSearch from "./modules/ledger-search.vue"; import { useBoolean } from "@sa/hooks"; import { canUpgradeRecord } from "@/constants/business"; import { ref, onMounted, watch } from "vue"; // import {useDepartment} from "@/hooks/common/useDepartment" import { exportXlsx, SheetData } from "@/utils/export-excel"; // 导入嵌入模态框 import { getFullDeptOptions } from "@/service/api/"; // 导入完整部门选项服务 import useTableSort from "@/hooks/common/useTableSort" import tableDownload from "@/components/common/table-Download.vue"; // 存储完整部门选项 const fullDeptOptions = ref<SelectOption[]>([]); // 加载完整部门列表 onMounted(async () => { fullDeptOptions.value = await getFullDeptOptions(); }); const appStore = useAppStore(); const { columns, columnChecks, data, getData, loading, mobilePagination, searchParams, resetSearchParams, } = useTable({ apiFn: fetchGetChangeLedgerList, showTotal: true, apiParams: { current: 1, size: 10, // if you want to use the searchParams in Form, you need to define the following properties, and the value is null // the value can not be undefined, otherwise the property in Form will not be reactive source: null, pecoName: null, peco: null, softwareChange: null, projectno: null, dept: null, canUpgrade: null, softResponsiblePerson: null, elecResponsiblePerson: null, changeResponsiblePerson: null, customerDemandTime: null, softCompletionTime:null, hardCompletionTime: null, fmtCustomerDemandTime:null, fmtSoftCompletionTime:null, fmtHardCompletionTime: null, }, columns: () => [ { type: "selection", align: "center", width: 48, }, { key: "index", title: $t("common.index"), align: "center", width: 64, sorter: true, }, { key: "hwswcoId", title: $t("page.change.ledger.hwswcoId"), align: "center", minWidth: 50, sorter: true, render: (row) => ( {row.hwswcoId} ), }, { key: "source", title: $t("page.change.ledger.source"), align: "center", width: 50, sorter: true, }, { key: "pecoName", title: $t("page.change.ledger.pecoName"), align: "center", minWidth: 50, sorter: true, }, { key: "peco", title: $t("page.change.ledger.peco"), align: "center", minWidth: 50, sorter: true, }, { key: "softwareChange", title: $t("page.change.ledger.softwareChange"), align: "center", minWidth: 150, sorter: true, }, { key: "projectno", title: $t("page.change.ledger.projectno"), align: "center", minWidth: 50, sorter: true, }, { key: "dept", title: $t("page.change.ledger.dept"), align: "center", width: 130, sorter: true, render: (row) => { // 使用完整部门选项映射部门名称 if (row.dept && fullDeptOptions.value.length > 0) { const dept = fullDeptOptions.value.find( (option) => option.value === row.dept ); if (dept) { return ( <NTag type="info" class="dept-tag"> {dept.label} </NTag> ); } } return null; }, }, { key: "softResponsiblePersonName", title: $t("page.change.ledger.softResponsiblePersonName"), align: "center", minWidth: 50, sorter: true, }, { key: "elecResponsiblePersonName", title: $t("page.change.ledger.elecResponsiblePersonName"), align: "center", minWidth: 50, sorter: true, }, // { // key: "changeResponsiblePerson", // title: $t("page.change.ledger.changeResponsiblePerson"), // align: "center", // minWidth: 50, // }, { key: "canUpgrade", title: $t("page.change.ledger.canUpgrade"), align: "center", minWidth: 50, sorter: true, render: (row) => { console.log(row.canUpgrade) if (row.canUpgrade) { // console.log( row.canUpgrade, canUpgradeRecord[ // row.canUpgrade as Api.Change.canUpgrade // ]) const label = $t( canUpgradeRecord[ row.canUpgrade as Api.Change.canUpgrade ] ); return <NTag type="default">{label}</NTag>; } return null; }, }, { key: "fmtCustomerDemandTime", title: $t("page.change.ledger.customerDemandTime"), align: "center", minWidth: 50, sorter: true, }, { key: "fmtSoftCompletionTime", title: $t("page.change.ledger.softCompletionTime"), align: "center", minWidth: 50, sorter: true, }, { key: "fmtHardCompletionTime", title: $t("page.change.ledger.hardCompletionTime"), align: "center", minWidth: 50, sorter: true, }, // { // key: "fmtPlanCompletionTime", // title: $t("page.change.ledger.planCompletionTime"), // align: "center", // minWidth: 50, // }, { key: "operate", title: $t("common.operate"), align: "center", width: 130, render: (row) => ( {hasAuth("B_ChangeLedger_Upgrade") ? ( <NButton type="primary" ghost size="small" onClick={() => window.open(${row.hwswco_upgrade_url}${row.hwswcoId}.html,"_blank")} > {$t("common.upgrade")} </NButton> ) : null} {hasAuth("B_ChangeLedger_Assign") ? ( <NButton type="primary" ghost size="small" onClick={() => window.open(${row.hwswco_url}${row.hwswcoId}.html,"_blank")} > {$t("common.assign")} </NButton> ) : null} ), }, ], }); const { drawerVisible, operateType, editingData, handleAdd, handleEdit, handleClone, checkedRowKeys, onBatchDeleted, onDeleted, // closeDrawer } = useTableOperate(data, getData); // 定义排序器 const sorter = ref<DataTableSortState | null>(null); // 使用自定义钩子 const { sortTable } = useTableSort(data, sorter); // 处理排序器变化 const handleSorterChange = (newSorter: DataTableSortState) => { sorter.value = newSorter; }; const { hasAuth } = useAuth(); const { bool: uploadVisible, setTrue: openModal } = useBoolean(); async function handleBatchDelete() { // request const { error } = await fetchBatchDeleteChange({ ids: checkedRowKeys.value, }); if (!error) { onBatchDeleted(); } } async function handleDelete(id: number) { // request const { error } = await fetchDeleteChange({ id }); if (!error) { onDeleted(); } } function edit(id: number) { handleEdit(id); } function clone(id: number) { handleClone(id); } interface Emits { (e: "update-total", payload: number | undefined): void; } const emit = defineEmits<Emits>(); watch( () => mobilePagination.value.itemCount, (newVal, oldVal) => { emit("update-total", newVal); }, { deep: true }, ); async function handleDownload() { // 请求cosnt {data, error } = await fetchGetProblemList({size:xxx,current:1}) const { data:responseData, error } = await fetchGetChangeLedgerList({ size: checkedRowKeys.value.length, current: 1, ids: checkedRowKeys.value, }); if (error) { console.error("获取数据时出错:", error); alert("获取数据时发生错误,请稍后再试。"); return; } // 关键修改:将部门ID转换为部门名称 const processedRecords = responseData.records.map(record => { // 查找匹配的部门选项 const deptOption = fullDeptOptions.value.find( option => option.value === record.dept ); // 转换canUpgrade数值为文本标签 const upgradeLabel = canUpgradeRecord[record.canUpgrade as keyof typeof canUpgradeRecord] ? $t(canUpgradeRecord[record.canUpgrade as keyof typeof canUpgradeRecord]) : record.canUpgrade; // 未匹配时保留原值 // 返回新对象(保留原数据,替换dept和canUpgrade字段) return { ...record, dept: deptOption ? deptOption.label : record.dept, canUpgrade: upgradeLabel // 替换为转换后的文本 }; }); // 翻译表头 const titleMap = { hwswcoId: $t("page.change.ledger.hwswcoId"), source: $t("page.change.ledger.source"), pecoName: $t("page.change.ledger.pecoName"), peco: $t("page.change.ledger.peco"), softwareChange:$t("page.change.ledger.softwareChange"), projectno: $t("page.change.ledger.projectno"), dept: $t("page.change.ledger.dept"), softResponsiblePersonName: $t("page.change.ledger.softResponsiblePersonName"), elecResponsiblePersonName: $t("page.change.ledger.elecResponsiblePersonName"), canUpgrade: $t("page.change.ledger.canUpgrade"), // customerDemandTime: $t("page.change.ledger.customerDemandTime"), // softCompletionTime: $t("page.change.ledger.softCompletionTime"), // hardCompletionTime: $t("page.change.ledger.hardCompletionTime"), fmtCustomerDemandTime: $t("page.change.ledger.fmtCustomerDemandTime"), fmtSoftCompletionTime: $t("page.change.ledger.fmtSoftCompletionTime"), fmtHardCompletionTime: $t("page.change.ledger.fmtHardCompletionTime"), }; const headers = Object.keys(titleMap).map((key) => titleMap[key]); const sheetData = [headers]; processedRecords.forEach(record => { const row = Object.keys(titleMap).map(key => record[key]); sheetData.push(row); }); const sheetName = $t("page.change.ledger.title"); const sheets: SheetData[] = [ { sheetName: sheetName, data: sheetData, }, ]; exportXlsx(sheets, ${sheetName}); } // 在页面加载时获取最新数据 getData(); </script> <template> <LedgerSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getData" /> <NCard :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper" > <template #header> {{ $t('page.change.ledger.title') }} <NTag type="info" round v-if="mobilePagination?.itemCount !== undefined"> {{ mobilePagination.itemCount }} </NTag> </template> <template #header-extra> <template #default> <NButton size="small" @click="handleDownload" type="primary" ghost> <template #icon> <icon-mdi-tray-download class="text-icon" :class="{ 'animate-spin': loading }" /> </template> {{ $t("common.download") }} </NButton> </template> </template> <NDataTable v-model:checked-row-keys="checkedRowKeys" :columns="columns" :data="data" size="small" :flex-height="!appStore.isMobile" :scroll-x="962" :loading="loading" remote :row-key="(row) => row.id" :pagination="mobilePagination" class="sm:h-full" @update:sorter="handleSorterChange" /> </NCard> </template> <style scoped></style> 如果没是有选中任何id,则提示请选择需要导出的数据!


<script setup lang="tsx"> import { NButton, NPopconfirm, NTag, SelectOption } from "naive-ui"; import { fetchGetChangeLedgerList,fetchBatchDeleteChange,fetchDeleteChange,clearDeptCache } from "@/service/api"; import { $t } from "@/locales"; import { useAppStore } from "@/store/modules/app"; import { useTable, useTableOperate } from "@/hooks/common/table"; import { useAuth } from "@/hooks/business/auth"; import LedgerSearch from "./modules/ledger-search.vue"; import { useBoolean } from "@sa/hooks"; import { canUpgradeRecord } from "@/constants/business"; import { ref, onMounted, watch } from "vue"; // import {useDepartment} from "@/hooks/common/useDepartment" import { exportXlsx, SheetData } from "@/utils/export-excel"; // 导入嵌入模态框 import { getFullDeptOptions } from "@/service/api/"; // 导入完整部门选项服务 // 存储完整部门选项 const fullDeptOptions = ref<SelectOption[]>([]); // 加载完整部门列表 onMounted(async () => { fullDeptOptions.value = await getFullDeptOptions(); }); const appStore = useAppStore(); const { columns, columnChecks, data, getData, loading, mobilePagination, searchParams, resetSearchParams, } = useTable({ apiFn: fetchGetChangeLedgerList, showTotal: true, apiParams: { current: 1, size: 10, // if you want to use the searchParams in Form, you need to define the following properties, and the value is null // the value can not be undefined, otherwise the property in Form will not be reactive source: null, pecoName: null, peco: null, softwareChange: null, projectno: null, dept: null, canUpgrade: null, softResponsiblePerson: null, elecResponsiblePerson: null, changeResponsiblePerson: null, customerDemandTime: null, softCompletionTime:null, hardCompletionTime: null, fmtCustomerDemandTime:null, fmtSoftCompletionTime:null, fmtHardCompletionTime: null, }, columns: () => [ { type: "selection", align: "center", width: 48, }, { key: "index", title: $t("common.index"), align: "center", width: 64, }, { key: "hwswcoId", title: $t("page.change.ledger.hwswcoId"), align: "center", minWidth: 50, render: (row) => ( {row.hwswcoId} ), }, { key: "source", title: $t("page.change.ledger.source"), align: "center", width: 50, }, { key: "pecoName", title: $t("page.change.ledger.pecoName"), align: "center", minWidth: 50, }, { key: "peco", title: $t("page.change.ledger.peco"), align: "center", minWidth: 50, }, { key: "softwareChange", title: $t("page.change.ledger.softwareChange"), align: "center", minWidth: 150, }, { key: "projectno", title: $t("page.change.ledger.projectno"), align: "center", minWidth: 50, }, { key: "dept", title: $t("page.change.ledger.dept"), align: "center", width: 130, render: (row) => { // 使用完整部门选项映射部门名称 if (row.dept && fullDeptOptions.value.length > 0) { const dept = fullDeptOptions.value.find( (option) => option.value === row.dept ); if (dept) { return ( <NTag type="info" class="dept-tag"> {dept.label} </NTag> ); } } return null; }, }, { key: "softResponsiblePersonName", title: $t("page.change.ledger.softResponsiblePersonName"), align: "center", minWidth: 50, }, { key: "elecResponsiblePersonName", title: $t("page.change.ledger.elecResponsiblePersonName"), align: "center", minWidth: 50, }, // { // key: "changeResponsiblePerson", // title: $t("page.change.ledger.changeResponsiblePerson"), // align: "center", // minWidth: 50, // }, { key: "canUpgrade", title: $t("page.change.ledger.canUpgrade"), align: "center", minWidth: 50, render: (row) => { console.log(row.canUpgrade) if (row.canUpgrade) { // console.log( row.canUpgrade, canUpgradeRecord[ // row.canUpgrade as Api.Change.canUpgrade // ]) const label = $t( canUpgradeRecord[ row.canUpgrade as Api.Change.canUpgrade ] ); return <NTag type="default">{label}</NTag>; } return null; }, }, { key: "fmtCustomerDemandTime", title: $t("page.change.ledger.customerDemandTime"), align: "center", minWidth: 50, }, { key: "fmtSoftCompletionTime", title: $t("page.change.ledger.softCompletionTime"), align: "center", minWidth: 50, }, { key: "fmtHardCompletionTime", title: $t("page.change.ledger.hardCompletionTime"), align: "center", minWidth: 50, }, // { // key: "fmtPlanCompletionTime", // title: $t("page.change.ledger.planCompletionTime"), // align: "center", // minWidth: 50, // }, { key: "operate", title: $t("common.operate"), align: "center", width: 130, render: (row) => ( {hasAuth("B_ChangeLedger_Upgrade") ? ( <NButton type="primary" ghost size="small" onClick={() => window.open(${row.hwswco_upgrade_url}${row.hwswcoId}.html,"_blank")} > {$t("common.upgrade")} </NButton> ) : null} {hasAuth("B_ChangeLedger_Assign") ? ( <NButton type="primary" ghost size="small" onClick={() => window.open(${row.hwswco_url}${row.hwswcoId}.html,"_blank")} > {$t("common.assign")} </NButton> ) : null} ), }, ], }); const { drawerVisible, operateType, editingData, handleAdd, handleEdit, handleClone, checkedRowKeys, onBatchDeleted, onDeleted, // closeDrawer } = useTableOperate(data, getData); const { hasAuth } = useAuth(); const { bool: uploadVisible, setTrue: openModal } = useBoolean(); async function handleBatchDelete() { // request const { error } = await fetchBatchDeleteChange({ ids: checkedRowKeys.value, }); if (!error) { onBatchDeleted(); } } async function handleDelete(id: number) { // request const { error } = await fetchDeleteChange({ id }); if (!error) { onDeleted(); } } function edit(id: number) { handleEdit(id); } function clone(id: number) { handleClone(id); } interface Emits { (e: "update-total", payload: number | undefined): void; } const emit = defineEmits<Emits>(); watch( () => mobilePagination.value.itemCount, (newVal, oldVal) => { emit("update-total", newVal); }, { deep: true }, ); async function handleDownload() { // 请求cosnt {data, error } = await fetchGetProblemList({size:xxx,current:1}) const { data:responseData, error } = await fetchGetChangeLedgerList({ size: checkedRowKeys.value.length, current: 1, ids: checkedRowKeys.value, }); if (error) { console.error("获取数据时出错:", error); alert("获取数据时发生错误,请稍后再试。"); return; } // 关键修改:将部门ID转换为部门名称 const processedRecords = responseData.records.map(record => { // 查找匹配的部门选项 const deptOption = fullDeptOptions.value.find( option => option.value === record.dept ); // 转换canUpgrade数值为文本标签 const upgradeLabel = canUpgradeRecord[record.canUpgrade as keyof typeof canUpgradeRecord] ? $t(canUpgradeRecord[record.canUpgrade as keyof typeof canUpgradeRecord]) : record.canUpgrade; // 未匹配时保留原值 // 返回新对象(保留原数据,替换dept和canUpgrade字段) return { ...record, dept: deptOption ? deptOption.label : record.dept, canUpgrade: upgradeLabel // 替换为转换后的文本 }; }); // 翻译表头 const titleMap = { hwswcoId: $t("page.change.ledger.hwswcoId"), source: $t("page.change.ledger.source"), pecoName: $t("page.change.ledger.pecoName"), peco: $t("page.change.ledger.peco"), softwareChange:$t("page.change.ledger.softwareChange"), projectno: $t("page.change.ledger.projectno"), dept: $t("page.change.ledger.dept"), softResponsiblePersonName: $t("page.change.ledger.softResponsiblePersonName"), elecResponsiblePersonName: $t("page.change.ledger.elecResponsiblePersonName"), canUpgrade: $t("page.change.ledger.canUpgrade"), // customerDemandTime: $t("page.change.ledger.customerDemandTime"), // softCompletionTime: $t("page.change.ledger.softCompletionTime"), // hardCompletionTime: $t("page.change.ledger.hardCompletionTime"), fmtCustomerDemandTime: $t("page.change.ledger.fmtCustomerDemandTime"), fmtSoftCompletionTime: $t("page.change.ledger.fmtSoftCompletionTime"), fmtHardCompletionTime: $t("page.change.ledger.fmtHardCompletionTime"), }; const headers = Object.keys(titleMap).map((key) => titleMap[key]); const sheetData = [headers]; processedRecords.forEach(record => { const row = Object.keys(titleMap).map(key => record[key]); sheetData.push(row); }); const sheetName = $t("page.change.ledger.title"); const sheets: SheetData[] = [ { sheetName: sheetName, data: sheetData, }, ]; exportXlsx(sheets, ${sheetName}); } // 在页面加载时获取最新数据 getData(); </script> <template> <LedgerSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getData" /> <NCard :title="$t('page.change.ledger.title')" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper" > <template #header-extra> <template #default> <NButton size="small" @click="handleDownload" type="primary" ghost> <template #icon> <icon-mdi-tray-download class="text-icon" :class="{ 'animate-spin': loading }" /> </template> {{ $t("common.download") }} </NButton> </template> </template> <NDataTable v-model:checked-row-keys="checkedRowKeys" :columns="columns" :data="data" size="small" :flex-height="!appStore.isMobile" :scroll-x="962" :loading="loading" remote :row-key="(row) => row.id" :pagination="mobilePagination" class="sm:h-full" /> </NCard> </template> <style scoped></style> 在page.change.ledger.title旁边显示itemCount





