例如有些时候需要上传多张图片,但是并不确定留下几个图片位,这是我们就想手动添加图片位,从而实现自定义数量图片的上传。我们以广告上传为例,上传多个广告。
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的字段、类型和数组层级定义正确即可。
- tp6+vue
- 1.工具和本地环境
- 2.启动项目
- 3.路由、模型与数据库操作
- 4.优化后端接口,前端使用axios实现接口功能
- 5.用户登录,bcrypt(hash)加密与验证
- 6.用户登录(二),token验证
- 7.分类的模型关联和通用CRUD接口
- 8.使用vue的markdown编辑器并批量上传图片
- Node.js + Vue.js
- 工具,本地环境
- 2.1启动项目
- 3.element-ui和vue-router路由的安装和使用
- 4.使用axios,并创建接口上传数据到mongodb数据库
- 5.mongoodb数据库的“删、改、查”操作
- 6.mongodb数据库无限层级的数据关联(子分类)
- 7.使用mongodb数据库关联多个分类(关联多个数据)
- 8.server端使用通用CRUD接口
- 9.图片上传
- 10.vue的富文本编辑器(vue2-editor)
- 11.动态添加分栏上传多组数据
- 12-1.管理员模块
- 13-1.搭建前台web端页面
- 1.使用sass工具搭建前台web端页面
- 2.sass工具的变量
- 3.使用flex布局并开始搭建web端
- 4.vue广告轮播图,并使用接口引入数据
- 5.使用字体图标(iconfont)
- 6.卡片组件的封装
- 14-1.生产环境编译
- 1.环境编译
- 2.购买域名服务器并解析域名到服务器
- 3.nginx配置web服务器并安装网站环境
- 4.git拉取代码到服务器
- 5.配置Nginx反向代理
- 6.迁移本地数据到服务器(mongodump)
- uni
- 1.工具&本地环境
- 2.页面制作
- 3.页面制作、组件与轮播
- 4.页面跳转与横向滑动
- 5.用户授权登录和用户信息获取
- 6.用户注册和数据存储
- 7.用户填写表单信息