技能学习:学习使用Node.js + Vue.js,开发前端全栈网站-11.动态添加分栏上传多组数据

简介: 例如有些时候需要上传多张图片,但是并不确定留下几个图片位,这是我们就想手动添加图片位,从而实现自定义数量图片的上传。我们以广告上传为例,上传多个广告。

例如有些时候需要上传多张图片,但是并不确定留下几个图片位,这是我们就想手动添加图片位,从而实现自定义数量图片的上传。我们以广告上传为例,上传多个广告。

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)

测试接口均没问题。
在这里插入图片描述

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
在这里插入图片描述
函数改为参数的回调,直接将接收到图片url赋值到当前循环数组item的image中,最后一并保存到model.items。

此时,测试,添加四个广告:
在这里插入图片描述
没问题。
输入内容测试model:
在这里插入图片描述
没问题。

3.删除单条广告

每一个广告位对应web端一个位置上的广告,选定位置后就不再进行修改。所以广告位中的广告数量如果不能修改,后期是非常麻烦的。
在这里插入图片描述
点击删除广告按钮后立即删除,需要“是否要删除*”提醒的话大家自行创建函数。

4.完善上传接口

保存一下,看下哪里卡住,就修改哪里的接口。
在这里插入图片描述
呀,没问题。
由于1.我们使用了CRUD接口,几乎不需要做改动就可以完成增删改查。而2.图片的上传又是独立接口,不与整体数据进行影响,只回调图片接口链接。所以在我们保存model到数据库时,就是单纯地将model数据保存,只要模型Ad.js的字段、类型和数组层级定义正确即可。

相关文章
|
8月前
|
前端开发 JavaScript 算法
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
transition过渡属性 早期在Web中要实现动画效果,都是依赖于JavaScript或Flash来完成。 但在CSS3中新增加了一个新的模块transition,它可以通过一些简单的CSS事件来触发元素的外观变化, 让效果显得更加细腻。简单点说,就是通过鼠标经过、获得焦点,被点击或对元素任何改变中触发, 并平滑地以动画效果改变CSS的属性值。 在CSS中创建简单的过渡效果可以从以下几个步骤来实现: 在默认样式中声明元素的初始状态样式; 声明过渡元素最终状态样式,比如悬浮状态; 在默认样式中通过添加
418 1
|
8月前
|
前端开发 JavaScript 算法
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
transform变形 css3在原来的基础上新增了变形和动画相关属性,通过这些属性可以实现以前需要大段JavaScript才能实现的 功能。 CSS3的变形功能可以对HTML组件执行位移、旋转、缩放、倾斜4种几何变换,这样的变换可以控制HTML组件 呈现出丰富的外观。 借助于位移、旋转、缩放、倾斜这4种几何变换,CSS3提供了transition动画。 transition动画比较简单,只要指定HTML组件的哪些CSS属性需要使用动画效果来执行变化,并指定动画时间,就可保证动画播放。 比transitio
414 1
|
JavaScript 前端开发 数据可视化
【01】Cocos游戏开发引擎从0开发一款游戏-cocos环境搭建以及配置-Cocos Creator软件系统下载安装-node环境-优雅草卓伊凡
【01】Cocos游戏开发引擎从0开发一款游戏-cocos环境搭建以及配置-Cocos Creator软件系统下载安装-node环境-优雅草卓伊凡
1051 2
【01】Cocos游戏开发引擎从0开发一款游戏-cocos环境搭建以及配置-Cocos Creator软件系统下载安装-node环境-优雅草卓伊凡
|
人工智能 监控 JavaScript
HarmonyOS5云服务技术分享--ArkTS开发Node环境
本文详细讲解了在HarmonyOS(ArkTS API 9及以上)中使用云函数的开发技巧,结合Node.js和HTTP触发器,从零开始手把手教学。内容涵盖核心能力、开发流程(配置到部署)、高阶优化及常见问题解决,并提供实际应用场景示例。助你快速掌握Serverless开发,提升效率,探索跨端协作与AI集成等未来方向。
|
JavaScript 数据可视化 前端开发
three.js简单实现一个3D三角函数学习理解
1.Three.js简介 Three.js是一个基于JavaScript编写的开源3D图形库,利用WebGL技术在网页上渲染3D图形。它提供了许多高级功能,如几何体、纹理、光照、阴影等,以便开发者能够快速地创建复杂且逼真的3D场景。同时,Three.js还具有很好的跨平台和跨浏览器兼容性,让用户无需安装任何插件就可以在现代浏览器上观看3D内容。
443 0
|
JavaScript 前端开发 jenkins
抛弃node和vscode,如何用记事本开发出一个完整的vue前端项目
本文探讨了在不依赖Node和VSCode的情况下,仅使用记事本和浏览器开发一个完整的Vue3前端项目的方法。通过CDN引入Vue、Vue Router、Element-UI等库,直接编写HTML文件实现页面功能,展示了前端开发的本质是生成HTML。虽然日常开发离不开现代工具,但掌握这种基础方法有助于快速实现想法或应对特殊环境限制。文章还介绍了如何用Node简单部署HTML文件到服务器,提供了一种高效、轻量的开发思路。
462 10
|
存储 JavaScript 前端开发
|
JavaScript 前端开发
JavaScript学习 -- 内置函数(Math和Date)
JavaScript学习 -- 内置函数(Math和Date)
169 0
|
JavaScript 前端开发
JavaScript学习 -- 内置函数(Math和Date)
JavaScript学习 -- 内置函数(Math和Date)
184 0
|
存储 JavaScript 前端开发

热门文章

最新文章

  • 1
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
    1206
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    537
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    418
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    414
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    525
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    707
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    1299
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    300
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    1082
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    491