1: shortList页面代码如下:
<template> <div class="fillcontain"> <head-top></head-top> <div class="table_container"> <el-table :data="tableData" style=" 100%"> <el-table-column type="expand"> <template scope="props"> <el-form label-position="left" inline class="demo-table-expand"> <el-form-item label="店铺名称"> <span>{{ props.row.name }}</span> </el-form-item> <el-form-item label="店铺地址"> <span>{{ props.row.address }}</span> </el-form-item> <el-form-item label="店铺介绍"> <span>{{ props.row.description }}</span> </el-form-item> <el-form-item label="店铺 ID"> <span>{{ props.row.id }}</span> </el-form-item> <el-form-item label="联系电话"> <span>{{ props.row.phone }}</span> </el-form-item> <el-form-item label="评分"> <span>{{ props.row.rating }}</span> </el-form-item> <el-form-item label="销售量"> <span>{{ props.row.recent_order_num }}</span> </el-form-item> <el-form-item label="分类"> <span>{{ props.row.category }}</span> </el-form-item> </el-form> </template> </el-table-column> <el-table-column label="店铺名称" prop="name"> </el-table-column> <el-table-column label="店铺地址" prop="address"> </el-table-column> <el-table-column label="店铺介绍" prop="description"> </el-table-column> <el-table-column label="操作" width="200"> <template scope="scope"> <el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button> <el-button size="mini" type="Success" @click="addFood(scope.$index, scope.row)">添加食品</el-button> <el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button> </template> </el-table-column> </el-table> <div class="Pagination"> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" :page-size="20" layout="total, prev, pager, next" :total="count"> </el-pagination> </div> <el-dialog title="修改店铺信息" v-model="dialogFormVisible"> <el-form :model="selectTable"> <el-form-item label="店铺名称" label-width="100px"> <el-input v-model="selectTable.name" auto-complete="off"></el-input> </el-form-item> <el-form-item label="详细地址" label-width="100px"> <el-autocomplete v-model="address.address" :fetch-suggestions="querySearchAsync" placeholder="请输入地址" style=" 100%;" @select="addressSelect" ></el-autocomplete> <span>当前城市:{{city.name}}</span> </el-form-item> <el-form-item label="店铺介绍" label-width="100px"> <el-input v-model="selectTable.description"></el-input> </el-form-item> <el-form-item label="联系电话" label-width="100px"> <el-input v-model="selectTable.phone"></el-input> </el-form-item> <el-form-item label="店铺分类" label-width="100px"> <el-cascader :options="categoryOptions" v-model="selectedCategory" change-on-select ></el-cascader> </el-form-item> <el-form-item label="商铺图片" label-width="100px"> <el-upload class="avatar-uploader" :action="baseUrl + '/v1/addimg/shop'" :show-file-list="false" :on-success="handleServiceAvatarScucess" :before-upload="beforeAvatarUpload"> <img v-if="selectTable.image_path" :src="baseImgPath + selectTable.image_path" class="avatar"> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="dialogFormVisible = false">取 消</el-button> <el-button type="primary" @click="updateShop">确 定</el-button> </div> </el-dialog> </div> </div> </template> <script> import headTop from '../components/headTop' import {baseUrl, baseImgPath} from '@/config/env' import {cityGuess, getResturants, getResturantsCount, foodCategory, updateResturant, searchplace, deleteResturant} from '@/api/getData' export default { data(){ return { baseUrl, baseImgPath, city: {}, offset: 0, limit: 20, count: 0, tableData: [], currentPage: 1, selectTable: {}, dialogFormVisible: false, categoryOptions: [], selectedCategory: [], address: {}, } }, created(){ this.initData(); }, components: { headTop, }, methods: { async initData(){ try{ this.city = await cityGuess(); const countData = await getResturantsCount(); if (countData.status == 1) { this.count = countData.count; }else{ throw new Error('获取数据失败'); } this.getResturants(); }catch(err){ console.log('获取数据失败', err); } }, async getCategory(){ try{ const categories = await foodCategory(); categories.forEach(item => { if (item.sub_categories.length) { const addnew = { value: item.name, label: item.name, children: [] } item.sub_categories.forEach((subitem, index) => { if (index == 0) { return } addnew.children.push({ value: subitem.name, label: subitem.name, }) }) this.categoryOptions.push(addnew) } }) }catch(err){ console.log('获取商铺种类失败', err); } }, async getResturants(){ const {latitude, longitude} = this.city; const restaurants = await getResturants({latitude, longitude, offset: this.offset, limit: this.limit}); this.tableData = []; restaurants.forEach(item => { const tableData = {}; tableData.name = item.name; tableData.address = item.address; tableData.description = item.description; tableData.id = item.id; tableData.phone = item.phone; tableData.rating = item.rating; tableData.recent_order_num = item.recent_order_num; tableData.category = item.category; tableData.image_path = item.image_path; this.tableData.push(tableData); }) }, handleSizeChange(val) { console.log(`每页 ${val} 条`); }, handleCurrentChange(val) { this.currentPage = val; this.offset = (val - 1)*this.limit; this.getResturants() }, handleEdit(index, row) { this.selectTable = row; this.address.address = row.address; this.dialogFormVisible = true; this.selectedCategory = row.category.split('/'); if (!this.categoryOptions.length) { this.getCategory(); } }, addFood(index, row){ this.$router.push({ path: 'addGoods', query: { restaurant_id: row.id }}) }, async handleDelete(index, row) { try{ const res = await deleteResturant(row.id); if (res.status == 1) { this.$message({ type: 'success', message: '删除店铺成功' }); this.tableData.splice(index, 1); }else{ throw new Error(res.message) } }catch(err){ this.$message({ type: 'error', message: err.message }); console.log('删除店铺失败') } }, async querySearchAsync(queryString, cb) { if (queryString) { try{ const cityList = await searchplace(this.city.id, queryString); if (cityList instanceof Array) { cityList.map(item => { item.value = item.address; return item; }) cb(cityList) } }catch(err){ console.log(err) } } }, addressSelect(vale){ const {address, latitude, longitude} = vale; this.address = {address, latitude, longitude}; }, handleServiceAvatarScucess(res, file) { if (res.status == 1) { this.selectTable.image_path = res.image_path; }else{ this.$message.error('上传图片失败!'); } }, beforeAvatarUpload(file) { const isRightType = (file.type === 'image/jpeg') || (file.type === 'image/png'); const isLt2M = file.size / 1024 / 1024 < 2; if (!isRightType) { this.$message.error('上传头像图片只能是 JPG 格式!'); } if (!isLt2M) { this.$message.error('上传头像图片大小不能超过 2MB!'); } return isRightType && isLt2M; }, async updateShop(){ this.dialogFormVisible = false; try{ Object.assign(this.selectTable, this.address); this.selectTable.category = this.selectedCategory.join('/'); const res = await updateResturant(this.selectTable) if (res.status == 1) { this.$message({ type: 'success', message: '更新店铺信息成功' }); this.getResturants(); }else{ this.$message({ type: 'error', message: res.message }); } }catch(err){ console.log('更新餐馆信息失败', err); } }, }, } </script> <style lang="less"> @import '../style/mixin'; .demo-table-expand { font-size: 0; } .demo-table-expand label { 90px; color: #99a9bf; } .demo-table-expand .el-form-item { margin-right: 0; margin-bottom: 0; 50%; } .table_container{ padding: 20px; } .Pagination{ display: flex; justify-content: flex-start; margin-top: 8px; } .avatar-uploader .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; } .avatar-uploader .el-upload:hover { border-color: #20a0ff; } .avatar-uploader-icon { font-size: 28px; color: #8c939d; 120px; height: 120px; line-height: 120px; text-align: center; } .avatar { 120px; height: 120px; display: block; } </style>
el-table:
data = "tableData": table和这个tableData绑定。
el-table-column:
<el-table-column
label="店铺名称" // 列名称
prop="name"> // 和tableData.name绑定
理解vue中的scope的使用:
这里scope的位置是el-table-column, 所以它绑定的是一行的值。 并且值是 {"row":{"name":"XXXX","address":"XXXX","ID":"XXX"},"$index":0}
下面看点击“编辑”弹出框的功能:
el-dialog:用v-model来控制dialog的显示和隐藏。
<el-dialog title="修改店铺信息" v-model="dialogFormVisible">
el-autocomplete
详细地址有输入时自动补全的功能,用这个el-autocomplete
el-cascader : 商铺分类的选择列表功能用这个控件。
created(){ // 页面还没渲染的时候执行,取得数据
this.initData();
},
el-pagination : 分页相关的控件
点击 “添加食品” 的时候:跳转到 addGoods页面,还要传递参数,这个是如何实现的?
页面跳转之前把restaurant_id: row.id放到query中,然后跳转过去;
addFood(index, row){
this.$router.push({ path: 'addGoods', query: { restaurant_id: row.id }})
},
在新页面渲染之前,从this.$route.query中可以得到参数。
created(){
if (this.$route.query.restaurant_id) {
this.restaurant_id = this.$route.query.restaurant_id;