天天看點

技能學習:學習使用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)           

測試接口均沒問題。

技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-11.動态添加分欄上傳多組資料

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

技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-11.動态添加分欄上傳多組資料

将函數改為參數的回調,直接将接收到圖檔url指派到目前循環數組item的image中,最後一并儲存到model.items。

此時,測試,添加四個廣告:

技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-11.動态添加分欄上傳多組資料

沒問題。

輸入内容測試model:

技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-11.動态添加分欄上傳多組資料

3.删除單條廣告

每一個廣告位對應web端一個位置上的廣告,標明位置後就不再進行修改。是以廣告位中的廣告數量如果不能修改,後期是非常麻煩的。

技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-11.動态添加分欄上傳多組資料

點選删除廣告按鈕後立即删除,需要“是否要删除*”提醒的話大家自行建立函數。

4.完善上傳接口

儲存一下,看下哪裡卡住,就修改哪裡的接口。

技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-11.動态添加分欄上傳多組資料

呀,沒問題。

由于1.我們使用了CRUD接口,幾乎不需要做改動就可以完成增删改查。而2.圖檔的上傳又是獨立接口,不與整體資料進行影響,隻回調圖檔接口連結。是以在我們儲存model到資料庫時,就是單純地将model資料儲存,隻要模型Ad.js的字段、類型和數組層級定義正确即可。