Element动态添加select及显示默认选项

最近开发一个商城,一个经典的我觉得是个商城都会有的一个东西就是规格选项,使用的是前后端分离,接口没啥问题,传递指定的值就行了。前端稍微有点复杂,要根据商品对应的spu动态去显示规格选项表单,貌似也没什么问题,正常提交了后端也没问题了,到修改的时候,问题就出来了。

首先遇到的问题就是点击商品对应的修改按钮,表单框里虽然也渲染出了该商品对应的规格选项表单,但是默认值不是该商品的,最开始我采用的办法是select的没有option像的value直接携带的是对象,商品返回的规格选项也是对象,对象就算长一样也不可能相等啊,所以默认值死活都不行,退其次按照以下的做法尝试。

先看下效果:

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
<template>
<div class="app-container">
<div style="width: 800px; margin: 0 auto;">
<el-card class="box-card" style="margin-top: 20px;">
<div slot="header" class="clearfix">
<span>商品列表</span>
</div>

<el-table :data="goods" border fit highlight-current-row style="width: 100%;">
<el-table-column label="ID" prop="id" align="center" width="80">
<template slot-scope="{row}">
<span>{{ row.id }}</span>
</template>
</el-table-column>

<el-table-column label="商品名" min-width="150px" align="center">
<template slot-scope="{row}">
<span>{{ row.name }}</span>
</template>
</el-table-column>
<el-table-column label="spu_id" min-width="150px" align="center">
<template slot-scope="{row}">
<span>{{ row.spu_id }}</span>
</template>
</el-table-column>

<el-table-column label="操作" align="center" width="230" class-name="small-padding fixed-width">
<template slot-scope="{row,$index}">
<el-button type="primary" size="mini" @click="handleUpdate(row)" icon="el-icon-edit">
修改
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<el-card class="box-card" style="margin-top: 50px;">
<div slot="header" class="clearfix">
<span>添加商品</span>
</div>
<el-form ref="dataForm" :model="forms" label-position="left" label-width="90px" style="padding: 0 50px;">
<el-row :gutter="100">


<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
<el-form-item label="商品spu">
<el-select v-model="forms.spu_id" class="filter-item" placeholder="请选择对应的商品spu" style="width: 100%;"
@change="getSpusOptions">
<el-option v-for="item in spus" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" v-for="(item, index) in current_sups" :key="item.id">
<el-form-item :label="item.name">
<el-select v-model="forms.specs[index]" class="filter-item" :placeholder="'请选择对应的'+item.name"
style="width: 100%;" @change="watch_select($event, item.id)">
<el-option v-for="option in item.options" :key="option.id" :label="option.value" :value="option.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</div>

</div>
</template>

<script>
export default {
data() {
return {


// 表单数据
forms: {
id: undefined,
name:"",
spu_id: "",
specs: {}
},
// 当前选择spu的规格数据
current_sups: [],
// 商品spu列表
spus: [{
id: 2,
name: "手机"
},
{
id: 5,
name: "电脑"
},
],
// 商品列表
goods: [
{
id: 15,
name: "苹果手机金色256G",
spu_id:2,
"specs": [
{
"spec_id": 4,
"option_id": 8
},
{
"spec_id": 5,
"option_id": 12
}
]
},
{
id: 16,
name: "联想电脑16英寸8核",
spu_id:5,
"specs": [
{
"spec_id": 7,
"option_id": 2
},
{
"spec_id": 8,
"option_id": 16
}
]
},
],
// 商品所有规格
sepcs: [{
id: 4,
spu_id: 2,
name: "颜色",
options: [{
id: 8,
value: "金色"
},
{
id: 9,
value: "深空灰"
},
{
id: 10,
value: "银色"
},
]
},
{
id: 5,
spu_id: 2,
name: "内存",
options: [{
id: 11,
value: "64GB"
},
{
id: 12,
value: "256GB"
}
]
},
{
id: 7,
spu_id: 5,
name: "屏幕尺寸",
options: [{
id: 1,
value: "14英寸"
},
{
id: 2,
value: "16英寸"
}
]
},
{
id: 8,
spu_id: 5,
name: "核心数",
options: [{
id: 16,
value: "8核"
},
{
id: 17,
value: "16核"
}
]
},
]
}
},
methods: {
// 获取指定spu下的规格选项值
getSpusOptions(spu_id) {
// 每次重新选择商品的时候,先清空下原始商品的规格选项
this.current_sups = []
// 清空原始商品规格选项值
this.forms.specs = {}
// 循环获取当前spu下的所有规格及其对应的规格选项
this.sepcs.forEach((item, index) => {
if (spu_id == item.spu_id) {
this.current_sups.push(item)
}
})
},
// 这个方法主要用来格式化提交时后端需要的规格选项格式如[{规格1:选项1},{规格2:选项2}],
// 此处没添加提交,所以该功能详见本人git
watch_select(option_id, spec_id){
console.log("当前变化的是什么:", option_id, spec_id)
},
// 点击修改按钮
handleUpdate(row){

// 每次重新选择商品的时候,先清空下原始商品的规格选项
this.current_sups = []
// 重新获取了该商品对应的所有规格选项
this.sepcs.forEach(item => {
if (row.spu_id == item.spu_id) {
this.current_sups.push(item)
}
})
// 规格选项值默认为商品的每个规格的选项值,用于修改时默认选择
row.specs.forEach((item, index)=>{
row.specs[index] = item.option_id
})
this.forms = row


},
}
}
</script>

<style>
</style>

以上代码并没有封装为后端需要的规格选项格式,包括动态验证的完整代码在本人的码云上:https://gitee.com/tonyu2016/mall_python_vue.git

完整版效果如下: