背景
最近项目当中遇到了一个需求,就是需要在自己的后台系统中集成公众号菜单操作,当时给我整懵了,难道登录微信公众号设置不好嘛?人家一句,我用你后台,完了设置个公众号菜单你还让我又跑去登录公众号后台设置。当我听到这句话的时候没啥可说的了,谁叫咱拿人钱财呢,不得替人消灾解难啥的嘛。这么一想也就舒坦了,管他呢,干就完事了呗。
当我想了想后,NM,这不就是把公众号的后台操作逻辑这个重新copy一份过来嘛,在找后台小哥商量商量帮我写几个接口完事。既然这样那就好办了,不过啊,首页的找UI小姐姐给整个好看的手机设计稿才行了,不能光整两个按钮光秃秃的多不好看呢。
思考
基于以上于是有了今天的文章了,也算是记录下自己做过的东西了。废话不多说了咱先看看效果再说哈,
这就是今天需要实现的效果,看起来也还好,那咱们就开干了。
实现
俗话说得好,想千遍万变不如干一遍,show me the code。首页要做的就是把这样的一个UI给实现了。
静态制作
首页要做的就是布局,要把结构给划分出来,在这里呢也就不献丑了,各位都是高手,直接上代码吧
<div class="mp-management">
<div class="mp-wrapper">
<div class="mobile">
<div class="weixin-hd">
<div class="weixin-title">公众号</div>
</div>
<div class="weixin-menu menu_main">
<div class="menu_bottom">
<div class="menu_item el-icon-s-fold active">菜单名称</div>
<div class="submenu">
<div class="menu_bottom menu_addicon"><i class="el-icon-plus"></i></div>
<div class="subtitle menu_bottom">
<div class="menu_subItem active">子菜单</div>
</div>
</div>
</div>
<div class="menu_bottom menu_addicon"><i class="el-icon-plus"></i></div>
</div>
</div>
<div class="mp-content">
<div class="right">
<p>请选择菜单配置</p>
</div>
<div class="right">
<div class="configure-page">
<div class="delete-btn">
<el-button size="mini" type="danger" icon="el-icon-delete">删除当前菜单</el-button>
</div>
<div class="menu-name">
<span>菜单名称:</span>
<el-input v-model="name" placeholder="请输入菜单名称" clearable></el-input>
</div>
<div>
<div class="menu-content">
<span>菜单内容:</span>
<el-select v-model="type" clearable placeholder="请选择" class="menu_option">
<el-option label="发送消息" value="click"></el-option>
</el-select>
</div>
<div class="configur-content">
<el-tabs v-model="repType" type="border-card">
<el-tab-pane label="文字" name="text">
<div class="message-text">
<span>回复文本:</span>
<el-input v-model="repContent" placeholder="请输入内容" clearable></el-input>
</div>
</el-tab-pane>
<el-tab-pane label="图片" name="image">
<div class="message-upload">
<div class="upload">
<i class="el-icon-plus uploader-icon"></i>
<p>选择现有资源</p>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="音频" name="voice">
<div class="message-upload">
<div class="upload">
<i class="el-icon-plus uploader-icon"></i>
<p>选择现有资源</p>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="视频" name="video">
<div class="message-upload">
<div class="upload">
<i class="el-icon-plus uploader-icon"></i>
<p>选择现有资源</p>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
<div class="configur-content">
<el-card>
<div class="applet">
<span>跳转链接:</span>
<el-input v-model="url" placeholder="请输入链接" clearable></el-input>
</div>
</el-card>
</div>
<div class="configur-content">
<el-card>
<div class="applet">
<span>小程序的appid:</span>
<el-input v-model="appid" placeholder="请输入小程序的appid" clearable></el-input>
</div>
<div class="applet">
<span>小程序的页面路径:</span>
<el-input v-model="pagepath" placeholder="请输入小程序的页面路径,如:pages/index" clearable></el-input>
</div>
<div class="applet">
<span>备用网页:</span>
<el-input v-model="url" placeholder="不支持小程序的老版本客户端将打开本网页" clearable></el-input>
</div>
<p class="tips">tips:需要和公众号进行关联才可以把小程序绑定带微信菜单上哟!</p>
</el-card>
</div>
</div>
</div>
</div>
<div class="save-wrapper right">
<el-button type="primary">保存并发布</el-button>
</div>
</div>
</div>
</div>
所以的结构就如上ok了,接下来就给化个妆美化一下。样式就更没啥说的了,大家都是高手,这里我使用的less作为css的扩展哦。
.mp-management{
min-width: 1200px;
width: 1200px;
margin: 0 auto;
.mp-wrapper{
display: flex;
.mobile{
width: 350px;
height: 715px;
background: url("./iphone_backImg.png") no-repeat;
background-size: 100% auto;
padding: 518px 25px 88px;
position: relative;
box-sizing: border-box;
.weixin-hd{
color: #fff;
text-align: center;
position: relative;
bottom: 426px;
left:0px;
width: 300px;
height:64px;
background: transparent url(./menu_head.png) no-repeat 0 0;
background-position: 0 0;
background-size: 100%;
.weixin-title{
color:#fff;
font-size:14px;
width:100%;
text-align: center;
position:absolute;
top: 33px;
left: 0px;
}
}
.weixin-menu{
background: transparent url(./menu_foot.png) no-repeat 0 0;
padding-left: 43px;
font-size: 12px;
}
.menu_main{
display: flex;
.menu_bottom{
position: relative;
display: inline-block;
box-sizing: border-box;
flex: 1;
text-align: center;
border: 1px solid #ebedee;
border-right: none;
background-color: #fff;
cursor: pointer;
&:nth-child(3){
border-right: none;
}
&.menu_addicon{
height: 46px;
line-height: 46px;
}
.menu_item{
height: 44px;
line-height: 44px;
text-align: center;
box-sizing: border-box;
width: 100%;
&.active{
border: 1px solid #2bb673;
}
}
.menu_subItem{
height: 44px;
line-height: 44px;
text-align: center;
box-sizing: border-box;
&.active{
border: 1px solid #2bb673;
}
}
}
i{
color:#2bb673;
}
.submenu{
position: absolute;
width: 100%;
bottom: 45px;
display: flex;
flex-direction: column;
.subtitle{
background-color: #fff;
box-sizing: border-box;
}
.menu_bottom{
border-right: 1px solid #ebedee;
}
}
}
}
.mp-content{
flex: 1;
margin-left: 20px;
.right{
background-color: rgb(245, 246, 250);
padding: 20px;
.el-input,.el-select{
flex: 1;
}
.configure-page{
.delete-btn{
text-align: right;
margin-bottom: 15px;
}
.menu-name{
margin-bottom: 20px;
display: flex;
align-items: center;
}
.menu-content{
display: flex;
align-items: center;
}
.configur-content{
margin-top: 20px;
background-color: #fff;
border-radius: 5px;
.message-text{
padding: 20px 0;
display: flex;
align-items: center;
}
.message-upload{
margin: 20px auto;
background-color: #ffffff;
cursor: pointer;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.upload{
width: 178px;
height: 178px;
border: 1px dashed #d9d9d9;
border-radius: 6px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
i{
font-size: 28px;
color: #8c939d;
}
p{
margin-top: 10px;
text-align: center;
}
}
img{
max-width: 300px;
}
}
.applet{
margin-bottom: 20px;
display: flex;
align-items: center;
}
.tips{
color:#29b6f6;
margin-top: 10px;
}
}
}
&.save-wrapper{
padding-top: 20px;
text-align: center;
}
}
}
}
}
当然了,这里我只是提供了一个简单的版本,如果有适配问题还请大家自行解决下,相信这个也难不倒各位高手了。预览的效果如下:
动态效果
静态的制作好后就需要添加相应的操作逻辑来使得这个静态的能够按照我们的逻辑来动。这里其实就是给相应的地方添加事件和操作了,这个过程也是我们在平时开发的时候的重要过程了。
左边菜单实现
要实现左边的菜单先需要知道几个问题:1、菜单可能没有的情况,2、菜单有一个的情况,3、菜单有两个,4、菜单有三个,5、菜单做多三个不能超过三个,6、有二级菜单。想明白了这几个问题那么我们就开始实现了。首先我们要看公众号菜单设置和获取的格式是什么样的:
通过上面两张图中对比后就知道了,设置和获取的格式都差不多,那么我们现在就只需要按照这个格式来默认定义几个数据,再根据定义的数据通过上面的接口渲染出来就可以了。
menu:{
button:[{type:'click',name:'菜单名称',sub_button:[{type:'click',name:'子菜单'}]},{type:'view',name:'菜单名称'},{type:'miniprogram',name:'菜单名称'}]
},//横向菜单
这里的菜单大家要根据后台的情况来定哦
关键的核心代码如下:
<div class="menu_bottom" v-for="(item, i) of menu.button" :key="i" >
<div @click="menuFun(i,item)" class="menu_item el-icon-s-fold" :class="{'active': isActive == i}">{{item.name}}</div>
<div class="submenu" v-if="isSubMenuFlag == i">
<div class="menu_bottom menu_addicon" v-if="!item.sub_button || item.sub_button.length < 5" @click="addSubMenu(i,item)"><i class="el-icon-plus"></i></div>
<template v-for="(subItem, k) in item.sub_button">
<div class="subtitle menu_bottom" v-if="item.sub_button" :key="k">
<div class="menu_subItem" :class="{'active': isSubMenuActive == i + '' +k}" @click="subMenuFun(subItem, i, k)">{{subItem.name}}</div>
</div>
</template>
</div>
</div>
<div class="menu_bottom menu_addicon" v-if="menuKeyLength < 3" @click="addMenu"><i class="el-icon-plus"></i></div>
这样左边的菜单大致就完成了,要看详细代码请移步文章末尾哦
右边内容
通过最开始的图可知道内容比较多的就是右边的内容了,这里有几部分:菜单相关、菜单内容相关。菜单有两部分,一个名称一个是菜单的内容类型。
<div class="menu-name">
<span>菜单名称:</span>
<el-input v-model="tempObj.name" placeholder="请输入菜单名称" :maxlength="nameMaxlength" clearable @blur="menuNameChange"></el-input>
</div>
<div class="menu-content">
<span>菜单内容:</span>
<el-select v-model="tempObj.type" clearable placeholder="请选择" class="menu_option" @change="menuChange">
<el-option v-for="item in menuOptions" :label="item.label" :value="item.value" :key="item.value"></el-option>
</el-select>
</div>
这两部分其实是很简单的一个是输入,一个是下拉选择对就ok了,麻烦的是下面的内容了。下面的内容要分几部分来说:一个是回复类的,一个是地址类,还有就是小程序类的,目前自己的项目最重要的就是小程序这块的,用于自己配置小程序的一些快捷入口。
回复类型的内容
回复类型的也有几个:文本、图片、音频、视频。这部分对接如下:
<el-tabs v-model="tempObj.repType" type="border-card" @tab-click="handleClick">
<el-tab-pane label="文字" name="text">
<div class="message-text">
<span>回复文本:</span>
<el-input v-model="tempObj.repContent" placeholder="请输入内容" clearable></el-input>
</div>
</el-tab-pane>
<el-tab-pane label="图片" name="image">
<div class="message-upload" @click="getMaterial('image')">
<img :src="curSelectMedia.url" alt="" v-if="tempObj.repType=='image' && tempObj.mediaId">
<div class="upload" v-else>
<i class="el-icon-plus uploader-icon"></i>
<p>选择现有资源</p>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="音频" name="voice">
<div class="message-upload" @click="getMaterial('voice')">
<audio :src="curSelectMedia.url" controls="controls" v-if="tempObj.repType=='voice' && tempObj.mediaId">您的浏览器不支持 audio 标签。</audio>
<div class="upload" v-else>
<i class="el-icon-plus uploader-icon"></i>
<p>选择现有资源</p>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="视频" name="video">
<div class="message-upload" @click="getMaterial('video')">
<video :src="curSelectMedia.url" controls="controls" v-if="tempObj.repType=='video' && tempObj.mediaId">您的浏览器不支持 video 标签。</video>
<div class="upload" v-else>
<i class="el-icon-plus uploader-icon"></i>
<p>选择现有资源</p>
</div>
</div>
</el-tab-pane>
</el-tabs>
连接类型的内容
连接类型的内容和上面的文本其实没有多大区别,但为了好理解还看,我还是分开了的,如下:
<el-card>
<div class="applet">
<span>跳转链接:</span>
<el-input v-model="tempObj.url" placeholder="请输入链接" clearable></el-input>
</div>
</el-card>
小程序内容的内容
这是这次项目的重点,小程序类型的,主要就是设置菜单打开小程序的一些路径,和连接和文本一起很想,但东西却要多一些,如下:
<el-card>
<div class="applet">
<span>小程序的appid:</span>
<el-input v-model="tempObj.appid" placeholder="请输入小程序的appid" clearable></el-input>
</div>
<div class="applet">
<span>小程序的页面路径:</span>
<el-input v-model="tempObj.pagepath" placeholder="请输入小程序的页面路径,如:pages/index" clearable></el-input>
</div>
<div class="applet">
<span>备用网页:</span>
<el-input v-model="tempObj.url" placeholder="不支持小程序的老版本客户端将打开本网页" clearable></el-input>
</div>
<p class="tips">tips:需要和公众号进行关联才可以把小程序绑定带微信菜单上哟!</p>
</el-card>
几乎到这里就差不多了。
完结
其实也就是基础的东西,也算是自己的一个学习笔记吧。完整的代码还是放在这,有需要的可以研究学习。
<template>
<div class="mp-management">
<div class="mp-wrapper" v-loading="saveLoading">
<div class="mobile">
<div class="weixin-hd">
<div class="weixin-title">公众号</div>
</div>
<div class="weixin-menu menu_main">
<div class="menu_bottom" v-for="(item, i) of menu.button" :key="i" >
<div @click="menuFun(i,item)" class="menu_item el-icon-s-fold" :class="{'active': isActive == i}">{{item.name}}</div>
<div class="submenu" v-if="isSubMenuFlag == i">
<div class="menu_bottom menu_addicon" v-if="!item.sub_button || item.sub_button.length < 5" @click="addSubMenu(i,item)"><i class="el-icon-plus"></i></div>
<template v-for="(subItem, k) in item.sub_button">
<div class="subtitle menu_bottom" v-if="item.sub_button" :key="k">
<div class="menu_subItem" :class="{'active': isSubMenuActive == i + '' +k}" @click="subMenuFun(subItem, i, k)">{{subItem.name}}</div>
</div>
</template>
</div>
</div>
<div class="menu_bottom menu_addicon" v-if="menuKeyLength < 3" @click="addMenu"><i class="el-icon-plus"></i></div>
</div>
</div>
<div class="mp-content">
<div v-if="!showRightFlag" class="right">
<p>请选择菜单配置</p>
</div>
<div v-if="showRightFlag" class="right">
<div class="configure-page">
<div class="delete-btn">
<el-button size="mini" type="danger" icon="el-icon-delete" @click="deleteMenu(tempObj)">删除当前菜单</el-button>
</div>
<div class="menu-name">
<span>菜单名称:</span>
<el-input v-model="tempObj.name" placeholder="请输入菜单名称" :maxlength="nameMaxlength" clearable @blur="menuNameChange"></el-input>
</div>
<div v-if="showConfigurContent">
<div class="menu-content">
<span>菜单内容:</span>
<el-select v-model="tempObj.type" clearable placeholder="请选择" class="menu_option" @change="menuChange">
<el-option v-for="item in menuOptions" :label="item.label" :value="item.value" :key="item.value"></el-option>
</el-select>
</div>
<div class="configur-content" v-if="tempObj.type == 'click'">
<el-tabs v-model="tempObj.repType" type="border-card" @tab-click="handleClick">
<el-tab-pane label="文字" name="text">
<div class="message-text">
<span>回复文本:</span>
<el-input v-model="tempObj.repContent" placeholder="请输入内容" clearable></el-input>
</div>
</el-tab-pane>
<el-tab-pane label="图片" name="image">
<div class="message-upload" @click="getMaterial('image')">
<img :src="curSelectMedia.url" alt="" v-if="tempObj.repType=='image' && tempObj.mediaId">
<div class="upload" v-else>
<i class="el-icon-plus uploader-icon"></i>
<p>选择现有资源</p>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="音频" name="voice">
<div class="message-upload" @click="getMaterial('voice')">
<audio :src="curSelectMedia.url" controls="controls" v-if="tempObj.repType=='voice' && tempObj.mediaId">您的浏览器不支持 audio 标签。</audio>
<div class="upload" v-else>
<i class="el-icon-plus uploader-icon"></i>
<p>选择现有资源</p>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="视频" name="video">
<div class="message-upload" @click="getMaterial('video')">
<video :src="curSelectMedia.url" controls="controls" v-if="tempObj.repType=='video' && tempObj.mediaId">您的浏览器不支持 video 标签。</video>
<div class="upload" v-else>
<i class="el-icon-plus uploader-icon"></i>
<p>选择现有资源</p>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
<div class="configur-content" v-if="tempObj.type == 'view'">
<el-card>
<div class="applet">
<span>跳转链接:</span>
<el-input v-model="tempObj.url" placeholder="请输入链接" clearable></el-input>
</div>
</el-card>
</div>
<div class="configur-content" v-if="tempObj.type == 'miniprogram'">
<el-card>
<div class="applet">
<span>小程序的appid:</span>
<el-input v-model="tempObj.appid" placeholder="请输入小程序的appid" clearable></el-input>
</div>
<div class="applet">
<span>小程序的页面路径:</span>
<el-input v-model="tempObj.pagepath" placeholder="请输入小程序的页面路径,如:pages/index" clearable></el-input>
</div>
<div class="applet">
<span>备用网页:</span>
<el-input v-model="tempObj.url" placeholder="不支持小程序的老版本客户端将打开本网页" clearable></el-input>
</div>
<p class="tips">tips:需要和公众号进行关联才可以把小程序绑定带微信菜单上哟!</p>
</el-card>
</div>
</div>
</div>
</div>
<div class="save-wrapper right" v-if="showRightFlag">
<el-button type="primary" @click="saveAndReleaseFun">保存并发布</el-button>
</div>
</div>
</div>
<el-dialog title="选择资源" :visible.sync="selectMaterial" width="50%">
<div class="table-page">
<el-table :data="materials" height="600">
<el-table-column prop="mediaId" label="媒体id"></el-table-column>
<el-table-column prop="name" label="标题"></el-table-column>
<el-table-column label="预览" v-if="curType=='image'"><template slot-scope="scope"><img :src="scope.row.url" alt=""></template></el-table-column>
<el-table-column prop="updateTime" label="更新时间"></el-table-column>
<el-table-column label="操作" align="center"><template slot-scope="scope"><span class="operation-btn" @click="selectItems(scope.row)">选择</span></template></el-table-column>
</el-table>
<el-pagination background @size-change="page.sizeChange" @current-change="page.currentChange" :current-page="page.pageNo" :page-sizes="page.pageSizes" :page-size="page.pageSize" :pager-count="5" layout="slot, sizes, total, prev, pager, next, jumper" :total="page.total"></el-pagination>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
showRightFlag:false,
menu:{
button:[]
},//横向菜单
isActive: -1,// 一级菜单点中样式
isSubMenuActive: -1,// 一级菜单点中样式
isSubMenuFlag: -1,// 二级菜单显示标志
tempObj:{},//右边临时变量,作为中间值牵引关系
tempSelfObj:{
//一些临时值放在这里进行判断,如果放在tempObj,由于引用关系,menu也会多了多余的参数
},
showConfigurContent:false,
nameMaxlength:0,//名称最大长度
menuOptions: [
{value: 'click',label: '发送消息'},
{value: 'view',label: '跳转网页'},
{value: 'miniprogram',label: '跳转小程序'}
],
saveLoading:false,
selectMaterial:false,
materials:[],
page: {
pageSize: 10, //偏移,页面数据个数
pageSizes: [10, 20, 50],
pageNo: 1, //当前页数
total: 0, //总数据量
sizeChange: this.handleSizeChange,
currentChange: this.handleCurrentChange
},
curType:null,
curSelectMedia:null
}
},
watch: {
'page.pageNo': function() {
this.getMaterial()
},
'page.pageSize': function() {
this.getMaterial()
},
'$route.query': function(val) {
if(val.reflist) {
this.getMaterial()
}
}
},
computed:{
// menuObj的长度,当长度 小于 3 才显示一级菜单的加号
menuKeyLength:function(){
return this.menu.button.length
}
},
mounted() {
this.getMenuFun()
},
methods: {
getMenuFun(){
// 获取全部设置好的菜单
},
getMaterial(){
// 获取不同类型的全部素材让用户选择
},
handleClick(tab){
this.tempObj.repType = tab.name
},
menuChange(){
this.tempObj.repType = this.tempObj.repType ? this.tempObj.repType : 'text'
if(this.tempObj.repType != 'text'){
this.getMaterialByMediaId(this.tempObj.mediaId)
}
},
getMaterialByMediaId(){
// 通过接口获取单个素材
// this.curSelectMedia =
},
menuNameChange(){
if(this.tempSelfObj.grand == '2'){
this.menu.button[this.tempSelfObj.index].sub_button[this.tempSelfObj.secondIndex].name = this.tempObj.name
this.menu.button[this.tempSelfObj.index].sub_button[this.tempSelfObj.secondIndex].key = this.tempObj.name
}
},
saveAndReleaseFun(){
this.$confirm('确定要保存并发布该菜单吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 保存菜单
// this.saveLoading = true
// var params = {
// ...this.menu
// }
// this.saveLoading = false
// this.$message.success('操作成功!')
}).catch(() => {
})
},
// 一级菜单点击事件
menuFun(i, item){
this.showRightFlag = true //右边菜单
this.tempObj = item //这个如果放在顶部,flag会没有。因为重新赋值了。
this.tempSelfObj.grand = "1" //表示一级菜单
this.tempSelfObj.index = i //表示一级菜单索引
this.isActive = i //一级菜单选中样式
this.isSubMenuFlag = i //二级菜单显示标志
this.isSubMenuActive = -1 //二级菜单去除选中样式
this.nameMaxlength = 4
if(item.sub_button&&item.sub_button.length>0){
this.showConfigurContent = false
}else{
this.showConfigurContent = true
}
},
// 二级菜单点击事件
subMenuFun(subItem, index, k){
this.showRightFlag = true //右边菜单
this.tempObj = subItem //将点击的数据放到临时变量,对象有引用作用
this.tempSelfObj.grand = "2" //表示二级菜单
this.tempSelfObj.index = index //表示一级菜单索引
this.tempSelfObj.secondIndex = k //表示二级菜单索引
this.isSubMenuActive = index + "" + k //二级菜单选中样式
this.isActive = -1 //一级菜单去除样式
this.showConfigurContent = true
this.nameMaxlength = 7
},
// 添加横向一级菜单
addMenu(){
let menuKeyLength = this.menuKeyLength
let addButton = {
name: "菜单名称",
sub_button: [],
appid: "",
content: "",
key: "",
mediaId: "",
pagepath: "",
repContent: "",
repDesc: "",
repHqUrl: "",
repName: "",
repThumbMediaId: "",
repThumbUrl: "",
repType: "",
repUrl: "",
type: "",
url: ""
}
this.$set(this.menu.button,menuKeyLength,addButton)
this.menuFun(this.menuKeyLength-1, addButton)
},
// 添加横向二级菜单
addSubMenu(i,item){
if(!item.sub_button||item.sub_button.length<=0){
this.$set( item, 'sub_button',[])
this.$delete( item, 'type')
this.$delete( item, 'pagepath')
this.$delete( item, 'url')
this.$delete( item, 'key')
this.$delete( item, 'media_id')
this.$delete( item, 'textContent')
this.showConfigurContent = false
}
let subMenuKeyLength = item.sub_button.length //获取二级菜单key长度
let addButton = {
name: "子菜单名称",
appid: "",
content: "",
key: "",
mediaId: "",
pagepath: "",
repContent: "",
repDesc: "",
repHqUrl: "",
repName: "",
repThumbMediaId: "",
repThumbUrl: "",
repType: "",
repUrl: "",
sub_button: [],
type: "",
url: ""
}
this.$set(item.sub_button,subMenuKeyLength,addButton)
this.subMenuFun(item.sub_button[subMenuKeyLength], i, subMenuKeyLength)
},
//删除当前菜单
deleteMenu(){
this.$confirm('确定要删除吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.deleteData() // 删除菜单数据
this.tempObj = {}
this.showRightFlag = false
this.isActive = -1
this.isSubMenuActive = -1
}).catch(() => {
})
},
// 删除菜单数据
deleteData(){
// 一级菜单的删除方法
if(this.tempSelfObj.grand == "1"){
this.menu.button.splice(this.tempSelfObj.index,1)
}
// 二级菜单的删除方法
if(this.tempSelfObj.grand == "2"){
this.menu.button[this.tempSelfObj.index].sub_button.splice(this.tempSelfObj.secondIndex, 1)
}
this.$message({
type: 'success',
message: '删除成功!'
})
},
// 用户选取素材
selectItems(row){
this.tempObj.mediaId = row.mediaId
this.curSelectMedia = row
this.selectMaterial = false
},
handleSizeChange(val) {
this.page.pageSize = val
},
handleCurrentChange(val) {
this.page.pageNo = val
},
},
}
</script>
<style lang="less">
.mp-management{
min-width: 1200px;
width: 1200px;
margin: 0 auto;
.mp-wrapper{
display: flex;
.mobile{
width: 350px;
height: 715px;
background: url("./iphone_backImg.png") no-repeat;
background-size: 100% auto;
padding: 518px 25px 88px;
position: relative;
box-sizing: border-box;
.weixin-hd{
color: #fff;
text-align: center;
position: relative;
bottom: 426px;
left:0px;
width: 300px;
height:64px;
background: transparent url(./menu_head.png) no-repeat 0 0;
background-position: 0 0;
background-size: 100%;
.weixin-title{
color:#fff;
font-size:14px;
width:100%;
text-align: center;
position:absolute;
top: 33px;
left: 0px;
}
}
.weixin-menu{
background: transparent url(./menu_foot.png) no-repeat 0 0;
padding-left: 43px;
font-size: 12px;
}
.menu_main{
display: flex;
.menu_bottom{
position: relative;
display: inline-block;
box-sizing: border-box;
flex: 1;
text-align: center;
border: 1px solid #ebedee;
border-right: none;
background-color: #fff;
cursor: pointer;
&:nth-child(3){
border-right: none;
}
&.menu_addicon{
height: 46px;
line-height: 46px;
}
.menu_item{
height: 44px;
line-height: 44px;
text-align: center;
box-sizing: border-box;
width: 100%;
&.active{
border: 1px solid #2bb673;
}
}
.menu_subItem{
height: 44px;
line-height: 44px;
text-align: center;
box-sizing: border-box;
&.active{
border: 1px solid #2bb673;
}
}
}
i{
color:#2bb673;
}
.submenu{
position: absolute;
width: 100%;
bottom: 45px;
display: flex;
flex-direction: column;
.subtitle{
background-color: #fff;
box-sizing: border-box;
}
.menu_bottom{
border-right: 1px solid #ebedee;
}
}
}
}
.mp-content{
flex: 1;
margin-left: 20px;
.right{
background-color: rgb(245, 246, 250);
padding: 20px;
.el-input,.el-select{
flex: 1;
}
.configure-page{
.delete-btn{
text-align: right;
margin-bottom: 15px;
}
.menu-name{
margin-bottom: 20px;
display: flex;
align-items: center;
}
.menu-content{
display: flex;
align-items: center;
}
.configur-content{
margin-top: 20px;
background-color: #fff;
border-radius: 5px;
.message-text{
padding: 20px 0;
display: flex;
align-items: center;
}
.message-upload{
margin: 20px auto;
background-color: #ffffff;
cursor: pointer;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.upload{
width: 178px;
height: 178px;
border: 1px dashed #d9d9d9;
border-radius: 6px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
i{
font-size: 28px;
color: #8c939d;
}
p{
margin-top: 10px;
text-align: center;
}
}
img{
max-width: 300px;
}
}
.applet{
margin-bottom: 20px;
display: flex;
align-items: center;
}
.tips{
color:#29b6f6;
margin-top: 10px;
}
}
}
&.save-wrapper{
padding-top: 20px;
text-align: center;
}
}
}
}
}
</style>