完整源码可以私聊我,需要一点点费用~
页面展示
方案一
方案二
代码解释
方案一:使用v-show
这种方案只适合有两种页面
现在form表单中设置好要展现的页面名(此处的url没有作用不用管)
通过一个两个for循环分别将form表单填入的数据回显到页面中,并通过menuHandle函数进行 点击后会发生的事件,:index和:key都是用来定位那一个单独的div
可以看到点击后触发函数里这个show变量的true和flase。
而具体内容中写了两个页面内容,再通过v-if函数展现dish和comment页面
方案二:使用<iframe>
同样的通过两个v-for循环将menuList中的内容页面展现出来,同时绑定一个menuHandle函数,点击的时候触发该函数
该函数被触发的时候,就会将当前元素的id、url等元素填入到展现的form表单中
内容展现区就是通过<iframe>框架进行展现
代码展示
方案一
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=no,minimal-ui"> <title>k1饱了吗</title> <link rel="icon" href="images/favico.ico"> <!--不同屏幕尺寸根字体设置--> <script src="./js/base.js"></script> <!--element-ui的样式--> <link rel="stylesheet" href="../backend/plugins/element-ui/index.css"/> <!--引入vant样式--> <link rel="stylesheet" href="styles/vant.min.css"/> <!-- 引入样式 --> <link rel="stylesheet" href="styles/index.css"/> <!--本页面内容的样式--> <link rel="stylesheet" href="styles/main.css"/> <link rel="stylesheet" href="styles/icon/iconfont.css"/> </head> <body> <div id="main" class="app"> <div class="divHead"> <img src="./images/user.png" @click="toUserPage"/> </div> <!-- 头部标签区--> <div class="divTitle"> <div class="divStatic"> <img src="./images/logo.png" class="logo"/> <div class="divDesc"> <div class="divName">饱了吗餐厅</div> <div class="divSend"> <span><img src="./images/time.png"/> 距离1.5km</span> <span><img src="./images/money.png"/> 配送费6元</span> <span><img src="./images/location.png"/> 预计时长12min</span> </div> </div> </div> <div class="divDesc"> 简介: 饱了吗餐厅是对抗饿了么的独立的品牌,定位“大众化的美食外送餐饮”,和美了么内卷竞争。 </div> </div> <!-- 菜品和评论选择区--> <div class="divSelect"> <div v-for="item in menuList" :key="item.id"> <div :index="item.id" v-if="item.children && item.children.length>0"> <template slot="title"> <span>{{item.name}}</span> </template> <div v-for="sub in item.children" :index="sub.id" :key="sub.id" @click="menuHandle(sub,false)" > <span slot="title" :class="sub.name">{{sub.name}}</span> </div> </div> <div v-else :index="item.id" @click="menuHandle(item,false)"> <span slot="title">{{item.name}}</span> </div> </div> </div> <!-- 内容展现区--> <div class="divBody"> <!--展示菜单--> <div class="dish" v-if="show" style="display: flex;"> <div class="divType"> <ul> <li v-for="(item,index) in categoryList" :key="index" @click="categoryClick(index,item.id,item.type)" :class="{active:activeType === index}">{{item.name}} </li> </ul> </div> <div class="divMenu"> <div> <div class="divItem" v-for="(item,index) in dishList" :key="index" @click="dishDetails(item)"> <el-image :src="imgPathConvert(item.image)"> <div slot="error" class="image-slot"> <img src="./images/noImg.png"/> </div> </el-image> <div> <div class="divName">{{item.name}}</div> <div class="divDesc">{{item.description}}</div> <div class="divDesc">{{'月销' + (item.saleNum ? item.saleNum : 0) }}</div> <div class="divBottom"><span>¥</span><span>{{item.price/100}}</span></div> <div class="divNum"> <div class="divSubtract" v-if="item.number > 0"> <img src="./images/subtract.png" @click.prevent.stop="subtractCart(item)"/> </div> <div class="divDishNum">{{item.number}}</div> <div class="divTypes" v-if="item.flavors && item.flavors.length > 0 && !item.number " @click.prevent.stop="chooseFlavorClick(item)">选择规格 </div> <div class="divAdd" v-else> <img src="./images/add.png" @click.prevent.stop="addCart(item)"/> </div> </div> </div> </div> </div> </div> </div> <!--展示评论--> <div class="comment" v-if="!show"> <div> <div class="divItem" v-for="(item,index) in commentList" :key="index"> <div class="divInfo"> <div class="divName">{{item.name}}</div> <div class="divTime">{{item.createTime}}</div> </div> <div class="divComment"> <div v-if="item.description" class="divDesc">{{item.description}}</div> </div> <el-image v-if="item.image" :src="imgPathConvert(item.image)" > </el-image> </div> </div> </div> <!-- 菜品选择区--> <!-- <div class="app-main" v-loading="loading">--> <!-- <div class="divTmp" v-show="loading"></div>--> <!-- <iframe--> <!-- id="cIframe"--> <!-- class="c_iframe"--> <!-- name="cIframe"--> <!-- :src="iframeUrl"--> <!-- width="100%"--> <!-- height="auto"--> <!-- frameborder="0"--> <!-- v-show="!loading"--> <!-- ></iframe>--> <!-- </div>--> </div> <div class="divLayer"> <div class="divLayerLeft"></div> <div class="divLayerRight"></div> </div> <div class="divCart" v-if="categoryList.length > 0"> <div :class="{imgCartActive: cartData && cartData.length > 0, imgCart:!cartData || cartData.length<1}" @click="openCart"></div> <div :class="{divGoodsNum:1===1, moreGoods:cartData && cartData.length > 99}" v-if="cartData && cartData.length > 0">{{ goodsNum }} </div> <div class="divNum"> <span>¥</span> <span>{{goodsPrice}}</span> </div> <div class="divPrice"></div> <div :class="{btnSubmitActive: cartData && cartData.length > 0, btnSubmit:!cartData || cartData.length<1}" @click="toAddOrderPage">去结算 </div> </div> <van-dialog v-model="dialogFlavor.show" :show-confirm-button="false" class="dialogFlavor" ref="flavorDialog"> <div class="dialogTitle">{{dialogFlavor.name}}</div> <div class="divContent"> <div v-for="flavor in dialogFlavor.flavors" :key="flavor.id"> <div class="divFlavorTitle">{{flavor.name}}</div> <span v-for="item in JSON.parse(flavor.value)" :key="item" @click="flavorClick(flavor,item)" :class="{spanActive:flavor.dishFlavor === item}" >{{item}}</span> </div> </div> <div class="divBottom"> <div><span class="spanMoney">¥</span>{{dialogFlavor.price/100}}</div> <div @click="dialogFlavorAddCart">加入购物车</div> </div> <div class="divFlavorClose" @click="dialogFlavor.show = false"> <img src="./images/close.png"/> </div> </van-dialog> <van-popup v-model="cartDialogShow" position="bottom" :style="{ height: '50%' }" class="dialogCart"> <div class="divCartTitle"> <div class="title">购物车</div> <div class="clear" @click="clearCart"> <i class="el-icon-delete"></i> 清空 </div> </div> <div class="divCartContent"> <div v-for="item in cartData" :key="item.id" class="divCartItem"> <el-image :src="imgPathConvert(item.image)"> <div slot="error" class="image-slot"> <img src="./images/noImg.png"/> </div> </el-image> <div class="divDesc"> <div class="name">{{item.name}}</div> <div class="price"> <span class="spanMoney">¥</span>{{item.amount}} </div> </div> <div class="divNum"> <div class="divSubtract"> <img src="./images/subtract.png" @click="cartNumberSubtract(item)"/> </div> <div class="divDishNum">{{item.number}}</div> <div class="divAdd"> <img src="./images/add.png" @click="cartNumAdd(item)"/> </div> </div> <div class="divSplit"></div> </div> </div> </van-popup> <van-dialog v-model="detailsDialog.show" :show-confirm-button="false" class="detailsDialog" ref="detailsDialog" v-if="detailsDialog.show" > <div class="divContainer"> <el-image :src="imgPathConvert(detailsDialog.item.image)"> <div slot="error" class="image-slot"> <img src="./images/noImg.png"/> </div> </el-image> <div class="title">{{detailsDialog.item.name}}</div> <div class="content">{{detailsDialog.item.description}}</div> </div> <div class="divNum"> <div class="left"> <span>¥</span><span>{{detailsDialog.item.price/100}}</span> </div> <div class="right"> <div class="divSubtract" v-if="detailsDialog.item.number > 0"> <img src="./images/subtract.png" @click="subtractCart(detailsDialog.item)"/> </div> <div class="divDishNum">{{detailsDialog.item.number}}</div> <div class="divTypes" v-if="detailsDialog.item.flavors && detailsDialog.item.flavors.length > 0 && !detailsDialog.item.number " @click="chooseFlavorClick(detailsDialog.item)">选择规格 </div> <div class="divAdd" v-else> <img src="./images/add.png" @click="addCart(detailsDialog.item)"/> </div> </div> </div> <div class="detailsDialogClose" @click="detailsDialog.show = false"> <img src="./images/close.png"/> </div> </van-dialog> <van-dialog v-model="setMealDialog.show" :show-confirm-button="false" class="setMealDetailsDialog" ref="setMealDetailsDialogd" v-if="setMealDialog.show" > <div class="divContainer"> <div class="title">{{setMealDialog.item.name}}</div> <div class="item" v-for="(item,index) in setMealDialog.item.list" :key="index"> <el-image :src="imgPathConvert(item.image)"> <div slot="error" class="image-slot"> <img src="./images/noImg.png"/> </div> </el-image> <div class="divSubTitle">{{item.name + '(' + item.copies + '份)' }} <div class="divPrice"> <span>¥</span><span>{{item.price/100}}</span> </div> </div> <div class="content">{{item.description}}</div> </div> </div> <div class="divNum"> <div class="left"> <span>¥</span><span>{{setMealDialog.item.price/100}}</span> </div> <div class="right"> <div class="divSubtract" v-if="setMealDialog.item.number > 0"> <img src="./images/subtract.png" @click="subtractCart(setMealDialog.item)"/> </div> <div class="divDishNum">{{setMealDialog.item.number}}</div> <div class="divAdd" v-if="setMealDialog.item.number"> <img src="./images/add.png" @click="addCart(setMealDialog.item)"/> </div> <div class="addCart" @click="addCart(setMealDialog.item)" v-if="!setMealDialog.item.number">加入购物车</div> </div> </div> <div class="detailsDialogClose" @click="setMealDialog.show = false"> <img src="./images/close.png"/> </div> </van-dialog> </div> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="../backend/plugins/vue/vue.js"></script> <!-- 引入组件库 --> <script src="../backend/plugins/element-ui/index.js"></script> <!-- 引入vant样式 --> <script src="./js/vant.min.js"></script> <!-- 引入axios --> <script src="../backend/plugins/axios/axios.min.js"></script> <script src="./js/request.js"></script> <script src="./js/common.js"></script> <script src="./api/main.js"></script> <script src="../api/comment.js"></script> </body> <script> new Vue({ el: '#main', data() { return { //左边菜品类别index activeType: 0, categoryList: [], categoryId: undefined, dishList: [], cartData: [], commentList: [], dialogFlavor: { name: '', flavors: [], dishId: undefined, price: undefined, show: false, image: '' }, cartDialogShow: false, detailsDialog: { show: false, item: {image: ''} }, setMealDialog: { show: false, item: {} }, menuList: [ // { // id: '1', // name: '门店管理', // children: [ { id: '2', name: '菜品', url: '../front/page/showDish.html', icon: 'icon-member' }, { id: '3', name: '评论', url: '../backend/page/member/list.html', icon: 'icon-category' } ], iframeUrl: '../backend/page/member/list.html', headTitle: '菜品', goBackFlag: false, loading: true, timer: null, show: true } }, computed: { goodsNum() { let num = 0 this.cartData.forEach(item => { num += item.number }) if (num < 99) { return num } else { return '99+' } }, goodsPrice() { let price = 0 this.cartData.forEach(item => { price += (item.number * item.amount) }) return price } }, created() { const userInfo = window.localStorage.getItem('userInfo') if (userInfo) { this.userInfo = JSON.parse(userInfo) } this.closeLoading() }, watch: { 'dialogFlavor.show'(flag) { if (flag) { document.querySelector('.divCart').style.zIndex = 1 } else { document.querySelector('.divCart').style.zIndex = 3000 } }, }, mounted() { this.initData() window.menuHandle = this.menuHandle }, methods: { //初始化数据 initData() { Promise.all([categoryListApi(), cartListApi({})]).then(res => { //获取分类数据 if (res[0].code === 1) { this.categoryList = res[0].data if (Array.isArray(res[0].data) && res[0].data.length > 0) { this.categoryId = res[0].data[0].id if (res[0].data[0].type === 1) { this.getDishList() this.getCommentList() } else { this.getSetmealData() } } } else { this.$notify({type: 'warning', message: res[0].msg}); } //获取菜品数据 if (res[1].code === 1) { this.cartData = res[1].data } else { this.$notify({type: 'warning', message: res[1].msg}); } }) }, //分类点击 categoryClick(index, id, type) { this.activeType = index this.categoryId = id if (type === 1) {//菜品 this.getDishList() } else { this.getSetmealData() } }, //获取菜品数据 async getDishList() { if (!this.categoryId) { return } const res = await dishListApi({categoryId: this.categoryId, status: 1}) if (res.code === 1) { let dishList = res.data const cartData = this.cartData if (dishList.length > 0 && cartData.length > 0) { dishList.forEach(dish => { cartData.forEach(cart => { if (dish.id === cart.dishId) { dish.number = cart.number } }) }) } this.dishList = dishList } else { this.$notify({type: 'warning', message: res.msg}); } }, //获取套餐数据setmealId async getSetmealData() { if (!this.categoryId) { return } const res = await setmealListApi({categoryId: this.categoryId, status: 1}) if (res.code === 1) { let dishList = res.data const cartData = this.cartData if (dishList.length > 0 && cartData.length > 0) { dishList.forEach(dish => { cartData.forEach(cart => { if (dish.id === cart.setmealId) { dish.number = cart.number } }) }) } this.dishList = dishList } else { this.$notify({type: 'warning', message: res.msg}); } }, //获取购物车数据 async getCartData() { const res = await cartListApi({}) if (res.code === 1) { this.cartData = res.data } else { this.$notify({type: 'warning', message: res.msg}); } }, //菜单中往购物车中添加商品 async addCart(item) { let params = { amount: item.price / 100,//金额 dishFlavor: item.dishFlavor,//口味 如果没有传undefined dishId: undefined,//菜品id setmealId: undefined,//套餐id name: item.name, image: item.image } if (Array.isArray(item.flavors)) {//表示是菜品 params.dishId = item.id } else {//表示套餐 套餐没有口味 params.setmealId = item.id } const res = await addCartApi(params) if (res.code === 1) { this.dishList.forEach(dish => { if (dish.id === item.id) { dish.number = res.data.number } }) if (this.setMealDialog.show) { item.number = res.data.number } this.getCartData() } else { this.$notify({type: 'warning', message: res.msg}); } }, //菜单中减少选中的商品 async subtractCart(item) { let params = { dishId: item.id, } if (!Array.isArray(item.flavors)) { params = { setmealId: item.id, } } const res = await updateCartApi(params) if (res.code === 1) { this.dishList.forEach(dish => { if (dish.id === item.id) { dish.number = (res.data.number === 0 ? undefined : res.data.number) } }) if (this.setMealDialog.show) { item.number = (res.data.number === 0 ? undefined : res.data.number) } this.getCartData() } else { this.$notify({type: 'warning', message: res.msg}); } }, //展开购物车 openCart() { if (this.cartData.length > 0) { this.cartDialogShow = true } }, //购物车中增加商品数量 async cartNumAdd(item) { let params = { amount: item.amount,//金额 dishFlavor: item.dishFlavor,//口味 如果没有传undefined dishId: item.dishId,//菜品id setmealId: item.setmealId,//套餐id name: item.name, image: item.image } const res = await addCartApi(params) if (res.code === 1) { this.dishList.forEach(dish => { if (dish.id === (item.dishId || item.setmealId)) { dish.number = res.data.number } }) console.log(this.dishList) this.getCartData() } else { this.$notify({type: 'warning', message: res.msg}); } }, //购物车中减少商品数量 async cartNumberSubtract(item) { let params = { dishId: item.dishId, setmealId: item.setmealId, } const res = await updateCartApi(params) if (res.code === 1) { this.dishList.forEach(dish => { if (dish.id === (item.dishId || item.setmealId)) { dish.number = (res.data.number === 0 ? undefined : res.data.number) } }) this.getCartData() } else { this.$notify({type: 'warning', message: res.msg}); } }, //修改商品列表中的数据number changeDishList(item) { for (let ele of this.dishList) { if (ele.id === (item.setmealId || item.dishId)) { ele.number = item.number } } }, //清空购物车 async clearCart() { const res = await clearCartApi() if (res.code === 1) { for (let ele of this.dishList) { ele.number = undefined } this.cartData = [] this.cartDialogShow = false } else { this.$notify({type: 'warning', message: res.msg}); } }, //点击选择规格 chooseFlavorClick(item) { this.dialogFlavor = { name: '', flavors: [], dishId: undefined, price: undefined, show: false } this.dialogFlavor = { name: item.name, flavors: item.flavors, dishId: item.id, price: item.price, show: true, image: item.image } }, flavorClick(flavor, item) { flavor.dishFlavor = item //强制刷新dialog的dom this.dialogFlavor.show = false this.dialogFlavor.show = true }, //选择规格加入购物车 dialogFlavorAddCart() { const dialogFlavor = this.dialogFlavor let flag = true let dishFlavor = [] dialogFlavor.flavors.forEach(item => { if (item.dishFlavor) { dishFlavor.push(item.dishFlavor) } else { flag = false Notify({type: 'warning', message: '请选择' + item.name}); } }) if (flag) { this.addCart({ price: dialogFlavor.price, dishFlavor: dishFlavor.join(","), id: dialogFlavor.dishId, flavors: [], image: dialogFlavor.image, name: dialogFlavor.name }) this.dialogFlavor.show = false } }, //网络图片路径转换 imgPathConvert(path) { return imgPath(path) }, //跳转到去结算界面 toAddOrderPage() { if (this.cartData.length > 0) { window.requestAnimationFrame(() => { window.location.href = '/front/page/add-order.html' }) } }, toUserPage() { window.requestAnimationFrame(() => { window.location.href = '/front/page/user.html' }) }, async dishDetails(item) { //先清除对象数据,如果不行的话dialog使用v-if this.detailsDialog.item = {} this.setMealDialog.item = {} if (Array.isArray(item.flavors)) { this.detailsDialog.item = item this.detailsDialog.show = true } else { //显示套餐的数据 const res = await setMealDishDetailsApi(item.id) if (res.code === 1) { this.setMealDialog.item = {...item, list: res.data} this.setMealDialog.show = true } else { this.$notify({type: 'warning', message: res.msg}); } } }, addComment() { window.location.href = 'page/addComment.html' }, menuHandle(item, goBackFlag) { this.loading = true this.menuActived = item.id this.iframeUrl = item.url this.headTitle = item.name this.goBackFlag = goBackFlag this.show = !this.show this.closeLoading() }, closeLoading() { this.timer = null this.timer = setTimeout(() => { this.loading = false }, 1000) }, showContent(button){ if(button == 'showDishContent'){ this.showContent = true; this.showComment = false; }else if(button == 'showCommentContent'){ this.showContent = false; this.showComment = true; } }, async getCommentList(){ const res = await commentListApi() if(res.code === 1){ this.commentList = res.data }else { this.$notify({type: 'warning', message: res.msg}) } } } }) </script> </html>
方案二
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>11外卖管理端</title> <link rel="shortcut icon" href="favicon.ico"> <!-- 引入样式 --> <!-- <link rel="stylesheet" href="plugins/element-ui/index.css"/> --> <link rel="stylesheet" href="styles/common.css"/> <link rel="stylesheet" href="styles/index.css"/> <link rel="stylesheet" href="styles/icon/iconfont.css"/> <style> .body { min-width: 1366px; } .app-main { height: calc(100% - 64px); } .app-main .divTmp { width: 100%; height: 100%; } </style> </head> <body> <div class="app" id="app"> <div class="app-wrapper openSidebar clearfix"> <!-- sidebar --> <div class="sidebar-container"> <el-scrollbar wrap-class="scrollbar-wrapper"> <el-menu> <div v-for="item in menuList" :key="item.id"> <el-submenu :index="item.id" v-if="item.children && item.children.length>0"> <template slot="title"> <i class="iconfont" :class="item.icon"></i> <span>{{item.name}}</span> </template> <el-menu-item v-for="sub in item.children" :index="sub.id" :key="sub.id" @click="menuHandle(sub,false)" > <i :class="iconfont" :class="sub.icon"></i> <span slot="title">{{sub.name}}</span> </el-menu-item > </el-submenu> <el-menu-item v-else :index="item.id" @click="menuHandle(item,false)"> <i class="iconfont" :class="item.icon"></i> <span slot="title">{{item.name}}</span> </el-menu-item> </div> </el-menu> </el-scrollbar> </div> <div class="main-container"> <!-- <navbar /> --> <div class="navbar"> <div class="head-lable"> <span v-if="goBackFlag" class="goBack" @click="goBack()" ><img src="images/icons/btn_back@2x.png" alt=""/> 返回</span > <span>{{headTitle}}</span> </div> <div class="right-menu"> <div class="avatar-wrapper">{{ userInfo.name }}</div> <!-- <div class="logout" @click="logout">退出</div> --> <img src="images/icons/btn_close@2x.png" class="outLogin" alt="退出" @click="logout"/> </div> </div> <div class="app-main" v-loading="loading"> <div class="divTmp" v-show="loading"></div> <iframe id="cIframe" class="c_iframe" name="cIframe" :src="iframeUrl" width="100%" height="auto" frameborder="0" v-show="!loading" ></iframe> </div> </div> </div> </div> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="plugins/vue/vue.js"></script> <!-- 引入组件库 --> <script src="plugins/element-ui/index.js"></script> <!-- 引入axios --> <script src="plugins/axios/axios.min.js"></script> <script src="js/request.js"></script> <script src="./api/login.js"></script> <script> new Vue({ el: '#app', data() { return { defAct: '2', menuActived: '2', userInfo: {}, menuList: [ // { // id: '1', // name: '门店管理', // children: [ { id: '2', name: '员工管理', url: 'page/member/list.html', icon: 'icon-member' }, { id: '3', name: '分类管理', url: 'page/category/list.html', icon: 'icon-category' }, { id: '4', name: '菜品管理', url: 'page/food/list.html', icon: 'icon-food' }, { id: '5', name: '套餐管理', url: 'page/combo/list.html', icon: 'icon-combo' }, { id: '6', name: '订单明细', url: 'page/order/list.html', icon: 'icon-order' } // ], // }, ], iframeUrl: 'page/member/list.html', headTitle: '员工管理', goBackFlag: false, loading: true, timer: null } }, computed: {}, created() { const userInfo = window.localStorage.getItem('userInfo') if (userInfo) { this.userInfo = JSON.parse(userInfo) } this.closeLoading() }, beforeDestroy() { this.timer = null clearTimeout(this.timer) }, mounted() { window.menuHandle = this.menuHandle }, methods: { logout() { logoutApi().then((res) => { if (res.code === 1) { localStorage.removeItem('userInfo') window.location.href = '/backend/page/login/login.html' } }) }, goBack() { // window.location.href = 'javascript:history.go(-1)' const menu = this.menuList.find(item => item.id === this.menuActived) // this.goBackFlag = false // this.headTitle = menu.name this.menuHandle(menu, false) }, menuHandle(item, goBackFlag) { this.loading = true this.menuActived = item.id this.iframeUrl = item.url this.headTitle = item.name this.goBackFlag = goBackFlag this.closeLoading() }, closeLoading() { this.timer = null this.timer = setTimeout(() => { this.loading = false }, 1000) } } }) </script> </body> </html>