ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
例如有些时候需要上传多张图片,但是并不确定留下几个图片位,这是我们就想手动添加图片位,从而实现自定义数量图片的上传。我们以广告上传为例,上传多个广告。 1.仿照分类组件编写广告位模块 AdSet.vue: ``` <template> <div> <h1>{{id ? '编辑' : '创建'}}广告位</h1> <el-form label-width="100px" style="margin-top:20px;" @submit.native.prevent="save"> <el-form-item label="广告位名称"> <el-input v-model="model.name"></el-input> </el-form-item> <el-form-item> <el-button type="primary" native-type="submit">保存</el-button> </el-form-item> </el-form> </div> </template> <script> export default { props: { id: {} }, data(){ return { model: {}, } }, methods: { async save(){ let res if(this.id){ res = await this.$http.put('rest/ads/' + this.id, this.model) }else{ res = await this.$http.post('rest/ads', this.model) } console.log("en?",res) this.$router.push('/ads/list') this.$message({ type: 'success', message: '保存成功' }) }, async fetch(){ const res = await this.$http.get('rest/ads/' + this.id) this.model = res.data } }, created(){ this.id && this.fetch() } } </script> ``` AdList.vue: ``` <template> <div> <h1>分类列表</h1> <el-table :data="items"> <el-table-column prop="_id" label="ID" width="220"> </el-table-column> <el-table-column prop="parent.name" label="上级分类"> </el-table-column> <el-table-column prop="name" label="分类名称"> </el-table-column> <el-table-column fixed="right" label="操作" width="100"> <template slot-scope="scope"> <el-button type="text" size="small" @click="$router.push('/ads/edit/' + scope.row._id)">编辑</el-button> <el-button @click="remove(scope.row)" type="text" size="small">删除</el-button> </template> </el-table-column> </el-table> </div> </template> <script> export default { data() { return { items: [] } }, methods: { async fetch(){ const res = await this.$http.get('rest/ads') this.items = res.data }, remove(row){ this.$confirm('是否确定要删除分类"' + row.name + '"?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(async () => { const res = await this.$http.delete('rest/ads/' + row._id) this.$message({ type: 'success', message: '删除成功!' }); if(res.status == 200){ this.fetch() } }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); } }, created() { this.fetch() } } </script> ``` 模型ad.js: ``` const mongoose = require('mongoose') const schema = new mongoose.Schema({ name: { type: String }, // 主要内容以数组格式存储,每条数据包括广告图片和广告链接 items: [{ image: { type: String }, url: { type: String } }] }) module.exports = mongoose.model('Ads', schema) ``` 测试接口均没问题。 ![](https://img.kancloud.cn/b9/92/b992b78a3193a11e593c030cef68aff1_1665x470.png) 2.添加广告元素(多组数据的上传) (1)在广告位名称下方创建添加技能模块: ``` <el-form-item label="添加广告"> <el-button type="text" size="small" @click="model.items.push({})"> <i class="el-icon-plus"></i> 添加广告 </el-button> <!-- 使用flex布局(栅格系统24列布局) --> <el-row type="flex" style="flex-wrap: wrap"> <!-- 由于要添加数据到数组,所以使用循环来建立多组数据,index为唯一的索引值 --> <el-col :md="12" v-for="(item, index) in model.items" :key="index"> <el-form-item label="广告链接"> <el-input v-model="item.url"></el-input> </el-form-item> <!-- 图片功能与技能模块创建过程相同 --> <el-form-item label="广告图"> <el-upload class="avatar-uploader" :action="$http.defaults.baseURL + '/upload'" :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload"> <img v-if="item.image" :src="item.image" class="avatar"> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload> </el-form-item> </el-col> </el-row> </el-form-item> ``` (2)修改js的data和methods: data: 把items内容数组放在model中,避免页面找不到items ``` data(){ return { model: { items: [], }, } }, ``` methods: a.进入修改广告位时的页面刷新函数,避免修改广告位内容时查询到的数据将items覆盖 ``` async fetch(){ const res = await this.$http.get('rest/ads/' + this.id) // 为避免直接给model赋值时覆盖model中的item字段,所以换一种赋值方式 // this.model = res.data this.model = Object.assign({}, this.model, res.data) } ``` b.添加图片时添加图片后的函数,理论上是将回调的图片url赋值到model的items中。但是我们数据中的items为数组格式,找不到该放在数组中的哪个字段中,所以我们不使用下面的handleAvatarSuccess函数。 ``` // 图片上传成功之后 handleAvatarSuccess(res) { // 新建字段赋值到model.items this.$set(this.model.items, 'image', res.url) }, ``` (3)修改图片上传html ![](https://img.kancloud.cn/96/3e/963e103ee36b65ca5a389182d94b6328_1218x805.png) 将函数改为参数的回调,直接将接收到图片url赋值到当前循环数组item的image中,最后一并保存到model.items。 此时,测试,添加四个广告: ![](https://img.kancloud.cn/08/0c/080c8ef8e05a4b1fb1a73226b6a5c081_1665x644.png) 没问题。 输入内容测试model: ![](https://img.kancloud.cn/1b/4e/1b4e0f9694c08158e466598431db9eed_1665x1072.png) 没问题。 3.删除单条广告 每一个广告位对应web端一个位置上的广告,选定位置后就不再进行修改。所以广告位中的广告数量如果不能修改,后期是非常麻烦的。 ![](https://img.kancloud.cn/3d/ef/3defd207838c5d2e0c48b75043983d18_1261x784.png) 点击删除广告按钮后立即删除,需要“是否要删除***”提醒的话大家自行创建函数。 4.完善上传接口 保存一下,看下哪里卡住,就修改哪里的接口。 ![](https://img.kancloud.cn/ea/ab/eaab6c96924892c0606d7de6327bf436_1665x644.png) 呀,没问题。 由于1.我们使用了CRUD接口,几乎不需要做改动就可以完成增删改查。而2.图片的上传又是独立接口,不与整体数据进行影响,只回调图片接口链接。所以在我们保存model到数据库时,就是单纯地将model数据保存,只要模型Ad.js的字段、类型和数组层级定义正确即可。