在vue页面中添加组件到底有多方便

修改vue写的前端页面到底有多方便?如果熟练的话,出乎你想象的快。

原来的页面:/admin/stock

原来的文件地址:src\views\admin\stock\Stock.vue

另一个页面有个入库功能,需要转移到上面的页面中:

路径:/purchase/request

地址:src\views\purchase\request\Request.vue

入库功能包括一个开启按键(1)和一个弹出表单(2):

 

开启按键代码:

<a-button type="primary" ghost @click="warehouse">入库</a-button>
    warehouse () {this.stockAdd.visiable = true},

弹出表单窗口是一个独立存在的vue文件:

路径:src\views\purchase\request\RequestAdd.vue

RequestAdd.vue代码:

<template><a-drawertitle="物品入库":maskClosable="false"placement="right":closable="false":visible="show":width="1200"@close="onClose"style="height: calc(100% - 55px);overflow: auto;padding-bottom: 53px;"><a-form :form="form" layout="horizontal"><a-row :gutter="50"><a-col :span="12"><a-form-item label='保管人' v-bind="formItemLayout"><a-input v-decorator="['custodian',{ rules: [{ required: true, message: '请输入保管人!' }] }]"/></a-form-item></a-col><a-col :span="12"><a-form-item label='入库人' v-bind="formItemLayout"><a-input v-decorator="['putUser',{ rules: [{ required: true, message: '请输入入库人!' }] }]"/></a-form-item></a-col><a-col :span="24"><a-form-item label='备注消息' v-bind="formItemLayout"><a-textarea :rows="4" v-decorator="['content',{ rules: [{ required: true, message: '请输入名称!' }] }]"/></a-form-item></a-col><a-col :span="24"><a-table :columns="columns" :data-source="dataList"><template slot="nameShow" slot-scope="text, record"><a-input v-model="record.name"></a-input></template><template slot="typeShow" slot-scope="text, record"><a-input v-model="record.type"></a-input></template><template slot="typeIdShow" slot-scope="text, record"><a-select v-model="record.typeId" style="width: 100%"><a-select-option v-for="(item, index) in consumableType" :value="item.id" :key="index">{{ item.name }}</a-select-option></a-select></template><template slot="unitShow" slot-scope="text, record"><a-input v-model="record.unit"></a-input></template><template slot="amountShow" slot-scope="text, record"><a-input-number v-model="record.amount" :min="1" :step="1"/></template><template slot="priceShow" slot-scope="text, record"><a-input-number v-model="record.price" :min="1"/></template></a-table><a-button @click="dataAdd" type="primary" ghost size="large" style="margin-top: 10px;width: 100%">新增物品</a-button></a-col></a-row></a-form><div class="drawer-bootom-button"><a-popconfirm title="确定放弃编辑?" @confirm="onClose" okText="确定" cancelText="取消"><a-button style="margin-right: .8rem">取消</a-button></a-popconfirm><a-button @click="handleSubmit" type="primary" :loading="loading">提交</a-button></div></a-drawer>
</template><script>
import {mapState} from 'vuex'
const formItemLayout = {labelCol: { span: 24 },wrapperCol: { span: 24 }
}
export default {name: 'requestAdd',props: {requestAddVisiable: {default: false}},computed: {...mapState({currentUser: state => state.account.user}),show: {get: function () {return this.requestAddVisiable},set: function () {}},columns () {return [{title: '物品名称',dataIndex: 'name',scopedSlots: {customRender: 'nameShow'}}, {title: '型号',dataIndex: 'type',scopedSlots: {customRender: 'typeShow'}}, {title: '数量',dataIndex: 'amount',scopedSlots: {customRender: 'amountShow'}}, {title: '所属类型',dataIndex: 'typeId',width: 200,scopedSlots: {customRender: 'typeIdShow'}}, {title: '单位',dataIndex: 'unit',scopedSlots: {customRender: 'unitShow'}}, {title: '单价',dataIndex: 'price',scopedSlots: {customRender: 'priceShow'}}]}},mounted () {this.getConsumableType()},data () {return {dataList: [],formItemLayout,form: this.$form.createForm(this),loading: false,consumableType: []}},methods: {getConsumableType () {this.$get('/cos/consumable-type/list').then((r) => {this.consumableType = r.data.data})},dataAdd () {this.dataList.push({name: '', type: '', typeId: '', unit: '', amount: '', price: ''})},reset () {this.loading = falsethis.form.resetFields()},onClose () {this.reset()this.$emit('close')},handleSubmit () {let price = 0this.dataList.forEach(item => {price += item.price * item.amount})this.form.validateFields((err, values) => {values.price = pricevalues.goods = JSON.stringify(this.dataList)if (!err) {this.loading = truethis.$post('/cos/stock-info/put', {...values}).then((r) => {this.reset()this.$emit('success')}).catch(() => {this.loading = false})}})}}
}
</script><style scoped></style>

在Request.vue中引用RequestAdd.vue的方法:

    <request-addv-if="requestAdd.visiable"@close="handleRequestAddClose"@success="handleRequestAddSuccess":requestAddVisiable="requestAdd.visiable"></request-add>
<script>
...
import RequestAdd from './RequestAdd'
...export default {...data () {return {...requestAdd: {visiable: false},...}},...methods: {...handleRequestAddClose () {this.requestAdd.visiable = false},handleRequestAddSuccess () {this.requestAdd.visiable = falsethis.$message.success('入库成功')this.search()},...search () {let {sortedInfo, filteredInfo} = thislet sortField, sortOrder// 获取当前列的排序和列的过滤规则if (sortedInfo) {sortField = sortedInfo.fieldsortOrder = sortedInfo.order}this.fetch({sortField: sortField,sortOrder: sortOrder,...this.queryParams,...filteredInfo})},...fetch (params = {}) {// 显示loadingthis.loading = trueif (this.paginationInfo) {// 如果分页信息不为空,则设置表格当前第几页,每页条数,并设置查询分页参数this.$refs.TableInfo.pagination.current = this.paginationInfo.currentthis.$refs.TableInfo.pagination.pageSize = this.paginationInfo.pageSizeparams.size = this.paginationInfo.pageSizeparams.current = this.paginationInfo.current} else {// 如果分页信息为空,则设置为默认值params.size = this.pagination.defaultPageSizeparams.current = this.pagination.defaultCurrent}if (params.typeId === undefined) {delete params.typeId}this.$get('/cos/stock-info/page', {...params}).then((r) => {let data = r.data.dataconst pagination = {...this.pagination}pagination.total = data.totalthis.dataSource = data.recordsthis.pagination = pagination// 数据加载完毕,关闭loadingthis.loading = false})}},watch: {}
}
</script>

实际上就是在Request.vue中添加一个数据对象(requestAdd.visiable)和两个方法(handleRequestAddClose、handleRequestAddSuccess)

开始改造

将RequestAdd.vue文件加入Stock.vue所在路径,修改合适的文件名称为StockAdd.vue,同时修改StockAdd.vue对外暴露的name和props的名称。

在Stock.vue的<template>代码适当位置添加按键和表单(7行代码):

 在Stock.vue的<script>代码中添加相关的引用(2行代码)、数据(3行代码)、函数(8行代码):

 

总结

改造过程,共复制vue文件1个,修改代码23行。熟悉代码的情况下,修改用时很短。

说明vue组件化特性为代码复用带来极大便利。

源码

src\views\purchase\request\Request.vue

<template><a-card :bordered="false" class="card-area"><div :class="advanced ? 'search' : null"><!-- 搜索区域 --><a-form layout="horizontal"><a-row :gutter="15"><div :class="advanced ? null: 'fold'"><a-col :md="6" :sm="24"><a-form-itemlabel="物品名称":labelCol="{span: 4}":wrapperCol="{span: 18, offset: 2}"><a-input v-model="queryParams.name"/></a-form-item></a-col><a-col :md="6" :sm="24"><a-form-itemlabel="物品型号":labelCol="{span: 4}":wrapperCol="{span: 18, offset: 2}"><a-input v-model="queryParams.type"/></a-form-item></a-col><a-col :md="6" :sm="24"><a-form-itemlabel="物品类型":labelCol="{span: 4}":wrapperCol="{span: 18, offset: 2}"><a-select v-model="queryParams.typeId" style="width: 100%" allowClear><a-select-option v-for="(item, index) in consumableType" :value="item.id" :key="index">{{ item.name }}</a-select-option></a-select></a-form-item></a-col></div><span style="float: right; margin-top: 3px;"><a-button type="primary" @click="search">查询</a-button><a-button style="margin-left: 8px" @click="reset">重置</a-button></span></a-row></a-form></div><div><div class="operator"><a-button type="primary" ghost @click="add">入库</a-button><!-- <a-button @click="batchDelete">删除</a-button> 后台API不存在/cos/request-type/{id}删除接口 这个按键是多余的 --></div><!-- 表格区域 --><a-table ref="TableInfo":columns="columns":rowKey="record => record.id":dataSource="dataSource":pagination="pagination":loading="loading":rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}":scroll="{ x: 900 }"@change="handleTableChange"><template slot="titleShow" slot-scope="text, record"><template><a-badge status="processing"/><a-tooltip><template slot="title">{{ record.title }}</template>{{ record.title.slice(0, 8) }} ...</a-tooltip></template></template><template slot="contentShow" slot-scope="text, record"><template><a-tooltip><template slot="title">{{ record.content }}</template>{{ record.content.slice(0, 30) }} ...</a-tooltip></template></template><template slot="operation" slot-scope="text, record"><a-icon type="setting" theme="twoTone" twoToneColor="#4a9ff5" @click="edit(record)" title="修 改"></a-icon></template></a-table></div><request-addv-if="requestAdd.visiable"@close="handleRequestAddClose"@success="handleRequestAddSuccess":requestAddVisiable="requestAdd.visiable"></request-add></a-card>
</template><script>
import RangeDate from '@/components/datetime/RangeDate'
import RequestAdd from './RequestAdd'
import {mapState} from 'vuex'
import moment from 'moment'
moment.locale('zh-cn')export default {name: 'request',components: {RequestAdd, RangeDate},data () {return {advanced: false,requestAdd: {visiable: false},requestEdit: {visiable: false},queryParams: {},filteredInfo: null,sortedInfo: null,paginationInfo: null,dataSource: [],selectedRowKeys: [],loading: false,pagination: {pageSizeOptions: ['10', '20', '30', '40', '100'],defaultCurrent: 1,defaultPageSize: 10,showQuickJumper: true,showSizeChanger: true,showTotal: (total, range) => `显示 ${range[0]} ~ ${range[1]} 条记录,共 ${total} 条记录`},consumableType: []}},computed: {...mapState({currentUser: state => state.account.user}),columns () {return [{title: '物品名称',dataIndex: 'name'}, {title: '型号',dataIndex: 'type',customRender: (text, row, index) => {if (text !== null) {return text} else {return '- -'}}}, {title: '物品数量',dataIndex: 'amount',customRender: (text, row, index) => {if (text !== null) {return text} else {return '- -'}}}, {title: '单位',dataIndex: 'unit',customRender: (text, row, index) => {if (text !== null) {return text} else {return '- -'}}}, {title: '单价',dataIndex: 'price',customRender: (text, row, index) => {if (text !== null) {return '¥' + text.toFixed(2)} else {return '- -'}}}, {title: '总价',dataIndex: 'allPrice',customRender: (text, row, index) => {return '¥' + (row.price * row.amount).toFixed(2)}}, {title: '物品类型',dataIndex: 'consumableType',customRender: (text, row, index) => {if (text !== null) {return <a-tag>{text}</a-tag>} else {return '- -'}}}, {title: '备注',dataIndex: 'content',customRender: (text, row, index) => {if (text !== null) {return text} else {return '- -'}}}, {title: '入库时间',dataIndex: 'createDate',customRender: (text, row, index) => {if (text !== null) {return text} else {return '- -'}}}]}},mounted () {this.fetch()this.getConsumableType()},methods: {getConsumableType () {this.$get('/cos/consumable-type/list').then((r) => {this.consumableType = r.data.data})},onSelectChange (selectedRowKeys) {this.selectedRowKeys = selectedRowKeys},toggleAdvanced () {this.advanced = !this.advanced},add () {this.requestAdd.visiable = true},handleRequestAddClose () {this.requestAdd.visiable = false},handleRequestAddSuccess () {this.requestAdd.visiable = falsethis.$message.success('入库成功')this.search()},handleDeptChange (value) {this.queryParams.deptId = value || ''},batchDelete () {if (!this.selectedRowKeys.length) {this.$message.warning('请选择需要删除的记录')return}let that = thisthis.$confirm({title: '确定删除所选中的记录?',content: '当您点击确定按钮后,这些记录将会被彻底删除',centered: true,onOk () {let ids = that.selectedRowKeys.join(',')that.$delete('/cos/request-type/' + ids).then(() => {that.$message.success('删除成功')that.selectedRowKeys = []that.search()})},onCancel () {that.selectedRowKeys = []}})},search () {let {sortedInfo, filteredInfo} = thislet sortField, sortOrder// 获取当前列的排序和列的过滤规则if (sortedInfo) {sortField = sortedInfo.fieldsortOrder = sortedInfo.order}this.fetch({sortField: sortField,sortOrder: sortOrder,...this.queryParams,...filteredInfo})},reset () {// 取消选中this.selectedRowKeys = []// 重置分页this.$refs.TableInfo.pagination.current = this.pagination.defaultCurrentif (this.paginationInfo) {this.paginationInfo.current = this.pagination.defaultCurrentthis.paginationInfo.pageSize = this.pagination.defaultPageSize}// 重置列过滤器规则this.filteredInfo = null// 重置列排序规则this.sortedInfo = null// 重置查询参数this.queryParams = {}this.fetch()},handleTableChange (pagination, filters, sorter) {// 将这三个参数赋值给Vue data,用于后续使用this.paginationInfo = paginationthis.filteredInfo = filtersthis.sortedInfo = sorterthis.fetch({sortField: sorter.field,sortOrder: sorter.order,...this.queryParams,...filters})},fetch (params = {}) {// 显示loadingthis.loading = trueif (this.paginationInfo) {// 如果分页信息不为空,则设置表格当前第几页,每页条数,并设置查询分页参数this.$refs.TableInfo.pagination.current = this.paginationInfo.currentthis.$refs.TableInfo.pagination.pageSize = this.paginationInfo.pageSizeparams.size = this.paginationInfo.pageSizeparams.current = this.paginationInfo.current} else {// 如果分页信息为空,则设置为默认值params.size = this.pagination.defaultPageSizeparams.current = this.pagination.defaultCurrent}if (params.typeId === undefined) {delete params.typeId}this.$get('/cos/stock-info/page', {...params}).then((r) => {let data = r.data.dataconst pagination = {...this.pagination}pagination.total = data.totalthis.dataSource = data.recordsthis.pagination = pagination// 数据加载完毕,关闭loadingthis.loading = false})}},watch: {}
}
</script>
<style lang="less" scoped>
@import "../../../../static/less/Common";
</style>

src\views\purchase\request\RequestAdd.vue:

<template><a-drawertitle="物品入库":maskClosable="false"placement="right":closable="false":visible="show":width="1200"@close="onClose"style="height: calc(100% - 55px);overflow: auto;padding-bottom: 53px;"><a-form :form="form" layout="horizontal"><a-row :gutter="50"><a-col :span="12"><a-form-item label='保管人' v-bind="formItemLayout"><a-input v-decorator="['custodian',{ rules: [{ required: true, message: '请输入保管人!' }] }]"/></a-form-item></a-col><a-col :span="12"><a-form-item label='入库人' v-bind="formItemLayout"><a-input v-decorator="['putUser',{ rules: [{ required: true, message: '请输入入库人!' }] }]"/></a-form-item></a-col><a-col :span="24"><a-form-item label='备注消息' v-bind="formItemLayout"><a-textarea :rows="4" v-decorator="['content',{ rules: [{ required: true, message: '请输入名称!' }] }]"/></a-form-item></a-col><a-col :span="24"><a-table :columns="columns" :data-source="dataList"><template slot="nameShow" slot-scope="text, record"><a-input v-model="record.name"></a-input></template><template slot="typeShow" slot-scope="text, record"><a-input v-model="record.type"></a-input></template><template slot="typeIdShow" slot-scope="text, record"><a-select v-model="record.typeId" style="width: 100%"><a-select-option v-for="(item, index) in consumableType" :value="item.id" :key="index">{{ item.name }}</a-select-option></a-select></template><template slot="unitShow" slot-scope="text, record"><a-input v-model="record.unit"></a-input></template><template slot="amountShow" slot-scope="text, record"><a-input-number v-model="record.amount" :min="1" :step="1"/></template><template slot="priceShow" slot-scope="text, record"><a-input-number v-model="record.price" :min="1"/></template></a-table><a-button @click="dataAdd" type="primary" ghost size="large" style="margin-top: 10px;width: 100%">新增物品</a-button></a-col></a-row></a-form><div class="drawer-bootom-button"><a-popconfirm title="确定放弃编辑?" @confirm="onClose" okText="确定" cancelText="取消"><a-button style="margin-right: .8rem">取消</a-button></a-popconfirm><a-button @click="handleSubmit" type="primary" :loading="loading">提交</a-button></div></a-drawer>
</template><script>
import {mapState} from 'vuex'
const formItemLayout = {labelCol: { span: 24 },wrapperCol: { span: 24 }
}
export default {name: 'requestAdd',props: {requestAddVisiable: {default: false}},computed: {...mapState({currentUser: state => state.account.user}),show: {get: function () {return this.requestAddVisiable},set: function () {}},columns () {return [{title: '物品名称',dataIndex: 'name',scopedSlots: {customRender: 'nameShow'}}, {title: '型号',dataIndex: 'type',scopedSlots: {customRender: 'typeShow'}}, {title: '数量',dataIndex: 'amount',scopedSlots: {customRender: 'amountShow'}}, {title: '所属类型',dataIndex: 'typeId',width: 200,scopedSlots: {customRender: 'typeIdShow'}}, {title: '单位',dataIndex: 'unit',scopedSlots: {customRender: 'unitShow'}}, {title: '单价',dataIndex: 'price',scopedSlots: {customRender: 'priceShow'}}]}},mounted () {this.getConsumableType()},data () {return {dataList: [],formItemLayout,form: this.$form.createForm(this),loading: false,consumableType: []}},methods: {getConsumableType () {this.$get('/cos/consumable-type/list').then((r) => {this.consumableType = r.data.data})},dataAdd () {this.dataList.push({name: '', type: '', typeId: '', unit: '', amount: '', price: ''})},reset () {this.loading = falsethis.form.resetFields()},onClose () {this.reset()this.$emit('close')},handleSubmit () {let price = 0this.dataList.forEach(item => {price += item.price * item.amount})this.form.validateFields((err, values) => {values.price = pricevalues.goods = JSON.stringify(this.dataList)if (!err) {this.loading = truethis.$post('/cos/stock-info/put', {...values}).then((r) => {this.reset()this.$emit('success')}).catch(() => {this.loading = false})}})}}
}
</script><style scoped></style>

 src\views\admin\stock\Stock.vue(修改后):

<template><a-card :bordered="false" class="card-area"><div :class="advanced ? 'search' : null"><!-- 搜索区域 --><a-form layout="horizontal"><a-row :gutter="15"><div :class="advanced ? null: 'fold'"><a-col :md="6" :sm="24"><a-form-itemlabel="物品名称":labelCol="{span: 4}":wrapperCol="{span: 18, offset: 2}"><a-input v-model="queryParams.name"/></a-form-item></a-col><a-col :md="6" :sm="24"><a-form-itemlabel="物品型号":labelCol="{span: 4}":wrapperCol="{span: 18, offset: 2}"><a-input v-model="queryParams.type"/></a-form-item></a-col><a-col :md="6" :sm="24"><a-form-itemlabel="物品类型":labelCol="{span: 4}":wrapperCol="{span: 18, offset: 2}"><a-select v-model="queryParams.typeId" style="width: 100%" allowClear><a-select-option v-for="(item, index) in consumableType" :value="item.id" :key="index">{{ item.name }}</a-select-option></a-select></a-form-item></a-col></div><span style="float: right; margin-top: 3px;"><a-button type="primary" @click="search">查询</a-button><a-button style="margin-left: 8px" @click="reset">重置</a-button></span></a-row></a-form></div><div><div class="operator"><a-button type="primary" ghost @click="warehouse">入库</a-button><a-button type="primary" ghost @click="outOfWarehouse">出库</a-button><!--<a-button @click="batchDelete">删除</a-button>--></div><!-- 表格区域  --><a-table ref="TableInfo":columns="columns":rowKey="record => record.id":dataSource="dataSource":pagination="pagination":loading="loading":rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}":scroll="{ x: 900 }"@change="handleTableChange"><template slot="titleShow" slot-scope="text, record"><template><a-badge status="processing"/><a-tooltip><template slot="title">{{ record.title }}</template>{{ record.title.slice(0, 8) }} ...</a-tooltip></template></template><template slot="contentShow" slot-scope="text, record"><template><a-tooltip><template slot="title">{{ record.content }}</template>{{ record.content.slice(0, 30) }} ...</a-tooltip></template></template><template slot="operation" slot-scope="text, record"><a-icon type="setting" theme="twoTone" twoToneColor="#4a9ff5" @click="edit(record)" title="修 改"></a-icon></template></a-table></div><stock-addv-if="stockAdd.visiable"@close="handleStockAddClose"@success="handleStockAddSuccess":stockAddVisiable="stockAdd.visiable"></stock-add><stock-out@close="handleStockoutClose"@success="handleStockoutSuccess":stockoutData="stockout.data":stockoutVisiable="stockout.visiable"></stock-out></a-card>
</template><script>
import RangeDate from '@/components/datetime/RangeDate'
import {mapState} from 'vuex'
import StockOut from './StockOut'
import StockAdd from './StockAdd'
import moment from 'moment'
moment.locale('zh-cn')export default {name: 'Stock',components: {StockOut, StockAdd, RangeDate},data () {return {advanced: false,stockAdd: {visiable: false},stockout: {visiable: false,data: null},requestEdit: {visiable: false},queryParams: {},filteredInfo: null,sortedInfo: null,paginationInfo: null,dataSource: [],selectedRowKeys: [],selectedRows: [],loading: false,pagination: {pageSizeOptions: ['10', '20', '30', '40', '100'],defaultCurrent: 1,defaultPageSize: 10,showQuickJumper: true,showSizeChanger: true,showTotal: (total, range) => `显示 ${range[0]} ~ ${range[1]} 条记录,共 ${total} 条记录`},consumableType: []}},computed: {...mapState({currentUser: state => state.account.user}),columns () {return [{title: '物品名称',dataIndex: 'name'}, {title: '型号',dataIndex: 'type',customRender: (text, row, index) => {if (text !== null) {return text} else {return '- -'}}}, {title: '物品数量',dataIndex: 'amount',customRender: (text, row, index) => {if (text !== null) {return text} else {return '- -'}}}, {title: '单位',dataIndex: 'unit',customRender: (text, row, index) => {if (text !== null) {return text} else {return '- -'}}}, {title: '单价',dataIndex: 'price',customRender: (text, row, index) => {if (text !== null) {return '¥' + text.toFixed(2)} else {return '- -'}}}, {title: '总价',dataIndex: 'allPrice',customRender: (text, row, index) => {return '¥' + (row.price * row.amount).toFixed(2)}}, {title: '物品类型',dataIndex: 'consumableType',customRender: (text, row, index) => {if (text !== null) {return <a-tag>{text}</a-tag>} else {return '- -'}}}, {title: '备注',dataIndex: 'content',customRender: (text, row, index) => {if (text !== null) {return text} else {return '- -'}}}, {title: '入库时间',dataIndex: 'createDate',customRender: (text, row, index) => {if (text !== null) {return text} else {return '- -'}}}]}},mounted () {this.fetch()this.getConsumableType()},methods: {getConsumableType () {this.$get('/cos/consumable-type/list').then((r) => {this.consumableType = r.data.data})},onSelectChange (selectedRowKeys, selectedRows) {selectedRows.forEach(item => {if (item.amount === 0) {this.$message.warning(`${item.name}没有库存!`)return false}})this.selectedRowKeys = selectedRowKeysthis.selectedRows = selectedRows},toggleAdvanced () {this.advanced = !this.advanced},// “入库”按键响应warehouse () {this.stockAdd.visiable = true},// “出库”按键的响应方法outOfWarehouse () {if (!this.selectedRowKeys.length) {this.$message.warning('请选择需要出库的物品')return}let goods = this.selectedRowslet amt = falselet warningwords = '某个物品'goods.forEach(item => {item.max = item.amountif (item.amount === 0) {amt = truewarningwords = item.name}})if (amt) {this.$message.warning(`${warningwords}没有库存!`)return}this.stockout.data = JSON.parse(JSON.stringify(goods))this.stockout.visiable = true},handleStockAddClose () {this.stockAdd.visiable = false},handleStockAddSuccess () {this.stockAdd.visiable = falsethis.$message.success('入库成功')this.search()},handleStockoutClose () {this.stockout.visiable = false},handleStockoutSuccess () {this.stockout.visiable = falsethis.selectedRows = []this.selectedRowKeys = []this.$message.success('出库成功')this.search()},handleDeptChange (value) {this.queryParams.deptId = value || ''},batchDelete () {if (!this.selectedRowKeys.length) {this.$message.warning('请选择需要删除的记录')return}let that = thisthis.$confirm({title: '确定删除所选中的记录?',content: '当您点击确定按钮后,这些记录将会被彻底删除',centered: true,onOk () {let ids = that.selectedRowKeys.join(',')that.$delete('/cos/request-type/' + ids).then(() => {that.$message.success('删除成功')that.selectedRowKeys = []that.selectedRows = []that.search()})},onCancel () {that.selectedRowKeys = []that.selectedRows = []}})},search () {let {sortedInfo, filteredInfo} = thislet sortField, sortOrder// 获取当前列的排序和列的过滤规则if (sortedInfo) {sortField = sortedInfo.fieldsortOrder = sortedInfo.order}this.fetch({sortField: sortField,sortOrder: sortOrder,...this.queryParams,...filteredInfo})},reset () {// 取消选中this.selectedRowKeys = []// 重置分页this.$refs.TableInfo.pagination.current = this.pagination.defaultCurrentif (this.paginationInfo) {this.paginationInfo.current = this.pagination.defaultCurrentthis.paginationInfo.pageSize = this.pagination.defaultPageSize}// 重置列过滤器规则this.filteredInfo = null// 重置列排序规则this.sortedInfo = null// 重置查询参数this.queryParams = {}this.fetch()},handleTableChange (pagination, filters, sorter) {// 将这三个参数赋值给Vue data,用于后续使用this.paginationInfo = paginationthis.filteredInfo = filtersthis.sortedInfo = sorterthis.fetch({sortField: sorter.field,sortOrder: sorter.order,...this.queryParams,...filters})},fetch (params = {}) {// 显示loadingthis.loading = trueif (this.paginationInfo) {// 如果分页信息不为空,则设置表格当前第几页,每页条数,并设置查询分页参数this.$refs.TableInfo.pagination.current = this.paginationInfo.currentthis.$refs.TableInfo.pagination.pageSize = this.paginationInfo.pageSizeparams.size = this.paginationInfo.pageSizeparams.current = this.paginationInfo.current} else {// 如果分页信息为空,则设置为默认值params.size = this.pagination.defaultPageSizeparams.current = this.pagination.defaultCurrent}if (params.typeId === undefined) {delete params.typeId}this.$get('/cos/stock-info/page', {...params}).then((r) => {let data = r.data.dataconst pagination = {...this.pagination}pagination.total = data.totalthis.dataSource = data.recordsthis.pagination = pagination// 数据加载完毕,关闭loadingthis.loading = false})}},watch: {}
}
</script>
<style lang="less" scoped>
@import "../../../../static/less/Common";
</style>

src\views\admin\stock\StockAdd.vue(修改后):

<template><a-drawertitle="物品入库":maskClosable="false"placement="right":closable="false":visible="show":width="1200"@close="onClose"style="height: calc(100% - 55px);overflow: auto;padding-bottom: 53px;"><a-form :form="form" layout="horizontal"><a-row :gutter="50"><a-col :span="12"><a-form-item label='保管人' v-bind="formItemLayout"><a-input v-decorator="['custodian',{ rules: [{ required: true, message: '请输入保管人!' }] }]"/></a-form-item></a-col><a-col :span="12"><a-form-item label='入库人' v-bind="formItemLayout"><a-input v-decorator="['putUser',{ rules: [{ required: true, message: '请输入入库人!' }] }]"/></a-form-item></a-col><a-col :span="24"><a-form-item label='备注消息' v-bind="formItemLayout"><a-textarea :rows="4" v-decorator="['content',{ rules: [{ required: true, message: '请输入名称!' }] }]"/></a-form-item></a-col><a-col :span="24"><a-table :columns="columns" :data-source="dataList"><template slot="nameShow" slot-scope="text, record"><a-input v-model="record.name"></a-input></template><template slot="typeShow" slot-scope="text, record"><a-input v-model="record.type"></a-input></template><template slot="typeIdShow" slot-scope="text, record"><a-select v-model="record.typeId" style="width: 100%"><a-select-option v-for="(item, index) in consumableType" :value="item.id" :key="index">{{ item.name }}</a-select-option></a-select></template><template slot="unitShow" slot-scope="text, record"><a-input v-model="record.unit"></a-input></template><template slot="amountShow" slot-scope="text, record"><a-input-number v-model="record.amount" :min="1" :step="1"/></template><template slot="priceShow" slot-scope="text, record"><a-input-number v-model="record.price" :min="1"/></template></a-table><a-button @click="dataAdd" type="primary" ghost size="large" style="margin-top: 10px;width: 100%">新增物品</a-button></a-col></a-row></a-form><div class="drawer-bootom-button"><a-popconfirm title="确定放弃编辑?" @confirm="onClose" okText="确定" cancelText="取消"><a-button style="margin-right: .8rem">取消</a-button></a-popconfirm><a-button @click="handleSubmit" type="primary" :loading="loading">提交</a-button></div></a-drawer>
</template><script>
import {mapState} from 'vuex'
const formItemLayout = {labelCol: { span: 24 },wrapperCol: { span: 24 }
}
export default {name: 'stockAdd',props: {stockAddVisiable: {default: false}},computed: {...mapState({currentUser: state => state.account.user}),show: {get: function () {return this.stockAddVisiable},set: function () {}},columns () {return [{title: '物品名称',dataIndex: 'name',scopedSlots: {customRender: 'nameShow'}}, {title: '型号',dataIndex: 'type',scopedSlots: {customRender: 'typeShow'}}, {title: '数量',dataIndex: 'amount',scopedSlots: {customRender: 'amountShow'}}, {title: '所属类型',dataIndex: 'typeId',width: 200,scopedSlots: {customRender: 'typeIdShow'}}, {title: '单位',dataIndex: 'unit',scopedSlots: {customRender: 'unitShow'}}, {title: '单价',dataIndex: 'price',scopedSlots: {customRender: 'priceShow'}}]}},mounted () {this.getConsumableType()},data () {return {dataList: [],formItemLayout,form: this.$form.createForm(this),loading: false,consumableType: []}},methods: {getConsumableType () {this.$get('/cos/consumable-type/list').then((r) => {this.consumableType = r.data.data})},dataAdd () {this.dataList.push({name: '', type: '', typeId: '', unit: '', amount: '', price: ''})},reset () {this.loading = falsethis.form.resetFields()},onClose () {this.reset()this.$emit('close')},handleSubmit () {let price = 0this.dataList.forEach(item => {price += item.price * item.amount})this.form.validateFields((err, values) => {values.price = pricevalues.goods = JSON.stringify(this.dataList)if (!err) {this.loading = truethis.$post('/cos/stock-info/put', {...values}).then((r) => {this.reset()this.$emit('success')}).catch(() => {this.loading = false})}})}}
}
</script><style scoped></style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/221548.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么样的CRM系统更值得使用?

CRM系统发展到了2023年&#xff0c;经过了无数次迭代与更新&#xff0c;各种概念开始层出不穷。当您的企业准备实施一套CRM系统&#xff0c;在选型前有个问题需要思考&#xff1a;您到底需要什么样的CRM系统&#xff1f; CRM系统早已经从当初的管理客户关系变为了“十项全能”—…

最全!10款高效制作组织架构图的软件推荐

在现代企业管理中&#xff0c;组织架构图扮演着重要的角色。通过清晰地展示公司内部的层级关系和职能分工&#xff0c;组织架构图可以帮助企业高效地管理和运作。然而&#xff0c;选择一款适合自己的组织架构图软件却不容易&#xff0c;本文将为大家分享10款高效制作组织架构图…

被围绕的区域

题目链接 被围绕的区域 题目描述 注意点 board[i][j] 为 ‘X’ 或 ‘O’被围绕的区间不会存在于边界上&#xff0c;换句话说&#xff0c;任何边界上的 ‘O’ 都不会被填充为 ‘X’。 任何不在边界上&#xff0c;或不与边界上的 ‘O’ 相连的 ‘O’ 最终都会被填充为 ‘X’如…

WinEdt打开.tex文件显示error reading错误

原因&#xff1a; 是因为.tex文件中包含了utf-8字符&#xff0c;而在打开的时候并没有指明utf-8打开方式 解决方法 在WinEdt中&#xff0c;【File】-【Open】&#xff08;或使用快捷键CtrlO&#xff09;&#xff0c;在弹出的打开对话框中&#xff0c;右下角【文件名】右侧有…

快速了解软件工程学概述(5种软件过程模型)

目录 1 、什么是软件&#xff1f;特点有哪些 &#xff1f; 2 、 软件危机 定义&#xff1a; 软件危机产生的原因 消除软件危机的方法 3 、软件工程 1.软件工程的介绍 &#xff08;1&#xff09;概念 &#xff08;2&#xff09;本质特征 (3)软件工程方法学&#xff08;方…

【数据结构】二叉树oj题

在处理oj题之前我们需要先处理一下之前遗留的问题 在二叉树中寻找为x的节点 BTNode* BinaryTreeFind(BTNode* root, int x) {if (root NULL)return NULL;if (root->data x)return root;BTNode* ret1 BinaryTreeFind(root->left, x);BTNode* ret2 BinaryTreeFind(ro…

【前沿技术了解】web图形Canvas、svg、WebGL、数据可视化引擎的技术选型

目录 Canvas&#xff1a;HTML5新增 Canvas标签&#xff08;画布&#xff09; 渲染上下文canvas.getContext(contextType[, contextAttributes]) 上下文类型&#xff08;contextType&#xff09; 上下文属性 (contextAttributes) 示例 动画 setInterval(function, delay)…

组装自己的稳定扩散模型

在本文中&#xff0c;我们将利用 Hugging Face Diffusers 库的组件实现自己的稳定扩散模型&#xff0c;可以像 diffuser.diffuse() 一样简单地生成图像。 在线工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编…

Portraiture全新4.1.2版本升级更新

关于PS修图插件&#xff0c;相信大家都有安装过使用过&#xff0c;而且还不止安装了一款&#xff0c;比如最为经典的DR5.0人像精修插件&#xff0c;Retouch4me11合1插件&#xff0c;Portraiture磨皮插件&#xff0c;这些都是人像精修插件中的领跑者。其中 Portraiture 刚刚升级…

内网隧道学习

默认密码&#xff1a;hongrisec2019 一.环境搭建 网卡学习 一个网卡一个分段&#xff0c;想象成一个管道 192.168.52一段 192.168.150一段 仅主机模式保证不予外界连通&#xff0c;保证恶意操作不会跑到真实机之上 52段是内部通信&#xff0c;150段属于服务器&#xff08;…

C语言学习笔记之函数篇

与数学意义上的函数不同&#xff0c;C语言中的函数又称为过程&#xff0c;接口&#xff0c;具有极其重要的作用。教科书上将其定义为&#xff1a;程序中的子程序。 在计算机科学中&#xff0c;子程序&#xff08;英语&#xff1a;Subroutine, procedure, function, routine, me…

FFmpeg零基础学习(二)——视频文件信息获取

目录 前言正文一、获取宽高信息1、核心代码2、AVFormatContext3、avformat_alloc_context4、avformat_open_input5、avformat_find_stream_info6、av_dump_format7、av_find_best_stream End、遇到的问题1、Qt Debug模式avformat_alloc_context 无法分配对象&#xff0c;而Rele…