项目中的 <a-textarea>组件需要自动填入下方数据表的物品名称+数量+单位,效果如下:
尝试 <a-textarea>{{插值}}</a-textarea>,实现不了,问ai得知需要使用v-decorator 指令的initialValue 属性
问:
如何绑定数据到textarea内容中?
<a-textarea :rows="4" v-decorator="[ 'content', { rules: [{ required: true, message: '请输入名称!' }] } ]"/>
ai答:
对于 Ant Design Vue 中的 <a-textarea> 组件,正确的绑定数据的方式是使用 v-decorator 指令的 initialValue 属性。
<template> <a-form :form="form"> <a-form-item label="Content" :colon="false" :validate-status="getFieldError('content') ? 'error' : ''" :help="getFieldError('content') || ''"> <a-textarea :rows="4" v-decorator="['content', { initialValue: content, rules: [{ required: true, message: '请输入内容!' }] }]"></a-textarea> </a-form-item> <a-form-item> <a-button type="primary" @click="submitForm">提交</a-button> </a-form-item> </a-form> </template> <script> export default { data() { return { form: this.$form.createForm(this), content: '', // 数据属性用于绑定 <a-textarea> 的内容 }; }, methods: { getFieldError(name) { const errors = this.form.getFieldError(name); if (errors && errors.length > 0) { return errors[0]; } return ''; }, submitForm() { this.form.validateFields((errors, values) => { if (!errors) { // 表单验证通过,执行提交操作 // ... } }); }, }, }; </script>
示例中,我们使用 initialValue 属性将 content 数据属性绑定到 <a-textarea> 的初始值上。这样,当页面加载时,<a-textarea> 的内容将会显示 content 的初始值。同时,当用户输入或修改 <a-textarea> 的内容时,content 的值也会相应地更新。
注意:initialValue表示初始值,如果用户不编辑<a-textarea> 的内容,绑定内容将一直跟随改变,一旦对<a-textarea> 的内容进行了编辑,内容就不再跟随绑定变量改变。
源码:
<template>
<a-drawer
title="物品入库"
: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="32">
<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',
{ initialValue: txtcontent, 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" :precision="2" @change="handleChange(record)"/>
</template>
<template slot="consumptionShow" slot-scope="text, record">
<a-input-number v-model="record.consumption" :min="0" :max="record.amount" :step="1" :precision="2" @change="handleChange(record)"/>
</template>
<template slot="priceShow" slot-scope="text, record">
<a-input-number v-model="record.price" :min="0"/>
</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 () {
}
},
txtcontent () {
// const string = JSON.stringify(contentlist)
let string = ''
this.dataList.forEach(item => {
string += item.name + item.amount + item.unit + ' '
})
return string
},
columns () {
return [{
title: '序号',
dataIndex: 'key'
}, {
title: '物品名称',
dataIndex: 'name',
scopedSlots: {customRender: 'nameShow'}
}, {
title: '所属类型',
dataIndex: 'typeId',
width: 200,
scopedSlots: {customRender: 'typeIdShow'}
}, {
title: '型号',
dataIndex: 'type',
scopedSlots: {customRender: 'typeShow'}
}, {
title: '采购量',
dataIndex: 'amount',
scopedSlots: {customRender: 'amountShow'}
}, {
title: '消耗量',
dataIndex: 'consumption',
scopedSlots: {customRender: 'consumptionShow'}
}, {
title: '剩余量',
dataIndex: 'balance'
}, {
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: [],
keynumber: 1,
textareacontent: '备注内容'
}
},
methods: {
getConsumableType () {
this.$get('/cos/consumable-type/list').then((r) => {
this.consumableType = r.data.data
})
},
dataAdd () {
this.dataList.push({key: this.keynumber++, name: '', type: '', typeId: '', unit: '', amount: 0, consumption: 0, balance: 0, price: 0})
},
reset () {
this.loading = false
this.form.resetFields()
},
onClose () {
this.reset()
this.$emit('close')
},
handleChange (record) {
record.balance = (record.amount - record.consumption).toFixed(2)
},
handleSubmit () {
let price = 0
this.dataList.forEach(item => {
price += item.price * item.amount
})
this.form.validateFields((err, values) => {
values.price = price
values.goods = JSON.stringify(this.dataList)
if (!err) {
this.loading = true
this.$post('/cos/stock-info/put', {
...values
}).then((r) => {
this.reset()
this.$emit('success')
}).catch(() => {
this.loading = false
})
}
})
}
}
}
</script>
<style scoped>
</style>