Vue + ElementUI的电商管理系统实例14 商品列表-添加商品
1、通過編程式導航跳轉到商品添加頁面
給添加商品按鈕添加點擊事件:
<el-button type="primary" @click="goAddpage">添加商品</el-button>
goAddpage事件函數:
// 跳轉到添加商品頁面
goAddpage() {
// 路由導航對象.push函數,跳轉到指定的路由頁面
this.$router.push('goods/add')
}
在goods文件夾下新建Add.vue文件:
<template>
<div>
添加商品組件頁面
</div>
</template>
<script>
export default {
}
</script>
<style lang="less" scoped>
</style>
添加路由:
import Add from '../components/goods/Add.vue'
const routes = [
{ path: '/', redirect: '/login' }, // 重定向
{ path: '/login', component: Login },
{
path: '/home',
component: Home,
redirect: '/welcome', // 重定向
children: [ // 子路由
{ path: '/welcome', component: Welcome },
{ path: '/users', component: Users }, // 用戶列表
{ path: '/rights', component: Rights }, // 權限列表
{ path: '/roles', component: Roles }, // 角色列表
{ path: '/categories', component: Cate }, // 商品分類
{ path: '/params', component: Params }, // 分類參數
{ path: '/goods', component: List }, // 商品列表
{ path: '/goods/add', component: Add } // 添加商品
]
}
]
點擊添加商品按鈕,效果圖:
2、渲染添加商品頁面的基本結構
還是面包屑和卡片視圖:
<template>
<div>
<!--面包屑導航區域-->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/home' }">首頁</el-breadcrumb-item>
<el-breadcrumb-item>商品管理</el-breadcrumb-item>
<el-breadcrumb-item>添加商品</el-breadcrumb-item>
</el-breadcrumb>
<!--卡片視圖區域-->
<el-card>
<!--警告提示區域-->
<el-alert title="添加商品信息" type="info" center show-icon :closable="false"></el-alert>
</el-card>
</div>
</template>
然后下面需要用到Steps 步驟條組件,要把Steps 和 step到添加到element.js中
選擇 含狀態步驟條 的代碼復制:
<!--步驟條區域-->
<el-steps :space="200" :active="1" finish-status="success">
<el-step title="已完成"></el-step>
<el-step title="進行中"></el-step>
<el-step title="步驟 3"></el-step>
</el-steps>
此時的效果圖:
3、美化步驟條組件
首先增加3個el-step,然后修改title的值:
<!--步驟條區域-->
<el-steps :space="200" :active="1" finish-status="success">
<el-step title="基本信息"></el-step>
<el-step title="商品參數"></el-step>
<el-step title="商品屬性"></el-step>
<el-step title="商品圖片"></el-step>
<el-step title="商品內容"></el-step>
<el-step title="完成"></el-step>
</el-steps>
然后在全局樣式中添加:
.el-steps{margin: 15px 0;}
.el-step__title{font-size: 13px;}
align-center標題和描述都將居中。
<el-steps :space="200" :active="1" finish-status="success" align-center>
修改默認激活為第一項:
<el-steps :space="200" :active="0" finish-status="success" align-center>
定義一個屬性綁定到active:
<el-steps :space="200" :active="activeIndex" finish-status="success" align-center>
<script>
export default {
data() {
return {
activeIndex: 0 // 當前激活的索引
}
}
}
</script>
此時效果圖:
4、渲染tab欄區域
添加tabs標簽代碼,可以通過tab-position設置標簽的位置:
<!--tab欄區域-->
<el-tabs :tab-position="'left'">
<el-tab-pane label="基本信息">基本信息</el-tab-pane>
<el-tab-pane label="商品參數">商品參數</el-tab-pane>
<el-tab-pane label="商品屬性">商品屬性</el-tab-pane>
<el-tab-pane label="商品圖片">商品圖片</el-tab-pane>
<el-tab-pane label="商品內容">商品內容</el-tab-pane>
</el-tabs>
效果圖:
5、實現步驟條和tab欄的數據聯動效果
steps步驟條組件的激活狀態是對應的activeIndex索引值
在tabs組件中,有屬性value / v-model :可以綁定選中選項卡的 name值
所以我們就把選項卡的name分別設置0-4的值,然后把v-model綁定activeIndex索引值,這樣每次切換選項卡時,它的name值就會綁定到activeIndex,由此實現聯動效果。
代碼:
<!--tab欄區域-->
<el-tabs v-model="activeIndex" :tab-position="'left'">
<el-tab-pane label="基本信息" name="0">基本信息</el-tab-pane>
<el-tab-pane label="商品參數" name="1">商品參數</el-tab-pane>
<el-tab-pane label="商品屬性" name="2">商品屬性</el-tab-pane>
<el-tab-pane label="商品圖片" name="3">商品圖片</el-tab-pane>
<el-tab-pane label="商品內容" name="4">商品內容</el-tab-pane>
</el-tabs>
因為v-model綁定得是字符串類型,所以要把activeIndex修改為字符串:
<script>
export default {
data() {
return {
activeIndex: '0' // 當前激活的索引
}
}
}
</script>
但是steps步驟條組件的active屬性綁定的是數字類型,所以要修改下:(隱式類型轉換)
<el-steps :space="200" :active="activeIndex - 0" finish-status="success" align-center>
此時刷新,可以實現聯動效果,如圖:
6、分拆表單的組成部分
在tabs標簽外面,添加form表單:
label-position=“top” 表示標簽的位置
<!--tab欄區域-->
<el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="100px" label-position="top">
<el-tabs v-model="activeIndex" :tab-position="'left'">
<el-tab-pane label="基本信息" name="0">基本信息</el-tab-pane>
<el-tab-pane label="商品參數" name="1">商品參數</el-tab-pane>
<el-tab-pane label="商品屬性" name="2">商品屬性</el-tab-pane>
<el-tab-pane label="商品圖片" name="3">商品圖片</el-tab-pane>
<el-tab-pane label="商品內容" name="4">商品內容</el-tab-pane>
</el-tabs>
</el-form>
<script>
export default {
data() {
// 添加商品的表單數據對象
addForm: {},
// 添加商品表單的驗證規則對象
addFormRules: {}
}
}
}
</script>
7、繪制基本信息面板的UI結構
記得要把tabs組件上的height="200px"刪掉,input指定type="number",只能輸入數字類型
添加代碼:
<el-tab-pane label="基本信息" name="0">
<el-form-item label="商品名稱" prop="goods_name">
<el-input v-model="addForm.goods_name"></el-input>
</el-form-item>
<el-form-item label="商品價格" prop="goods_price">
<el-input v-model="addForm.goods_price" type="number"></el-input>
</el-form-item>
<el-form-item label="商品重量" prop="goods_weight">
<el-input v-model="addForm.goods_weight" type="number"></el-input>
</el-form-item>
<el-form-item label="商品數量" prop="goods_number">
<el-input v-model="addForm.goods_number" type="number"></el-input>
</el-form-item>
</el-tab-pane>
<script>
export default {
data() {
return {
// 添加商品的表單數據對象
addForm: {
goods_name: '',
goods_price: 0,
goods_weight: 0,
goods_number: 0
},
// 添加商品表單的驗證規則對象
addFormRules: {
goods_name: [
{ required: true, message: '請輸入商品名稱', trigger: 'blur' }
],
goods_price: [
{ required: true, message: '請輸入商品價格', trigger: 'blur' }
],
goods_weight: [
{ required: true, message: '請輸入商品重量', trigger: 'blur' }
],
goods_number: [
{ required: true, message: '請輸入商品數量', trigger: 'blur' }
]
}
}
}
}
</script>
此時效果圖:
8、獲取商品分類數據
調用api的商品分類數據列表接口,前面商品分類功能有寫過
添加代碼:
<script>
export default {
data() {
return {
cateList: [] // 商品分類列表數據
}
},
created() {
this.getCateList()
},
methods: {
// 獲取所有商品分類數據
async getCateList() {
const { data: res } = await this.$http.get('categories')
if (res.meta.status !== 200) {
return this.$message.error('獲取商品分類失敗')
}
console.log(res)
this.cateList = res.data
}
}
}
</script>
9、繪制商品分類的級聯選擇器
添加級聯選擇器代碼:
<el-form-item label="商品分類" prop="goods_cat">
<!--選擇商品分類的級聯選擇框-->
<!-- options用來指定數據源 props用來指定配置對象 value/v-model選中項綁定值-->
<el-cascader
v-model="addForm.goods_cat"
:options="cateList"
:props="cateProps"
@change="cateChanged"
clearable
></el-cascader>
</el-form-item>
<script>
export default {
data() {
return {
// 添加商品的表單數據對象
addForm: {
goods_name: '',
goods_price: 0,
goods_weight: 0,
goods_number: 0,
goods_cat: [] // 商品所屬的分類數據
},
// 添加商品表單的驗證規則對象
addFormRules: {
goods_name: [
{ required: true, message: '請輸入商品名稱', trigger: 'blur' }
],
goods_price: [
{ required: true, message: '請輸入商品價格', trigger: 'blur' }
],
goods_weight: [
{ required: true, message: '請輸入商品重量', trigger: 'blur' }
],
goods_number: [
{ required: true, message: '請輸入商品數量', trigger: 'blur' }
],
goods_cat: [
{ required: true, message: '請選擇商品分類', trigger: 'blur' }
]
},
cateList: [], // 商品分類列表數據
// 指定級聯選擇框的配置對象
cateProps: {
expandTrigger: 'hover', // 次級菜單的展開方式 click / hover
value: 'cat_id', // 指定選中值的屬性
label: 'cat_name', // 指定選中標簽的名稱
children: 'children' // 指定父子嵌套的屬性
}
}
},
methods: {
// 級聯選擇框選中項變化,會觸發這個函數
cateChanged() {
console.log(this.addForm.goods_cat)
}
}
}
</script>
我們這里設置的goods_cat是個數組,后臺接口定義的是要接收字符串類型,后面還要進行轉譯。
效果圖:
10、只允許選中三級商品分類
// 級聯選擇框選中項變化,會觸發這個函數
cateChanged() {
// 證明選中的不是三級分類
if (this.addForm.goods_cat.length !== 3) {
this.addForm.goods_cat = [] // 清空級聯選擇框的數據
return
}
// 證明選中的是三級分類
console.log(this.addForm.goods_cat)
}
11、阻止標簽切換
在沒有填寫表單前,不允許切換標簽。
監聽標簽頁的切換事件,在事件的處理函數中,判斷是否處于第一個標簽中,同時還要判斷已選中的商品分類是否為三級商品分類。
tabs組件中屬性:before-leave 切換標簽之前的鉤子,若返回 false 或者返回 Promise 且被 reject,則阻止切換。返回一個Function(activeName, oldActiveName),其中activeName:代表即將進入的標簽頁的name名稱,oldActiveName:代表即將離開的標簽頁的name名稱。
添加代碼:
<el-tabs v-model="activeIndex" :tab-position="'left'" :before-leave="beforeTabLeave">
beforeTabLeave事件函數:
// 阻止標簽切換
beforeTabLeave(activeName, oldActiveName) {
// console.log('即將離開的標簽頁名字是' + oldActiveName)
// console.log('即將進入的標簽頁名字是' + activeName)
if (oldActiveName === '0' && this.addForm.goods_cat.length !== 3) {
this.$message.error('請先選擇商品分類')
return false
}
}
12、獲取動態參數列表數據
下面要實現的是商品參數標簽,需要調用api的參數列表接口,具體前面也有寫過
還需要用到tabs組件的tab-click事件,表示:tab 被選中時觸發
添加代碼:
<el-tabs v-model="activeIndex" :tab-position="'left'" :before-leave="beforeTabLeave"
@tab-click="tabClicked">
tabClicked事件函數:
// tab 被選中時觸發
async tabClicked() {
console.log(this.activeIndex)
}
這時打印的是當前激活標簽的name,所以要判斷下當打印為1時,請求參數列表接口,獲取參數列表數據
// tab 被選中時觸發
async tabClicked() {
console.log(this.activeIndex) // 當前激活標簽的name
// 證明訪問的時動態參數面板
if (this.activeIndex === '1') {
const { data: res } = await this.$http.get(
`categories/${this.addForm.goods_cat[2]}/attributes`,
{ params: { sel: 'many' } }
)
if (res.meta.status !== 200) {
return this.$message.error('獲取參數列表失敗')
}
console.log(res)
this.manyTableData = res.data
}
}
this.addForm.goods_cat[2]這樣寫的太復雜,也可以定義一個計算屬性來實現:
methods:{
// tab 被選中時觸發
async tabClicked() {
console.log(this.activeIndex) // 當前激活標簽的name
// 證明訪問的時動態參數面板
if (this.activeIndex === '1') {
const { data: res } = await this.$http.get(
`categories/${this.cateId}/attributes`,
{ params: { sel: 'many' } }
)
if (res.meta.status !== 200) {
return this.$message.error('獲取動態參數列表失敗')
}
console.log(res)
this.manyTableData = res.data
}
}
},
computed: {
// 當前選中的三級分類ID
cateId() {
if (this.addForm.goods_cat.length === 3) {
return this.addForm.goods_cat[2]
}
return null
}
}
13、繪制商品參數面板中的復選框組件
先在商品參數的標簽中添加代碼:
<el-tab-pane label="商品參數" name="1">
<!-- 渲染表單的item項 -->
<el-form-item v-for="item in manyTableData" :key="item.attr_id"
:label="item.attr_name">
</el-form-item>
</el-tab-pane>
因為attr.vals是字符串,所以要在獲取到參數列表數據時,將數據進行for循環,每循環一次把item項用空格做分隔,重新賦值為數組的形式。
修改tabClicked函數:
// tab 被選中時觸發
async tabClicked() {
console.log(this.activeIndex) // 當前激活標簽的name
// 證明訪問的時動態參數面板
if (this.activeIndex === '1') {
const { data: res } = await this.$http.get(
`categories/${this.cateId}/attributes`,
{ params: { sel: 'many' } }
)
if (res.meta.status !== 200) {
return this.$message.error('獲取動態參數列表失敗')
}
console.log(res)
// 循環data中的每一項,把attr_vals參數的字符串,重新賦值為item.attr_vals數組
res.data.forEach(item => {
item.attr_vals = item.attr_vals.length !== 0
? item.attr_vals.split(' ') : []
})
this.manyTableData = res.data
}
}
然后需要用到Checkbox 多選框組件中,多選框組:適用于多個勾選框綁定到同一個數組的情景,通過是否勾選來表示這一組選項中選中的項。
checkbox-group元素能把多個 checkbox 管理為一組,只需要在 Group 中使用v-model綁定Array類型的變量即可。el-checkbox的label屬性是該 checkbox 對應的值,若該標簽中無內容,則該屬性也充當 checkbox 按鈕后的介紹。label與數組中的元素值相對應,如果存在指定的值則為選中狀態,否則為不選中。
設置border屬性可以渲染為帶有邊框的多選框。
添加代碼:
<el-tab-pane label="商品參數" name="1">
<!-- 渲染表單的item項 -->
<el-form-item v-for="item in manyTableData" :key="item.attr_id"
:label="item.attr_name">
<!--復選框組-->
<el-checkbox-group v-model="item.attr_vals">
<el-checkbox :label="cb" v-for="(cb, i) in item.attr_vals"
:key="i" border size="small"></el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-tab-pane>
此時效果圖:
14、優化復選框的樣式
每個復選框的間隔過大,而且換行的話,第2行對不齊
添加樣式:
<style lang="less" scoped>
.el-checkbox{
margin: 0 10px 0 0 !important;
}
</style>
效果圖:
15、獲取靜態屬性列表
還是要調用api的參數列表接口,只不過參數變為靜態屬性的only
修改tabClicked函數,添加代碼:
// tab 被選中時觸發
async tabClicked() {
console.log(this.activeIndex) // 當前激活標簽的name
// 證明訪問的是動態參數面板
if (this.activeIndex === '1') {
const { data: res } = await this.$http.get(
`categories/${this.cateId}/attributes`,
{ params: { sel: 'many' } }
)
if (res.meta.status !== 200) {
return this.$message.error('獲取動態參數列表失敗')
}
console.log(res)
// 循環data中的每一項,把attr_vals參數的字符串,重新賦值為item.attr_vals數組
res.data.forEach(item => {
item.attr_vals = item.attr_vals.length !== 0
? item.attr_vals.split(' ') : []
})
this.manyTableData = res.data
} else if (this.activeIndex === '2') {
// 證明訪問的是靜態屬性面板
const { data: res } = await this.$http.get(
`categories/${this.cateId}/attributes`,
{ params: { sel: 'only' } }
)
if (res.meta.status !== 200) {
return this.$message.error('獲取靜態屬性列表失敗')
}
console.log(res)
this.onlyTableData = res.data
}
}
16、渲染商品屬性面板的UI結構
添加代碼:
<el-tab-pane label="商品屬性" name="2">
<el-form-item v-for="item in onlyTableData" :key="item.attr_id" :label="item.attr_name">
<el-input v-model="item.attr_vals"></el-input>
</el-form-item>
</el-tab-pane>
效果圖:
17、初步使用upload上傳組件
Upload 上傳組件:通過點擊或者拖拽上傳文件
通過 slot 你可以傳入自定義的上傳按鈕類型和文字提示。可通過設置limit和on-exceed來限制上傳文件的個數和定義超出限制時的行為。可通過設置before-remove來阻止文件移除操作。
action 必選參數,上傳的地址
on-preview 點擊文件列表中已上傳的文件時的鉤子 處理圖片預覽效果
on-remove 文件列表移除文件時的鉤子
list-type 文件列表的類型 指定預覽文件的類型
使用圖片列表縮略圖,復制代碼:
<el-tab-pane label="商品圖片" name="3">
<!--上傳組件-->
<!--action 表示圖片要上傳到的后臺API地址-->
<el-upload :action="uploadURL" :on-preview="handlePreview"
:on-remove="handleRemove" list-type="picture">
<el-button size="small" type="primary">點擊上傳</el-button>
</el-upload>
</el-tab-pane>
action表示圖片要上傳到的后臺API地址,需要圖片上傳接口的路徑,請求路徑:upload,請求方法:post,請求參數:file 上傳文件
data里添加:
// 上傳圖片的URL uploadURL: 'http://127.0.0.1:8888/api/private/v1/upload'
18、手動給upload組件綁定headers請求頭
這時我們打開控制臺的Network,然后點擊上傳按鈕,隨便選擇一張圖片上傳。這時發現Previwe里的msg顯示無效token,狀態碼400,證明我們上傳失敗了
我們最開始的時候在mian.js文件里通過axios的request攔截器,給每一個請求都掛載了一個Authorization字段,里面的值就是'token'。
這就證明upload組件上傳的時候沒有用到axios請求。
查看element的upload文檔,有個headers屬性:設置上傳的請求頭部 object對象
添加代碼:
<!--上傳組件-->
<!--action 表示圖片要上傳到的后臺API地址-->
<el-upload :action="uploadURL" :on-preview="handlePreview"
:on-remove="handleRemove" list-type="picture" :headers="headerObj">
<el-button size="small" type="primary">點擊上傳</el-button>
</el-upload>
<script>
export default {
data() {
return {
// 圖片上傳組件的headers請求頭對象
headerObj: {
Authorization: window.sessionStorage.getItem('token')
}
}
}
}
</script>
刷新重新點擊上傳按鈕上傳圖片,查看控制臺效果:
19、監聽upload組件的on-success事件
查看api接口文檔,發現添加商品接口,其中一項參數pics:上傳的圖片臨時路徑(對象)
"pics":[
{"pic":"/tmp_uploads/30f08d52c551ecb447277eae232304b8"}
],
我們剛才在控制臺里看到圖片上傳成功后服務器返回的信息,tmp_path字段里就是服務器保存的是圖片的臨時路徑。
我們下面需要做的就是監聽圖片上傳成功之后,把tmp_path的臨時路徑以對象的形式添加到pics數組中。
查看element文檔的upload組件,有個on-success事件:文件上傳成功時的鉤子函數,可以指定function(response, file, fileList) ,其中response代表服務器返回的數據,file是文件的信息,fileList是上次組件的文件列表。我們這里只用到response就行了。
在addForm對象中添加pics數組,然后添加on-success代碼:
<!--上傳組件-->
<!--action 表示圖片要上傳到的后臺API地址-->
<el-upload :action="uploadURL" :on-preview="handlePreview" :on-remove="handleRemove"
list-type="picture" :headers="headerObj" :on-success="handleSuccess">
<el-button size="small" type="primary">點擊上傳</el-button>
</el-upload>
<script>
export default {
data() {
return {
// 添加商品的表單數據對象
addForm: {
goods_name: '',
goods_price: 0,
goods_weight: 0,
goods_number: 0,
goods_cat: [], // 商品所屬的分類數據
pics: [] // 圖片的數組
},
}
},
methods: {
// 監聽圖片上傳成功的事件
handleSuccess(response) {
console.log(response)
// 1.拼接得到一個圖片信息對象
const picInfo = { pic: response.data.tmp_path }
// 2.將圖片信息對象,push到pics組數中
this.addForm.pics.push(picInfo)
console.log(this.addForm)
}
}
}
</script>
效果圖:
20、監聽upload組件的on-remove事件
1.獲取將要刪除的圖片的臨時路徑
2.從 pics 數組中,找到這個圖片對應的索引值
3.調用數組的 splice 方法,把圖片信息對象,從 pics 數組中刪除
代碼:
// 處理移除圖片的操作
handleRemove(file) {
// console.log(file)
// 1.獲取將要刪除的圖片的臨時路徑
const filePaht = file.response.data.tmp_path
// 2.從 pics 數組中,找到這個圖片對應的索引值
const i = this.addForm.pics.findIndex(x => x.pic === filePaht) // x 代表數組的每一項
// 3.調用數組的 splice 方法,把圖片信息對象,從 pics 數組中移除
this.addForm.pics.splice(i, 1)
console.log(this.addForm)
},
21、實現圖片的預覽效果
添加代碼:
<!--圖片預覽對話框-->
<el-dialog title="圖片預覽" :visible.sync="previewVisible" width="50%" >
<!--內容主體區域-->
<img width="100%" :src="picUrl" alt="">
</el-dialog>
<script>
export default {
data() {
return {
picUrl: '', // 圖片預覽路徑
previewVisible: false // 控制圖片預覽對話框是否顯示
}
},
methods: {
// 處理圖片預覽效果
handlePreview(file) {
console.log(file)
this.picUrl = file.response.data.url
this.previewVisible = true
},
}
}
</script>
現在上傳圖片后,點擊圖片名稱,就可以實現預覽了。
22、安裝并配置vue-quill-editor
Vue-Quill-Editor:
基于 Quill、適用于 Vue 的富文本編輯器,支持服務端渲染和單頁應用。
打開可視化工具,在左側菜單點擊依賴,然后點擊安裝依賴,在運行依賴里面搜索vue-quill-editor,進行安裝。
在全局注冊為全局可用的組件,在main.js文件里添加:
// 導入富文本編輯器 import VueQuillEditor from 'vue-quill-editor' // 導入富文本編輯器對應的樣式 import 'quill/dist/quill.core.css' import 'quill/dist/quill.snow.css' import 'quill/dist/quill.bubble.css' // 將富文本編輯器注冊為全局可用的組件 Vue.use(VueQuillEditor)
回到Add.vue文件中添加代碼:
<el-tab-pane label="商品內容" name="4">
<!--富文本編輯器組件-->
<quill-editor v-model="addForm.goods_introduce"></quill-editor>
</el-tab-pane>
<script>
export default {
data() {
return {
// 添加商品的表單數據對象
addForm: {
goods_name: '',
goods_price: 0,
goods_weight: 0,
goods_number: 0,
goods_cat: [], // 商品所屬的分類數據
pics: [], // 圖片的數組
goods_introduce: '' // 商品的詳情描述
},
}
}
}
</script>
需要在全局樣式golbal.css中指定富文本編輯器的最小高度:
.ql-editor{min-height: 300px;}
然后在編輯器下面還需要一個添加商品的按鈕:
<el-tab-pane label="商品內容" name="4">
<!--富文本編輯器組件-->
<quill-editor v-model="addForm.goods_introduce"></quill-editor>
<!--添加商品按鈕-->
<el-button type="primary" @click="addGoods" class="btnAdd">添加商品</el-button>
</el-tab-pane>
<style lang="less" scoped>
.btnAdd{margin-top: 15px;}
</style>
此時效果圖:
23、實現表單數據的預驗證
給添加商品按鈕添加點擊事件:
<!--添加商品按鈕--> <el-button type="primary" @click="addGoods" class="btnAdd">添加商品</el-button>
addGoods函數:
// 點擊按鈕,添加商品
addGoods() {this.$refs.addFormRef.validate(async valid => {
// 預校驗
if (!valid) {
return this.$message.error('請填寫必要的表單項')
}
// 執行添加的業務邏輯
})
}
24、把goods_cat從數組轉換為字符串
添加商品需要調用api的添加商品接口,請求路徑:goods,請求方法:post
請求參數:
goods_name | 商品名稱 | 不能為空 |
goods_cat | 以為','分割的分類列表 | 不能為空 |
goods_price | 價格 | 不能為空 |
goods_number | 數量 | 不能為空 |
goods_weight | 重量 | 不能為空 |
goods_introduce | 介紹 | 可以為空 |
pics | 上傳的圖片臨時路徑(對象) | 可以為空 |
attrs | 商品的參數(數組),包含 `動態參數` 和 `靜態屬性` | 可以為空 |
因為接口文檔里,goods_cat參數要以為','分割的字符串類型,我們保存的是數組類型,所以需要轉換下
// 點擊按鈕,添加商品
addGoods() {
this.$refs.addFormRef.validate(async valid => {
// 預校驗
if (!valid) {
return this.$message.error('請填寫必要的表單項')
}
// 執行添加的業務邏輯
console.log(this.addForm)
this.addForm.goods_cat = this.addForm.goods_cat.join(',')
})
}
這時已經把goods_cat的值轉成了字符串類型,但是在上面級聯選擇器代碼中,v-model="addForm.goods_cat",這里綁定的是數組類型,這里會報錯。(新版沒報錯)
所以需要lodashcloneDeep(obj)。
_.cloneDeep(value) 這個方法類似 _.clone,除了它會遞歸拷貝 value。(也叫深拷貝)。
還是打開可視化工具,添加運行依賴,搜索“lodash”,進行安裝。
在本頁面進行導入,并添加代碼:
<script>
import _ from 'lodash'
export default {
methods: {
// 點擊按鈕,添加商品
addGoods() {
this.$refs.addFormRef.validate(async valid => {
// 預校驗
if (!valid) {
return this.$message.error('請填寫必要的表單項')
}
// 執行添加的業務邏輯
console.log(this.addForm)
// this.addForm.goods_cat = this.addForm.goods_cat.join(',')
// lodash cloneDeep(obj) 深拷貝,復制為新對象
const form = _.cloneDeep(this.addForm)
form.goods_cat = form.goods_cat.join(',')
console.log(form)
})
}
}
}
</script>
25、處理attrs數組
attrs 商品的參數(數組),包含 `動態參數` 和 `靜態屬性`
"attrs":[
{
"attr_id":15,
"attr_value":"ddd"
},
{
"attr_id":15,
"attr_value":"eee"
}
]
首先要把 attrs 添加到 addForm 對象中,然后分別循環manyTableData 和onlyTableData,并把他們中的每一項進行處理,最后push到attrs數組中。
// 點擊按鈕,添加商品
addGoods() {
this.$refs.addFormRef.validate(async valid => {
// 預校驗
if (!valid) {
return this.$message.error('請填寫必要的表單項')
}
// 執行添加的業務邏輯
console.log(this.addForm)
// this.addForm.goods_cat = this.addForm.goods_cat.join(',')
// lodash cloneDeep(obj) 深拷貝,復制為新對象
const form = _.cloneDeep(this.addForm)
form.goods_cat = form.goods_cat.join(',')
console.log(form)
// 處理動態參數
console.log(this.manyTableData)
this.manyTableData.forEach(item => {
const newInfo = { attr_id: item.attr_id, attr_value: item.attr_vals.join(' ') }
this.addForm.attrs.push(newInfo)
})
// 處理靜態屬性
this.onlyTableData.forEach(item => {
this.addForm.attrs.push({ attr_id: item.attr_id, attr_value: item.attr_vals })
})
form.attrs = this.addForm.attrs
console.log(form)
})
}
26、完成添加商品的操作
在上面代碼下發起網絡請求:
// 點擊按鈕,添加商品
addGoods() {
this.$refs.addFormRef.validate(async valid => {
// 預校驗
if (!valid) {
return this.$message.error('請填寫必要的表單項')
}
// 執行添加的業務邏輯
console.log(this.addForm)
// this.addForm.goods_cat = this.addForm.goods_cat.join(',')
// lodash cloneDeep(obj) 深拷貝,復制為新對象
const form = _.cloneDeep(this.addForm)
form.goods_cat = form.goods_cat.join(',')
console.log(form)
// 處理動態參數
console.log(this.manyTableData)
this.manyTableData.forEach(item => {
const newInfo = { attr_id: item.attr_id, attr_value: item.attr_vals.join(' ') }
this.addForm.attrs.push(newInfo)
})
// 處理靜態屬性
this.onlyTableData.forEach(item => {
this.addForm.attrs.push({ attr_id: item.attr_id, attr_value: item.attr_vals })
})
form.attrs = this.addForm.attrs
console.log(form)
// 請求服務器接口,添加商品
const { data: res } = await this.$http.post('goods', form)
if (res.meta.status !== 201) {
return this.$message.error('添加商品失敗!')
}
this.$message.success('添加商品成功!')
// 路由導航對象.push函數,跳轉到指定的路由頁面
this.$router.push('/goods')
})
}
添加成功后,跳轉到商品列表頁,效果圖:
27、將goods_list分支的代碼合并,并推送到遠程
goods_list分支提交到本地倉庫,并推送到遠程:
git branch git add . git commit -m "完成了商品功能的開發" git push
合并到master,并推送到遠程:
git branch git checkout master git merge goods_list git push
總結
以上是生活随笔為你收集整理的Vue + ElementUI的电商管理系统实例14 商品列表-添加商品的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: How to handle the ge
- 下一篇: Marketing Cloud的cont