@zhouhaiyang0326/invoicetemplateform
| Install | |
|---|---|
npm install @zhouhaiyang0326/invoicetemplateform |
|
| Latest Version: | 0.1.28 |
| Vue: | 2 |
| License: | MIT |
| Last Updated: | Oct 24, 2026 |
| Links: | npm |
invoicetemplateform
基于 Vue 2.7、JavaScript 和 Vite 构建的发票模板表单组件。
功能特性
- 发票类型下拉选择
- 左上角信息通过
top-info-fields的field、label、value配置展示,提交时合并进表单 - 开票明细操作按钮上方提供独占整行的“开票要求”多行文本框,内容保存在
form.invoiceRequirement - “选择订单”“选择转账单”按钮,分别触发
select-order、select-transfer-order事件 - 顶部按钮支持通过
actions配置名称、父组件方法和样式类型 - 购方名称按钮通过
buyer-actions配置;销方名称按钮通过seller-actions配置 - 购销互换会同步交换购方和销方的名称、纳税人识别号、地址、电话、开户银行和银行账号
- 每个字段的权限通过
field-permissions配置,支持edit、readonly、required - 默认必填:购方名称、购方纳税人识别号、销方名称、销方纳税人识别号,以及明细项目类型、项目名称、单价、金额、税率、税额;其余字段默认可修改
invoiceType使用两位字符串编码:'01'表示增值税专用发票,'02'表示普通发票- 税率仅提供
13%和1%:专票默认13%,普票默认1%,切换类型和新增明细时自动选择 - 买方、卖方信息展示与统一展开/收起;收起时保留名称、纳税人识别号两行
- 明细行新增、删除、全选与清空确认
- 所有明细列表统一提供新增、删除事件,并暴露对应新增、删除和清空方法
- 数量、单价、金额三者联动,任意修改一个会自动推算另一个关联值
- 单价和金额至少显示两位小数
- 含税/不含税切换,标题和值同步转换
- 税额、不含税合计、价税合计自动汇总
- 价税合计自动生成人民币大写
- 订单信息和收款信息表格通过
detail-tables配置列、表头按钮、行内按钮和字段权限 - “添加到备注”实时同步到备注信息区
- 备注 textarea 手动输入与字数统计
- 图标字体本地化,不依赖外部 CDN
环境要求
- Node.js >= 14.18.0
- Vue ^2.7.0
- npm
Vue 2 已停止维护,安装时可能出现 EOL 提示,不影响当前项目运行。
安装
npm install @zhouhaiyang0326/invoicetemplateform
如果宿主项目还没有 Vue 2.7:
npm install vue@^2.7.16
Vue CLI 4 / Webpack 4 不支持 npm
exports子路径解析。此类项目请使用:import '@zhouhaiyang0326/invoicetemplateform/dist/style.css'Webpack 5、Vite 等项目可继续使用
@zhouhaiyang0326/invoicetemplateform/style.css。
快速开始
全局注册
import Vue from 'vue'
import InvoiceTemplateForm from '@zhouhaiyang0326/invoicetemplateform'
import '@zhouhaiyang0326/invoicetemplateform/style.css'
Vue.use(InvoiceTemplateForm)
new Vue({
render: (h) => h(App),
}).$mount('#app')
<template>
<InvoiceTemplateForm />
</template>
按需引入
<script>
import { InvoiceTemplateForm } from '@zhouhaiyang0326/invoicetemplateform'
import '@zhouhaiyang0326/invoicetemplateform/style.css'
export default {
components: {
InvoiceTemplateForm,
},
}
</script>
<template>
<InvoiceTemplateForm />
</template>
组件没有必填参数,挂载后即可使用完整表单界面。
表单数据与顶部按钮配置
通过 v-model 传入表单数据,通过 actions 配置顶部按钮:
<template>
<InvoiceTemplateForm
ref="invoiceForm"
v-model="invoiceForm"
:actions="invoiceActions"
:detail-tables="detailTables"
:buyer-actions="buyerActions"
:seller-actions="sellerActions"
:top-info-fields="topInfoFields"
:field-permissions="fieldPermissions"
@button-click="handleButtonClick"
/>
</template>
<script>
import { InvoiceTemplateForm } from '@zhouhaiyang0326/invoicetemplateform'
export default {
components: { InvoiceTemplateForm },
data() {
return {
fieldPermissions: { // 覆盖默认字段权限,未配置字段沿用默认权限
gmfMc: 'required', // 购方名称:可修改且必填
gmfNsrsbh: 'readonly', // 购方纳税人识别号:只读
xsfMc: 'required', // 销方名称:可修改且必填
details: { // 开票明细字段权限
name: 'required', // 项目名称:可修改且必填
amount: 'readonly', // 金额:只读
taxRate: 'required', // 税率:可修改且必填
},
bz: 'required', // 备注:可修改且必填
},
invoiceForm: {
invoiceType: '01', // 发票类型:01 增值税专用发票,02 普通发票
spfEmail: 'invoice@example.com', // 收票方邮箱
spfPhone: '13800138000', // 收票方手机号
gmfMc: '杭州测试科技有限公司', // 购方名称
gmfNsrsbh: '91330106MA2XXXXXXX', // 购方纳税人识别号
gmfDz: '浙江省杭州市西湖区文三路 100 号', // 购方地址
gmfLxdh: '0571-88886666', // 购方电话
gmfKhh: '', // 购方开户银行
gmfYhzh: '', // 购方银行账号
xsfMc: '温州测试销方有限公司', // 销方名称
xsfNsrsbh: '91330302MA2853J12E', // 销方纳税人识别号
xsfDz: '浙江省温州市鹿城区测试地址', // 销方地址
xsfLxdh: '0577-88886666', // 销方电话
xsfKhh: '中国农业银行股份有限公司温州滨江支行', // 销方开户银行
xsfYhzh: '19211501040001739', // 销方银行账号
details: [ // 开票明细列表
{
projectType: '服务类', // 项目类型
name: '技术服务费', // 项目名称
spec: '标准版', // 规格型号
unit: '项', // 单位
quantity: '1', // 数量
unitPrice: '100', // 单价
amount: '100', // 金额
taxRate: 0.13, // 税率,显示为 13%
},
],
orderDetails: [ // 订单信息列表
{
orderCode: 'DD001', // 订单编码
productCode: 'CP001', // 产品编码
productName: '技术服务费', // 产品名称
spec: '标准版', // 规格型号
quantity: '2', // 数量
unitPrice: '500.00', // 单价
amount: '1000.00', // 金额
},
],
receipts: [ // 收款信息列表
{
receiptCode: 'SK001', // 收款单编码
orderCode: 'DD001', // 订单编码
receiptUnit: '测试收款单位', // 收款单位
receiptAccount: '62220001', // 收款账户
receiptAmount: '1234.50', // 收款金额
receiptShop: '测试店铺', // 收款店铺
},
],
invoiceRequirement: '请按订单内容开具电子发票', // 开票要求
bz: '测试备注', // 手动输入的备注文本
},
}
},
computed: {
invoiceActions() {
return [
{
name: '选择订单', // 按钮名称
type: 'primary', // 按钮样式类型
code: 'select-order', // 按钮业务编码
},
{
name: '选择转账单', // 按钮名称
type: 'primary-bordered', // 按钮样式类型
code: 'select-transfer-order', // 按钮业务编码
},
]
},
detailTables() {
return {
invoice: {
buttons: {
header: [
{ code: 'add' },
{ code: 'batch-edit' },
{ code: 'import' },
{ code: 'export' },
{ code: 'clear' },
],
body: [
{ code: 'delete' },
{
name: '复制行',
type: 'default',
code: 'copy-row',
},
],
},
},
order: {
field: 'orderDetails',
title: '订单信息',
buttons: {
header: [
{ code: 'add' },
{
name: '关联订单',
type: 'default',
code: 'relate-order',
},
{ code: 'clear' },
],
body: [
{ code: 'delete' },
{
name: '复制行',
type: 'default',
code: 'copy-order-row',
},
],
},
columns: [
{
field: 'orderCode',
label: '订单编码',
type: 'text',
permissions: 'edit',
required: true,
},
{
field: 'productName',
label: '产品名称',
type: 'text',
permissions: 'edit',
},
{
field: 'amount',
label: '金额',
type: 'num',
permissions: 'edit',
required: true,
summary: true,
},
],
},
receipt: {
field: 'receipts',
title: '收款信息',
buttons: {
header: [
{ code: 'add' },
{ code: 'clear' },
],
body: [{ code: 'delete' }],
},
columns: [
{
field: 'receiptCode',
label: '收款单编码',
type: 'text',
permissions: 'edit',
required: true,
},
{
field: 'receiptAccount',
label: '收款账户',
type: 'text',
permissions: 'readonly',
},
{
field: 'receiptAmount',
label: '收款金额',
type: 'num',
permissions: 'edit',
required: true,
summary: true,
},
],
},
}
},
topInfoFields() {
return [
{
field: 'shopName',
label: '店铺名称',
value: '温州测试店铺',
},
{
field: 'orderTime',
label: '下单时间',
value: '2026-10-20 10:30:00',
},
{
field: 'paymentTime',
label: '付款时间',
value: '2026-10-20 10:35:00',
},
{
field: 'preInvoiceAmount',
label: '预开票金额(元)',
value: '1000.00',
},
{
field: 'receivedAmount',
label: '收款金额(元)',
value: '1234.50',
},
]
},
buyerActions() {
return [
{ code: 'transfer' }, // 使用组件内置购销互换方法
{
name: '选择购方', // 自定义按钮名称
type: 'primary-bordered', // 按钮颜色类型
code: 'select-buyer', // 按钮业务编码
},
]
},
sellerActions() {
return [
{
name: '选择销方', // 按钮名称
type: 'primary', // 按钮颜色类型
code: 'select-seller', // 按钮业务编码
},
]
},
},
methods: {
handleSelectOrder(form, code) {
console.log('选择订单', code, form)
},
handleSelectTransferOrder(form, code) {
console.log('选择转账单', code, form)
},
handleSellerAction(form, code) {
console.log('销方名称按钮', code, form)
},
handleBuyerAction(form, code) {
console.log('购方名称按钮', code, form)
},
handleDetailAction(form, type, code) {
console.log('明细列表按钮', type, code, form)
},
handleDetailRowAction(form, type, code, item, index) {
console.log('明细行按钮', type, code, item, index, form)
},
handleSubmit() {
const submitData = this.$refs.invoiceForm.getSubmitData()
console.log('合并左上角信息后的表单', submitData)
},
},
}
</script>
Vue 2 的 v-model 对应组件的 value prop 和 input 事件。组件内部修改会同步
回 invoiceForm,父组件替换 invoiceForm 后组件也会重新同步。
左上角信息通过 top-info-fields 配置:
topInfoFields: [
{
field: 'shopName',
label: '店铺名称',
type: 'input',
permissions: 'required',
value: '温州测试店铺',
},
{
field: 'orderTime',
label: '下单时间',
type: 'text',
permissions: 'readonly',
value: '2026-10-20 10:30:00',
},
{
field: 'paymentTime',
label: '付款时间',
type: 'text',
permissions: 'readonly',
value: '2026-10-20 10:35:00',
},
{
field: 'preInvoiceAmount',
label: '预开票金额(元)',
type: 'text',
permissions: 'readonly',
value: '1000.00',
},
{
field: 'receivedAmount',
label: '收款金额(元)',
type: 'text',
permissions: 'readonly',
value: '1234.50',
},
]
这些值默认只用于展示,不会立即写入 form。左上角字段不会自动添加千分位、
补齐小数或使用其他字段替代空值,直接按配置原值展示。提交时使用:
const submitData = this.$refs.invoiceForm.getSubmitData()
submitData 会按每项的 field 把 value 合并到表单副本。调用组件的
submit() 会合并到当前表单,并触发 submit 事件。
topInfoFields 同样支持 type 和 permissions:
text、input、num、number、date、datetime-localselect,通过options传入{ value, label }edit、readonly、required、hidden
date、datetime-local 的 value 支持 10 位秒级或 13 位毫秒级时间戳。
select 默认支持按 label 或 value 搜索;传入 searchable: false 可关闭搜索。
input、数字、日期和 select 类型会直接编辑当前表单数据,并在
getFormData()/提交时合并;required 会参与必填校验,hidden 不渲染,
readonly 只展示不可修改。未传 type 时按 text 展示,未传 permissions
时默认为 edit。
不传 top-info-fields 或传入空数组时,左上角信息区域不展示。
备注信息下方自定义字段
通过 invoice-info-fields 在“备注信息”下方渲染四列表格。配置格式与
top-info-fields 相同,并增加 type 和 permissions:
<InvoiceTemplateForm
v-model="invoiceForm"
:invoice-info-fields="invoiceInfoFields"
/>
invoiceInfoFields: [
{
field: 'contractNo',
label: '合同编号',
type: 'input',
permissions: 'required',
},
{
field: 'settlementType',
label: '结算方式',
type: 'select',
permissions: 'edit',
value: 'MONTHLY',
options: [
{ value: 'MONTHLY', label: '月结' },
{ value: 'CASH', label: '现结' },
],
},
{
field: 'orderSource',
label: '订单来源',
type: 'text',
permissions: 'readonly',
value: '线上订单',
},
]
支持的 type:
| 类型 | 展示方式 |
|---|---|
text |
文本 |
input |
文本输入框 |
num / number |
数字输入框 |
date |
日期输入框 |
datetime-local |
日期时间输入框 |
select |
下拉框,选项格式为 { value, label } |
支持的 permissions:
| 权限 | 效果 |
|---|---|
edit |
可修改 |
readonly |
只读 |
required |
可修改、显示必填标记并参与校验 |
hidden |
隐藏 |
date、datetime-local 支持传入 10 位秒级或 13 位毫秒级时间戳,组件会自动转换为
日期输入框所需格式。
select 默认启用搜索,并会根据视口底部空间自动向上或向下展开。
自定义字段值会合并到 getFormData() 和提交数据中,也会触发表单字段变更事件。
字段权限统一通过 field-permissions 对象传入。配置会与默认权限合并:
fieldPermissions: {
gmfMc: 'required', // 可修改,显示必填标记并参与校验
gmfNsrsbh: 'readonly', // 只读,不可修改
gmfDz: 'edit', // 可修改,非必填
bz: 'hidden', // 隐藏备注字段
details: {
name: 'required', // 开票明细项目名称必填
amount: 'readonly', // 开票明细金额只读
},
'details.projectType': 'required', // 也支持使用完整字段路径
}
权限值说明:
| 值 | 含义 |
|---|---|
edit |
可修改,非必填;除默认必填字段外使用此值 |
readonly |
只读,页面上不能修改 |
required |
可修改,显示必填标记并参与 validateRequiredFields() 校验 |
hidden |
不渲染字段,同时跳过该字段的必填校验 |
默认必填字段:
{
gmfMc: 'required', // 购方名称
gmfNsrsbh: 'required', // 购方纳税人识别号
xsfMc: 'required', // 销方名称
xsfNsrsbh: 'required', // 销方纳税人识别号
details: {
projectType: 'required', // 开票明细项目类型
name: 'required', // 开票明细项目名称
unitPrice: 'required', // 开票明细单价
amount: 'required', // 开票明细金额
taxRate: 'required', // 开票明细税率
tax: 'required', // 开票明细税额
},
}
如需取消某个默认必填项,可显式传 edit:
fieldPermissions: {
gmfMc: 'edit', // 购方名称改为非必填
details: {
amount: 'edit', // 明细金额改为非必填
},
}
支持的字段:
- 收票信息:
spfEmail、spfPhone - 发票类型:
invoiceType - 购方:
gmfMc、gmfNsrsbh、gmfDz、gmfLxdh、gmfKhh、gmfYhzh - 销方:
xsfMc、xsfNsrsbh、xsfDz、xsfLxdh、xsfKhh、xsfYhzh - 开票明细:
details.projectType、details.name、details.spec、details.unit、details.quantity、details.unitPrice、details.amount、details.taxRate、details.tax - 开票要求:
invoiceRequirement - 备注:
bz
details.tax 为自动计算字段,配置为 required 时会显示必填标记并参与校验。
字段只读只影响页面输入;父组件仍可通过 v-model 或公开方法更新数据。
字段隐藏只影响页面展示,表单中的原值仍会保留并参与提交。top-info-fields
中配置的字段同样可以使用 fieldPermissions[field] = 'hidden' 隐藏。
权限只作用于具体字段,不会控制按钮、勾选列、行内增删或列表级操作。列表级按钮
是否显示完全由 detail-tables.*.buttons 配置决定。
示例只列出了部分字段,未传字段会使用组件默认值;details 数组会
覆盖默认数组,行 id 可以省略,组件会自动生成并保证唯一。
| 字段 | 说明 |
|---|---|
name |
按钮显示文字 |
method |
可选的旧版回调;新代码通过 button-click 处理,不需要传入 |
type |
按钮样式:primary、primary-bordered(或 bordered)、default |
code |
按钮业务编码,通过 button-click 的 payload.code 获取 |
不传 actions 时,默认显示“选择订单”和“选择转账单”,并分别触发
select-order、select-transfer-order 事件。
发票明细列表按钮配置
发票明细表头按钮通过 detail-tables.invoice.buttons.header 配置。未传
header 时默认显示 add、import、batch-edit 和 clear;传入数组后会完全
覆盖默认按钮:
<InvoiceTemplateForm
v-model="invoiceForm"
:detail-tables="{
invoice: {
field: 'details',
title: '发票明细',
buttons: {
header: [
{ code: 'add' },
{ code: 'batch-edit' },
{ code: 'import' },
{ code: 'export' },
{ code: 'clear' },
],
},
},
}"
/>
配置字段:
| 字段 | 说明 |
|---|---|
name |
按钮显示文字 |
method |
可选的旧版回调;新代码通过 button-click 处理,不需要传入 |
type |
primary、primary-bordered、default 等按钮颜色类型 |
code |
按钮业务编码;add、import、export、batch-edit、clear 是内置功能 |
未配置时的默认值:
detailTables.invoice.buttons.header: [
{ code: 'add' },
{ code: 'batch-edit' },
{ code: 'import' },
{ code: 'export' },
{ code: 'clear' },
]
通过传入空数组可以完全隐藏某个列表的默认按钮:
detailTables: {
invoice: {
buttons: {
header: [],
},
},
}
code: 'add' 不需要传 name、method、type:
detailTables.invoice.buttons.header: [{ code: 'add' }]
组件会使用对应列表的内置新增方法,并显示“新增行”或“添加行”。传 name 或
type 可以覆盖新增按钮的名称和颜色,但 method 始终使用组件内置的新增方法。
code: 'clear' 同样不需要传其他字段:
detailTables.invoice.buttons.header: [{ code: 'clear' }]
配置 { code: 'clear' } 时会调用 clearInvoiceDetails()。
code: 'import' 打开内置导入窗口。支持 .xlsx、.xls、JSON、CSV、TSV 文件,
也可以直接粘贴 Excel 数据。带匹配明细 ID 的行会更新原明细,ID 为空或未匹配的
行会新增,原有其他明细保持不变。点击“下载导入模板”会生成带表头和示例行的
Excel 文件,可直接填写后再导入。
code: 'batch-edit' 打开批量修改窗口,仅修改当前已勾选的明细。可修改项目类型、
项目名称、规格型号和单位;每个字段需要单独勾选后才会应用,未勾选字段不变。
其他非内置按钮会触发 button-click,通过 payload.code 区分业务。
样式规则:
- 开票明细按钮使用按钮样式,
type控制按钮颜色
methods: {
handleDetailAction(form, type, code) {
// form:当前完整表单
// type:invoice
// code:按钮配置中的业务编码
},
}
发票明细行操作按钮配置
发票明细行内操作通过 detail-tables.invoice.buttons.body 配置。未传时默认显示内置删除:
detailTables: {
invoice: {
buttons: {
body: [{ code: 'delete' }],
},
},
}
传入数组后会完全覆盖该列表的默认行操作;传入空数组可以隐藏行操作:
detailTables: {
invoice: {
buttons: {
body: [
{ code: 'delete' },
{
name: '复制行',
type: 'default',
code: 'copy-row',
},
],
},
},
}
code: 'delete' 不需要传 name、method、type,组件自动调用当前行对应的:
invoice→removeDetail(index)
自定义行操作方法接收:
handleDetailRowAction(form, type, code, item, index) {
// form:完整表单
// type:invoice
// code:按钮业务编码
// item:当前行对象
// index:当前行索引
}
行操作统一使用文本链接样式;删除默认显示为橙色,其他操作默认蓝色。type 传
primary、primary-bordered 时也显示为橙色。
自定义明细表配置
除固定发票明细外,其他表格全部通过 detail-tables 自定义。order、receipt
只是示例 key,没有内置数据字段、标题或列配置。未配置的表格不会渲染。
detailTables: {
order: {
field: 'orderDetails',
title: '订单信息',
buttons: {
header: [
{ code: 'add' },
{
name: '关联订单',
type: 'default',
code: 'relate-order',
},
{ code: 'clear' },
],
body: [
{ code: 'delete' },
{
name: '复制行',
type: 'default',
code: 'copy-order-row',
},
],
},
columns: [
{
field: 'orderCode',
label: '订单编码',
type: 'text',
permissions: 'edit',
required: true,
},
{
field: 'productName',
label: '产品名称',
type: 'text',
permissions: 'edit',
},
{
field: 'amount',
label: '金额',
type: 'num',
permissions: 'edit',
required: true,
summary: true,
},
],
},
receipt: {
field: 'receipts',
title: '收款信息',
buttons: {
header: [{ code: 'add' }, { code: 'clear' }],
body: [{ code: 'delete' }],
},
columns: [
{
field: 'receiptCode',
label: '收款单编码',
type: 'text',
permissions: 'edit',
required: true,
},
{
field: 'receiptAccount',
label: '收款账户',
type: 'text',
permissions: 'readonly',
},
{
field: 'receiptAmount',
label: '收款金额',
type: 'num',
permissions: 'edit',
required: true,
summary: true,
},
],
},
}
表格字段:
| 字段 | 说明 |
|---|---|
field |
指定表格数据在 form 中的数组字段,例如 order |
title |
表格标题 |
buttons |
表头按钮 header 和行内按钮 body |
columns |
列配置数组 |
例如:
detailTables: {
order: {
field: 'order',
columns: [
{
field: 'orderCode',
label: '订单编码',
type: 'text',
permissions: 'edit',
required: true,
},
],
},
}
对应读取:
form.order[0].orderCode
表格 key 控制事件类型,field 控制数据来源,columns[].field 控制每一列读取
哪个行属性。任何表格未设置 field 时,默认读取 form[表格key]。
也可以使用任意配置 key,例如物流信息:
detailTables: {
logistics: {
field: 'logistics',
title: '物流信息',
buttons: {
header: [{ code: 'add' }, { code: 'clear' }],
body: [{ code: 'delete' }],
},
columns: [
{
field: 'trackingNo',
label: '物流单号',
type: 'text',
permissions: 'edit',
required: true,
},
{
field: 'company',
label: '物流公司',
type: 'select',
permissions: 'edit',
options: [
{ value: 'SF', label: '顺丰' },
{ value: 'YTO', label: '圆通' },
{ value: 'ZTO', label: '中通' },
],
},
{
field: 'freight',
label: '运费',
type: 'num',
permissions: 'edit',
summary: true,
},
],
},
}
对应数据为 form.logistics。如果省略 field,默认读取同名的 form.logistics。
自定义列表同样支持 add、clear、delete 以及 logistics-detail-added、
logistics-detail-removed 等事件。
add 和 delete 直接使用组件内置方法,不需要父级传 method。
form.logistics[0].company = 'SF' // 对应 { value: 'SF', label: '顺丰' }
列字段:
| 字段 | 说明 |
|---|---|
field |
对应明细行对象中的字段名 |
label |
表头显示名称 |
type |
text、select、num |
permissions |
edit、readonly、required、hidden |
required |
是否必填并参与 validateRequiredFields() |
options |
select 类型选项,格式为 { value, label } 数组 |
searchable |
select 是否支持搜索,默认 true;传 false 使用原生下拉框 |
summary |
数字列是否显示合计 |
permissions: 'hidden' 的列不会渲染,也不会参与必填校验。
select 列默认启用搜索,可按 label 或 value 过滤选项:
下拉框会根据视口底部剩余空间自动选择向下或向上展开。
{
field: 'company',
label: '物流公司',
type: 'select',
permissions: 'edit',
options: [
{ value: 'SF', label: '顺丰' },
{ value: 'YTO', label: '圆通' },
{ value: 'ZTO', label: '中通' },
],
}
关闭搜索:
{
field: 'company',
label: '物流公司',
type: 'select',
searchable: false,
options: [],
}
columns: [
{
field: 'internalCode',
label: '内部编码',
permissions: 'hidden',
},
]
按钮字段:
buttons.header:表头新增、清空及自定义按钮buttons.body:行内删除及自定义按钮code: 'add'、code: 'clear'、code: 'delete'使用组件内置方法
销方名称按钮配置
seller-actions 默认为空数组,不传时销方名称右侧不显示按钮:
sellerActions: [
{
name: '选择销方',
type: 'primary',
code: 'select-seller',
},
]
自定义销方按钮通过 button-click 交给父级处理:
handleButtonClick(payload) {
if (payload.code === 'select-seller') {
payload.preventDefault()
this.selectSeller()
}
}
购方名称按钮配置
buyer-actions 未传时默认显示 { code: 'transfer' } 购销互换按钮;传入数组后
完全覆盖默认配置,传入空数组可以隐藏所有购方名称按钮:
buyerActions: [
{ code: 'transfer' },
{
name: '选择购方',
type: 'primary-bordered',
code: 'select-buyer',
},
]
code: 'transfer' 使用组件内置互换方法。其他操作通过 button-click 由父级
执行。购销互换会交换名称、纳税人识别号、地址、电话、开户银行和银行账号。
当前未提供发票提交接口,提交逻辑需要按实际业务接入。
组件方法
Vue 2 中可以通过 ref 获取组件实例后调用公开方法:
<template>
<InvoiceTemplateForm ref="invoiceForm" />
</template>
<script>
import { InvoiceTemplateForm } from '@zhouhaiyang0326/invoicetemplateform'
export default {
components: { InvoiceTemplateForm },
methods: {
addLine() {
this.$refs.invoiceForm.addInvoiceDetail()
},
},
}
</script>
可用方法:
| 方法 | 说明 | 返回值 |
|---|---|---|
addInvoiceDetail(data?) |
新增开票明细,可选传入初始字段;若当前只有一条未录入业务数据的初始空行,会复用该位置而不是额外保留空行 | 新增的明细对象 |
importInvoiceDetails(data) |
增量导入明细;匹配现有明细 ID 时更新原行,否则新增。可传数组、JSON、CSV 或 TSV 文本 | 新增或更新的明细数组 |
importInvoiceDetailsByJson(json) |
接收 { details: [...] } 对象或对应 JSON 字符串进行增量导入,内部调用 importInvoiceDetails() |
新增或更新的明细数组 |
downloadInvoiceImportTemplate() |
下载带表头和示例行的 Excel 导入模板 | 无 |
getInvoiceImportTemplateCsv() |
获取导入模板 CSV 文本 | CSV 字符串 |
exportInvoiceDetails() |
导出当前全部开票明细为 Excel | 导出的明细数据数组 |
getInvoiceExportData() |
获取明细 ID、项目类型、项目名称、规格型号、单位、数量、单价、金额、税率和税额 | 数据数组 |
getInvoiceExportRows() |
获取包含表头的 Excel 二维数组 | 二维数组 |
batchUpdateInvoiceDetails(data, targets?) |
批量修改项目类型、项目名称、规格型号、单位;未传 targets 时修改全部已勾选明细 |
被修改的明细数组 |
removeInvoiceDetail(indexOrDetail) |
删除指定索引或明细对象 | 成功返回 true |
addDetailTableRow(type, data?) |
向指定明细表新增一行 | 新增的明细对象 |
removeDetailTableRow(type, indexOrRow) |
删除指定明细表的行 | 成功返回 true |
getDetailTableRows(type) |
获取指定明细表的全部行 | 当前行数组 |
getSelectedDetailTableRows(type) |
获取指定明细表中勾选的行 | 勾选行数组 |
getSelectedInvoiceDetails() |
获取勾选的开票明细 | 勾选行数组 |
swapBuyerSeller() |
互换购方和销方的全部基础信息 | 无 |
validateRequiredFields() |
按 field-permissions 校验所有配置为 required 的字段 |
{ valid, errors } |
clearInvoiceDetails() |
清空所有开票明细 | 清空后的明细数组 |
clearDetailTable(type) |
清空指定自定义明细表,type 为 detailTables 的 key |
清空后的明细数组 |
clearAllDetails() |
清空开票明细、所有自定义明细表及遗留明细数组 | 按数据字段返回已清空的数组 |
getFormData(options?) |
获取完整表单数据,默认移除明细 id |
表单数据 |
getFixedFields() |
获取组件固定位置字段名称 | 字段名数组 |
getInvoiceSummary() |
获取本次开票的税额、不含税金额和价税合计 | { taxAmount, amountWithoutTax, totalAmount, taxIncluded } |
getSubmitData(options?) |
返回合并左上角配置值后的提交副本,默认移除明细 id |
表单数据 |
mergeTopInfoToForm() |
将左上角配置值合并到当前表单 | 当前表单 |
submit() |
合并左上角信息并触发 submit 事件 |
提交表单数据 |
默认情况下,getFormData()、getSubmitData() 和 submit() 返回的所有明细数组
都会移除组件内部的 id,不会提交到后端:
const data = this.$refs.invoiceForm.getFormData()
如确实需要保留明细 id:
const data = this.$refs.invoiceForm.getFormData({
includeDetailIds: true,
})
索引从 0 开始。删除方法也可以直接传入行对象,或传入行对象的 id 字符串;
传对象时会先按引用匹配,再按 id 匹配。删除最后一条开票明细后,details
会变为空数组。
清空开票明细后 details 为 [];如需清空其他明细,可单独
任意自定义明细表可调用 clearDetailTable(type);clearAllDetails() 会一次清空
开票明细和所有自定义明细表。
开票明细导入与批量修改
导入采用增量模式:
- 明细
id能匹配现有行时,覆盖该行的导入字段并保留原 ID。 id为空或未匹配时新增一行,并自动生成唯一 ID。- 未出现在导入数据中的现有明细保持不变。
- 只传数量与金额时,组件会反算单价;税额按当前税率自动计算。
const rows = this.$refs.invoiceForm.importInvoiceDetails([
{
id: 'detail-existing-id', // 可选,匹配时更新现有明细
projectType: '金属制品', // 项目类型,可传配置项的 label 或 value
name: '测试商品', // 项目名称
spec: 'A-01', // 规格型号
unit: '个', // 单位
quantity: '2', // 数量
unitPrice: '50.00', // 单价
amount: '100.00', // 金额
taxRate: 0.13, // 税率
},
])
也可以直接传入带表头的 CSV、TSV 文本或 JSON 字符串:
导入弹窗还可以直接选择 .xlsx 或 .xls 文件,组件会读取第一个工作表,并按
表头名称匹配字段。项目类型属于下拉选择字段,只有值与
projectTypeOptions 中的 label 或 value 匹配时才会填充;未匹配或没有值时,
projectType 和 sphfwssflhbbm 都保持为空。
this.$refs.invoiceForm.importInvoiceDetails(`
明细ID,项目类型,项目名称,规格型号,单位,数量,单价,金额,税率,税额
,金属制品,测试商品,A-01,个,2,50.00,100.00,0.13,11.50
`)
this.$refs.invoiceForm.importInvoiceDetails(JSON.stringify({
details: [
{ projectType: '金属制品', name: '测试商品', quantity: 2, amount: 100 },
],
}))
也可以使用专用 JSON 接口。对象和 JSON 字符串都支持:
const importJson = {
details: [
{
id: 'detail-existing-id',
projectType: '金属制品', // 项目类型
name: '测试商品', // 项目名称
spec: 'A-01', // 规格型号
unit: '个', // 单位
quantity: '2', // 数量
unitPrice: '50.00', // 单价
amount: '100.00', // 金额
taxRate: 0.13, // 税率
},
],
}
this.$refs.invoiceForm.importInvoiceDetailsByJson(importJson)
// 后端返回 JSON 字符串时也可以直接传入
this.$refs.invoiceForm.importInvoiceDetailsByJson(JSON.stringify(importJson))
用于让其他 AI 将自由文本转换成导入 JSON 的提示词:
你是一个开票明细数据转换器。请把用户提供的文本转换成下面结构的合法 JSON。
目标格式:
{
"details": [
{
"id": "原明细ID,没有则填空字符串",
"projectType": "项目类型",
"name": "项目名称",
"spec": "规格型号",
"unit": "单位",
"quantity": "数量",
"unitPrice": "单价",
"amount": "金额",
"taxRate": "税率"
}
]
}
转换规则:
1. 只输出 JSON,不要输出 Markdown 代码块、解释、标题或任何额外文字。
2. 每个项目或商品明细输出为 details 数组中的一个对象,不得遗漏或合并。
3. id 对应“明细ID”,projectType 对应“项目类型”,name 对应“项目名称”,spec 对应“规格型号”,unit 对应“单位”,quantity 对应“数量”,unitPrice 对应“单价”,amount 对应“金额”,taxRate 对应“税率”。
4. quantity 和 amount 使用不带千分位逗号、货币符号和单位的数字字符串,例如 "2"、"100.00"。
5. 不要推测文本中没有的数据。缺失字段统一使用空字符串 ""。
6. 只有文本明确提供明细ID时才填写 id,否则使用空字符串;不要输出 sphfwssflhbbm、tax 或其他未列出的字段。
7. 保持文本中金额的小数精度;如果金额明确,优先保留两位小数。
8. 文本中的项目类型可以保留原始名称;组件只保留能在 projectTypeOptions 中匹配到的值。
9. 如果无法识别出任何明细,只输出 {"details":[]}。
10. 输出必须能被 JSON.parse 直接解析,不得包含注释、尾随逗号或未转义字符。
待转换文本:
"""
{{在这里粘贴需要转换的文本}}
"""
批量修改默认只处理已勾选的明细:
const rows = this.$refs.invoiceForm.batchUpdateInvoiceDetails({
projectType: '金属制品', // 同时更新项目类型和 sphfwssflhbbm
name: '统一项目名称',
spec: '统一规格',
unit: '个',
})
也可以通过第二个参数 targets 指定要修改的行、行 ID 或索引:
this.$refs.invoiceForm.batchUpdateInvoiceDetails(
{ unit: '箱' },
['invoice-row-id-1', 2],
)
导入完成会触发 invoice-details-imported,参数中包含 addedItems、
updatedItems 和 items。新增行仍会触发 detail-field-change 的 add;
更新行会触发对应字段的 update。批量修改完成会触发
invoice-details-batch-updated。
开票明细导出
配置 { code: 'export' } 会显示“导出”按钮,将当前全部开票明细导出为 Excel,
固定导出明细 ID、项目类型、项目名称、规格型号、单位、数量、单价、金额、税率和
税额十列。没有明细时会提示“没有可导出的开票明细”。
也可以通过组件方法导出:
const exportedRows = this.$refs.invoiceForm.exportInvoiceDetails()
导出文件名格式为 开票明细-YYYYMMDD-HHmmss.xlsx,完成后触发
invoice-details-exported 事件。
按钮点击事件
所有配置按钮点击都会触发统一的 button-click 事件。父组件通过 code 判断业务
并执行自己的方法,不再需要传入 method:
<InvoiceTemplateForm
:actions="topActions"
:detail-tables="detailTables"
:buyer-actions="buyerActions"
:seller-actions="sellerActions"
@button-click="handleButtonClick"
/>
topActions: [
{
name: '选择订单',
code: 'select-order',
type: 'primary',
},
]
methods: {
handleButtonClick(payload) {
if (payload.code === 'select-order') {
payload.preventDefault()
this.selectOrder()
return
}
if (payload.code === 'import') {
payload.preventDefault()
this.importProducts(payload.form)
}
},
}
事件参数:
{
source: 'detail-header', // top、detail-header、detail-row、buyer、seller
button: {
name: '导入',
code: 'import',
type: 'primary',
},
code: 'import',
name: '导入',
form: {},
detailType: 'invoice', // 明细按钮才有
dataKey: 'details',
item: {}, // 行内按钮才有
index: 0,
list: [],
handledByComponent: false, // 组件是否会继续执行内置逻辑
defaultPrevented: false,
preventDefault() {}, // 阻止组件内置行为及旧 method
}
按钮区域通过 payload.source 区分:
source |
按钮区域 |
|---|---|
top |
顶部按钮 |
detail-header |
明细表头按钮 |
detail-row |
明细行内按钮 |
buyer |
购方名称按钮 |
seller |
销方名称按钮 |
新增、导入、批量修改、清空、删除、购销互换等内置按钮仍由组件执行。父级调用
payload.preventDefault() 后,组件跳过内置行为,父级可以改为执行自己的方法。
字段变更事件
主表单和明细表字段发生变化时会向父组件发送事件。
| 事件 | 说明 |
|---|---|
field-change |
主表单字段发生变化 |
detail-field-change |
任意明细表新增、删除或字段发生变化 |
field-change 参数:
{
field: 'gmfMc', // 字段名
value: '新值',
previousValue: '旧值',
form: {}, // 当前完整表单
}
detail-field-change 参数:
{
action: 'update', // update、add、remove、replace
type: 'invoice', // invoice,或 detailTables 中配置的任意 key
dataKey: 'details', // 对应 form 中的数组字段
field: 'name', // 字段修改时为字段名,新增和删除时为 null
value: '新值', // 新增时为新行对象,删除时为 null
previousValue: '旧值', // 删除时为被删除行对象
item: {}, // 当前明细行对象
index: 0, // 当前行索引
list: [], // 当前明细数组
form: {}, // 当前完整表单
}
action 取值:
update:明细字段修改add:新增明细行remove:删除明细行
<InvoiceTemplateForm
v-model="invoiceForm"
@field-change="handleFieldChange"
@detail-field-change="handleDetailFieldChange"
/>
methods: {
handleFieldChange({ field, value, previousValue, form }) {
console.log('表单字段变化', field, value, previousValue, form)
},
handleDetailFieldChange(payload) {
if (payload.action === 'update') {
console.log('字段修改', payload.field, payload.value)
} else if (payload.action === 'add') {
console.log('新增明细', payload.type, payload.item)
} else if (payload.action === 'remove') {
console.log('删除明细', payload.type, payload.previousValue)
}
},
}
复选框状态 selected 和内部 id 不触发字段变更事件。数量、单价、金额等
自动计算产生的字段变化也会分别触发事件。
沿用原有 detail-added、detail-removed 和
<type>-detail-added、<type>-detail-removed 事件的监听不需要修改。
明细新增与删除事件
所有明细列表都会在新增和删除行时触发事件,包括界面操作和公开的新增、删除方法。
| 事件 | 说明 |
|---|---|
detail-added |
任意明细新增,通过 payload.type 判断类型 |
detail-removed |
任意明细删除 |
invoice-detail-added / invoice-detail-removed |
开票明细新增 / 删除 |
order-detail-added / order-detail-removed |
订单信息新增 / 删除 |
receipt-detail-added / receipt-detail-removed |
收款信息新增 / 删除 |
<type>-detail-added / <type>-detail-removed |
任意 detailTables 配置 key 对应的事件 |
事件参数:
{
type: 'invoice', // invoice,或 detailTables 中配置的任意 key
item: {}, // 新增或删除的明细对象
index: 0, // 对应列表中的索引
list: [], // 事件触发后的当前列表
form: {}, // 当前完整表单数据
}
<InvoiceTemplateForm
v-model="invoiceForm"
@invoice-detail-added="handleDetailAdded"
@invoice-detail-removed="handleDetailRemoved"
@order-detail-added="handleDetailAdded"
@order-detail-removed="handleDetailRemoved"
@receipt-detail-added="handleDetailAdded"
@receipt-detail-removed="handleDetailRemoved"
/>
methods: {
handleDetailAdded({ type, item, index, list, form }) {
console.log('新增明细', type, item, index, list, form)
},
handleDetailRemoved({ type, item, index, list, form }) {
console.log('删除明细', type, item, index, list, form)
},
}
新增明细时可以同时传入业务数据:
const detail = this.$refs.invoiceForm.addInvoiceDetail({
projectType: '其他类型', // 项目类型,可传配置项的 label 或 value
name: '技术服务费', // 项目名称
spec: '标准版', // 规格型号
unit: '项', // 单位
quantity: '1', // 数量
unitPrice: '100', // 单价
taxRate: 0.13, // 税率,显示为 13%
})
// 以下三种删除方式都支持
this.$refs.invoiceForm.removeInvoiceDetail(detail)
this.$refs.invoiceForm.removeInvoiceDetail({ id: detail.id })
this.$refs.invoiceForm.removeInvoiceDetail(detail.id)
const orderRow = this.$refs.invoiceForm.addDetailTableRow('order', {
orderCode: 'DD001', // 订单编码
productCode: 'CP001', // 产品编码
productName: '技术服务费', // 产品名称
spec: '标准版', // 规格型号
quantity: '2', // 数量
unitPrice: '500.00', // 单价
amount: '1000.00', // 金额
})
const receiptRow = this.$refs.invoiceForm.addDetailTableRow('receipt', {
receiptCode: 'SK001', // 收款单编码
orderCode: 'DD001', // 订单编码
receiptUnit: '测试收款单位', // 收款单位
receiptAccount: '62220001', // 收款账户
receiptAmount: '1234.50', // 收款金额
receiptShop: '测试店铺', // 收款店铺
})
this.$refs.invoiceForm.removeDetailTableRow('order', orderRow)
this.$refs.invoiceForm.removeDetailTableRow('receipt', receiptRow.id)
this.$refs.invoiceForm.clearInvoiceDetails()
this.$refs.invoiceForm.clearDetailTable('order')
this.$refs.invoiceForm.clearAllDetails()
projectType 传入 projectTypeOptions 中的 label 或 value 时,组件会同时写入
details[].projectType(label)和 details[].sphfwssflhbbm(value)。
如果未匹配到配置项,则 projectType 和 sphfwssflhbbm 都不填充。
数量与单价同时传入时,金额会自动计算。新增明细和自定义明细行的 id 会自动生成:
优先使用 UUID,浏览器不支持时回退为时间戳、序号和随机串;新增时还会检查当前
列表,避免重复。传入的 id 会被忽略。
数据模型
组件内部主要使用以下状态:
form:发票表单数据form.details:明细行数组form.orderDetails:订单信息数组form.receipts:收款信息数组form.bz:手动备注文本taxIncluded:当前单价/金额的含税口径topInfoExpanded:买方、卖方信息是否展开
明细行字段
{
id: 'detail-1', // 明细行唯一标识,新增时自动生成
projectType: '金属制品', // 项目类型名称
sphfwssflhbbm: '1080414010000000000', // 项目类型业务编码
name: '', // 项目名称
spec: '', // 规格型号
unit: '', // 单位
quantity: '', // 数量
unitPrice: '', // 单价
amount: '', // 金额
taxRate: 0.13, // 税率,显示为 13%
selected: false, // 是否勾选
}
收款信息字段
{
id: 'receipt-1', // 收款行唯一标识,新增时自动生成
receiptCode: '', // 收款单编码
orderCode: '', // 订单编码
receiptUnit: '', // 收款单位
receiptAccount: '', // 收款账户
receiptAmount: '', // 收款金额
receiptShop: '', // 收款店铺
selected: false, // 是否勾选
}
订单信息字段
{
id: 'order-1', // 订单行唯一标识,新增时自动生成
orderCode: '', // 订单编码
productCode: '', // 产品编码
productName: '', // 产品名称
spec: '', // 规格型号
quantity: '', // 数量
unitPrice: '', // 单价
amount: '', // 金额
selected: false, // 是否勾选
}
表单主要字段
{
invoiceType: '01', // 发票类型:01 增值税专用发票,02 普通发票
shopName: '', // 店铺名称
orderTime: '', // 下单时间
paymentTime: '', // 付款时间
preInvoiceAmount: '', // 预开票金额
receivedAmount: '', // 收款金额
spfEmail: '', // 收票方邮箱
spfPhone: '', // 收票方手机号
gmfMc: '', // 购方名称
gmfNsrsbh: '', // 购方纳税人识别号
gmfDz: '', // 购方地址
gmfLxdh: '', // 购方电话
gmfKhh: '', // 购方开户银行
gmfYhzh: '', // 购方银行账号
xsfMc: '', // 销方名称
xsfNsrsbh: '', // 销方纳税人识别号
xsfDz: '', // 销方地址
xsfLxdh: '', // 销方电话
xsfKhh: '', // 销方开户银行
xsfYhzh: '', // 销方银行账号
skr: '', // 收款人
fhr: '', // 复核人
details: [], // 开票明细数组
orderDetails: [], // 订单信息数组
receipts: [], // 收款信息数组
invoiceRequirement: '', // 开票要求
bz: '', // 手动备注文本
}
交互说明
明细行
- 行内删除通过
detail-tables.invoice.buttons.body的默认{ code: 'delete' }提供 - 列表按钮配置在
detail-tables.invoice.buttons.header - 列表按钮配置
{ code: 'add' }时显示“新增行”按钮 - 列表按钮配置
{ code: 'import' }时显示“导入”按钮;ID 匹配时更新,否则新增 - 列表按钮配置
{ code: 'export' }时显示“导出”按钮并导出当前开票明细 - 列表按钮配置
{ code: 'batch-edit' }时显示“批量修改”按钮,作用于勾选明细 - “清空”按钮通过
detail-tables.invoice.buttons.header配置{ code: 'clear' }后显示 - 表头复选框控制全部明细的勾选状态
数量、单价、金额
- 修改数量:优先用单价重算金额;单价为空时用金额反算单价
- 修改单价:优先用数量重算金额;数量为空时用金额反算数量
- 修改金额:优先用数量反算单价;数量为空时用单价反算数量
- 数量或单价为空、除数为 0 时不会执行无效除法
税率自动选择
- 专票(
invoiceType: '01')默认税率taxRate: 0.13,显示为13% - 普票(
invoiceType: '02')默认税率taxRate: 0.01,显示为1% - 可通过
tax-rate-options-by-invoice-type为每种发票类型指定可选税点 - 切换发票类型时,所有明细税点自动使用当前类型税点列表的第一项
- 新增开票明细时同样默认使用第一个税点
- 切换发票类型时,所有开票明细的税率会按新配置更新
<InvoiceTemplateForm
v-model="invoiceForm"
:tax-rate-options-by-invoice-type="taxRateOptionsByInvoiceType"
/>
taxRateOptionsByInvoiceType: {
'01': [
{ value: 0.13, label: '13%' },
],
'02': [
{ value: 0.01, label: '1%' },
{ value: 0.03, label: '3%' },
],
}
未传该配置时,默认仍为专票 13%、普票 1%。
项目类型配置
发票明细的“项目类型”使用配置化下拉,默认选项为:
[
{
value: '1080414010000000000',
label: '金属制品',
},
]
父组件可以覆盖:
<InvoiceTemplateForm
v-model="invoiceForm"
:project-type-options="projectTypeOptions"
/>
projectTypeOptions: [
{ value: '1080414010000000000', label: '金属制品' },
{ value: '1080414010000000001', label: '其他类型' },
]
新增明细或项目类型配置变化时,默认使用选项列表第一项。value 按字符串保存,
对应的 label 写入 details[].projectType,value 写入
details[].sphfwssflhbbm,不会把大整数转换成不精确的 JavaScript Number。
通过 addInvoiceDetail() 传入 projectType 时,可以传 label 或 value;
手动更新明细的 projectType 后,组件也会按配置自动同步
sphfwssflhbbm。
示例明细:
{
projectType: '金属制品',
sphfwssflhbbm: '1080414010000000000',
}
含税切换
切换右上角含税开关时:
- “单价(含税)”与“单价(不含税)”同步切换
- “金额(含税)”与“金额(不含税)”同步切换
- 单价和金额会按当前税率互相换算
- 税额和价税合计按当前口径重新计算
税额和合计
- 含税金额的税额:
金额 × 税率 ÷ (100 + 税率) - 不含税金额的税额:
金额 × 税率 ÷ 100 - 合计行金额显示不含税金额
- 价税合计自动生成人民币大写
订单信息
- 订单信息表格仅在
detail-tables.order配置后显示 - 列、表头按钮和行内按钮均来自
detail-tables - 有数据时始终展示,不提供展开/收起按钮;没有数据时不展示表格内容
- 数据源由
detail-tables.order.field指定,未传时读取form.order - 列的
permissions和required控制只读与必填
收款信息
- 收款信息表格仅在
detail-tables.receipt配置后显示 - 列、表头按钮和行内按钮均来自
detail-tables - 有数据时始终展示,不提供展开/收起按钮;没有数据时不展示表格内容
- 数据源由
detail-tables.receipt.field指定,未传时读取form.receipt - 数字列配置
summary: true时显示合计
开票要求
- 位于开票明细操作按钮上方,独占整行
- 内容保存在
form.invoiceRequirement,通过v-model与父组件同步 - 可通过
field-permissions.invoiceRequirement设置为edit、readonly或required
备注信息
- 勾选买方地址、买方开户银行、卖方地址、卖方开户银行后的“添加到备注”
- 勾选内容会显示在备注框上方的分栏信息区
- 勾选状态下修改对应字段,备注内容会实时更新
- 取消勾选只移除对应信息块
- 勾选内容只在备注信息区实时展示,不会立即修改
form.bz getFormData()、getSubmitData()和submit()返回的数据会在bz末尾合并当前勾选的自动内容,并保留 textarea 中手写的备注- 取消勾选只会移除预览内容,不会修改 textarea 数据
- 备注 textarea 上限为 200 字
- 备注 textarea 会随内容自动增高,最小
92px,最大428px,超过后内部滚动
本地开发
npm install
npm run dev
开发入口为根目录的 index.html,预览页面位于 playground/。
构建
npm run build
构建产物:
dist/index.js:ES Moduledist/index.umd.cjs:UMDdist/style.css:组件样式
发布
发布前修改 package.json 中的版本号,并确认包名和许可协议:
npm publish
publishConfig 已指向 npm 官方源。
目录结构
.
├── playground/ # 本地开发预览
├── src/
│ ├── assets/
│ │ ├── fonts/ # 本地图标字体
│ │ └── images/
│ ├── components/
│ │ └── InvoiceTemplateForm.vue
│ └── index.js # 组件库入口
├── index.html # 开发服务器入口
├── vite.config.js
└── README.md
注意事项
- 图标字体已放在
src/assets/fonts,构建后随样式一起打包 - 当前版本没有实现历史发票和真实接口提交
Related Packages
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 0.1.28 | ^2.7.0 | MIT | |
| 0.1.27 | ^2.7.0 | MIT | |
| 0.1.26 | ^2.7.0 | MIT | |
| 0.1.25 | ^2.7.0 | MIT | |
| 0.1.24 | ^2.7.0 | MIT | |
| 0.1.23 | ^2.7.0 | MIT | |
| 0.1.22 | ^2.7.0 | MIT | |
| 0.1.21 | ^2.7.0 | MIT | |
| 0.1.20 | ^2.7.0 | MIT | |
| 0.1.19 | ^2.7.0 | MIT | |
| 0.1.18 | ^2.7.0 | MIT | |
| 0.1.17 | ^2.7.0 | MIT | |
| 0.1.16 | ^2.7.0 | MIT | |
| 0.1.15 | ^2.7.0 | MIT | |
| 0.1.14 | ^2.7.0 | MIT | |
| 0.1.13 | ^2.7.0 | MIT | |
| 0.1.12 | ^2.7.0 | MIT | |
| 0.1.11 | ^2.7.0 | MIT | |
| 0.1.10 | ^2.7.0 | MIT | |
| 0.1.9 | ^2.7.0 | MIT | |
| 0.1.8 | ^2.7.0 | MIT | |
| 0.1.7 | ^2.7.0 | MIT | |
| 0.1.6 | ^2.7.0 | MIT | |
| 0.1.5 | ^2.7.0 | MIT | |
| 0.1.4 | ^2.7.0 | MIT | |
| 0.1.3 | ^2.7.0 | MIT | |
| 0.1.2 | ^2.7.0 | MIT | |
| 0.1.1 | ^2.7.0 | MIT | |
| 0.1.0 | ^2.7.0 | MIT |
Pre-releases (1)
| Version | Released | License |
|---|---|---|
| 0.0.0-stage |