程序的经典的底部菜单,在json配置文件设置,最多不能超过五个,小程序的底部菜单有时候新增的页面没有,这种情况需要切一个底部。
那么接下来就看看是如何实现的吧。
第一步,寻找合适的图标准备好合适的图标,每组图标为2张,一张是默认状态,一张是选中状态
http://www.iconfont.cn/home/index?spm=a313x.7781069.1998910419.2
第二步,将图片放在自己程序的路径下大家可以建立一个images目录
第三步,添加代码小程序的底部菜单在官方文档是一个app.json中的一个全局配置属性
大家可以直接将下面的代码放到app.json中,注意要在外面还有一个整体的{}
"tabBar": {
"color": "#a9b7b7",
"selectedColor": "#11cd6e",
"borderStyle": "white",
"list": [
{
"selectedIconPath": "images/menuicon/index.png",
"iconPath": "images/menuicon/index1.png",
"pagePath": "pages/index/index",
"text": "首页"
},
{
"selectedIconPath": "images/menuicon/list.png",
"iconPath": "images/menuicon/list1.png",
"pagePath": "pages/list/list",
"text": "列表"
},
{
"selectedIconPath": "images/menuicon/user.png",
"iconPath": "images/menuicon/user1.png",
"pagePath": "pages/user/user",
"text": "个人中心"
}
]
}
详细的介绍可以看这个官方文档:
https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#全局配置
篇文章我们一起来实现一个vue的下拉菜单组件。
像这种基本UI组件,网上已经有很多了,为什么要自己实现呢?其实并不是有意重复造轮子,而是想通过这个过程回顾一下vue组件开发的一些细节和注意事项。
为什么选择下拉菜单组件?
因为:麻雀虽小五脏俱全,这个小小的组件涉及到了不少vue组件开发的知识点。
好了,那就开始吧!
首先创建一个vue-cli的项目,笔者用的是vue-cli3,创建过程略,然后创建一个vue组件:DropDownList.vue
在编写模板之前,我们来分析一下这个组件的视图结构和功能。
下拉菜单组件应该由两部分组成:
它的主要功能包括:
<template>
<div class="zq-drop-list" @mouseover="onDplOver($event)" @mouseout="onDplOut($event)">
<span>选中项的文本<i></i></span>
<ul>
<li>北京</li>
<li>上海</li>
<li>广州</li>
</ul>
</div>
</template>
选中项文本右侧的i标签,用来实现下拉菜单的三角形图标,在下文的css中我们用背景图来实现。
我们给根元素div已经添加了鼠标经过和滑出的回调函数,具体实现见下文。
接下来我们为这个下拉菜单编写样式,在模板下方添加style标签,为了防止和其他组件的样式发生冲突,笔者建议大家在开发组件时,都给style加上scoped属性。另外,笔者在这里用到了scss,具体代码如下:
<style scoped lang="scss">
.zq-drop-list{
display: inline-block;
min-width: 100px;
position: relative;
span{
display: block;
height: 30px;
line-height: 30px;
background: #f1f1f1;
font-size: 14px;
text-align: center;
color: #333333;
border-radius: 4px;
i{
background: url(https://www.easyicon.net/api/resizeApi.php?id=1189852&size=16) no-repeat center center;
margin-left: 6px;
display: inline-block;
}
}
ul{
position: absolute;
top: 30px;
left: 0;
width: 100%;
margin: 0;
padding: 0;
border: solid 1px #f1f1f1;
border-radius: 4px;
overflow: hidden;
li{
list-style: none;
height: 30px;
line-height: 30px;
font-size: 14px;
border-bottom: solid 1px #f1f1f1;
background: #ffffff;
}
li:last-child{
border-bottom: none;
}
li:hover{
background: #f6f6f6;
}
}
}
</style>
关于样式,这里就不详细展开了,只说其中几个需要注意的点:
现在这个组件大概长这个样子:
1.png
我们继续为这个组件定义属性,很显然,待选菜单应该作为属性传进来,一定不能是内部写死的,属性定义如下:
<script>
export default {
name: "DropDownList",
props:{
dataList:{
type:Array,
default(){
return [
{name: "选项一"},
{name: "选项二"}
]
}
},
labelProperty:{
type:String,
default(){ return "name" }
}
},
data(){
return {
activeIndex:0
}
},
}
其中dataList就是待选菜单的数据源属性,这里我们给这个属性定义了默认值,这也是笔者建议大家养成的一个习惯,作为一个组件,最好有默认值,因为当别人使用你的组件时,可以先不设置相关属性,就能看到一个成品的效果,也能快速查看你这个组件所需属性的数据细节。
另外一个属性是labelProperty,这个属性的作用是什么?我们实际项目中的数据源,并不一定都含有name这个字段,因此就可能导致下拉菜单无法渲染数据的文本,于是我们定义了这个属性用来指定实际数据源渲染文本的字段,这个字段必须是字符串。这个属性的默认值是name,因为它需要和默认数据源保持一致。相信你还看到了一个组件内部数据,activeIndex,这个是用来表示当前选中项的索引的,我们后面会用到。
现在我们就可以在其他地方引入并使用这个组件了,虽然它还没有完成,但我们不妨先让它显示在界面上吧:
<template>
<div class="home">
<DropList :dataList="dplist" labelProperty="city" @change="onDpChange($event)"></DropList>
<p>其他文本内容</p>
</div>
</template>
<script>
import DropList from '@/components/DropDownList.vue'
//其他代码略
</script>
这个页面引入并使用了我们的DropDownList组件,:dataList="dplist" 绑定了当前页面的dplist数组到组件的dataList属性上,这个数组中的对象有一个city字段,我们希望此字段显示在下拉菜单上,因此我们设置组件的labelProperty为city,我们还给这个组件注册了change事件,这个组件内部需要派发这个事件,见下文。
现在我们回到组件的模板部分,发现它都还是静态内容,我们把这些静态内容修改为通过属性渲染。
<template>
<div class="zq-drop-list" @mouseover="onDplOver($event)" @mouseout="onDplOut($event)">
<span>{{dplLable}}<i></i></span>
<ul>
<li v-for="(item, index) in dataList" :key="index" @click="onLiClick(index, $event)">{{item[labelProperty]}}</li>
</ul>
</div>
</template>
其中待选菜单li的文本是 item[labelProperty] 这样就能正确的显示开发者指定的字段了。
我们看看选中项的文本表达式:dplLabel,我们并没有定义这个属性,也没有定义这个内部数据,它是哪儿来的?选中项的文本应该是 dataList[activeIndex][labelProperty] (这个很好理解吧,有问题请留言),但这个表达式太长了,写在模板里不利于维护,我们就把它写到计算属性里吧。
computed:{
dplLable(){
return this.dataList[this.activeIndex][this.labelProperty]
}
}
于是才有了上面的dplLabel,计算属性真的很好用呢。
现在下拉菜单的视图和数据关联部分我们已经写完了,接下来我们要实现它的功能。
第一步是先让待选菜单默认隐藏起来,这里我们为什么不直接用css的display:none呢,然后鼠标经过的时候display:block不就可以了吗?因为这样的话,我们无法实现点击待选菜单条目的时候让它隐藏,体验不好。我们用js来控制,但vue对直接访问dom元素支持的并不好,我们要想在组件初始化的时候访问dom元素,有一个最方便的做法,那就是:自定义指令。
我们为下拉菜单组件添加局部自定义指令,代码如下:
directives:{
dpl:{
bind(el){
el.style.display="none";
}
}
},
这个dpl就是自定义指令啦,请忽略我笨拙的命名哈!然后我们在自定义指令的钩子函数bind方法中,访问el元素,控制它的style属性display:none; 最后,把这个自定义指令加到模板里面的ul标签上。别忘了要加v-,现在看看效果,待选菜单已经隐藏了。
<ul v-dpl>
我们利用自定义指令钩子函数访问dom元素,实现了对dom的控制,这一点非常实用!
让我们继续实现最开始为下拉菜单定义的鼠标经过和鼠标滑出的监听,实现待选菜单的显示与隐藏。
onDplOver(event){
let ul=event.currentTarget.childNodes[1];
ul.style.display="block";
},
onDplOut(event){
let ul=event.currentTarget.childNodes[1];
ul.style.display="none";
},
我们在鼠标事件中,访问event的currentTarget对象,为什么不是target?因为下拉菜单的子元素也会触发这个事件,如果访问target,可能不会是我们预期的顶层元素。
最后一步,我们实现待选菜单条目的点击事件,点击后,待选菜单隐藏,修改内部状态,派发change事件。
onLiClick(index){
let path=event.path || (event.composedPath && event.composedPath()) //兼容火狐和safari
path[1].style.display="none";
this.activeIndex=index;
this.$emit("change", {
index:index,
value:this.dataList[index]
})
}
这里有一个细节需要注意,我们要通过li元素找到外层ul元素,但path不支持火狐和safari,好在这两个浏览器支持composedPath,因此才有了第一行代码的兼容写法。然后通过修改内部数据activeIndex实现选中项文本的更新,最后调用emit方法向父元素派发change事件,别忘了把事件对象封装好传出去。
完整的代码如下:
<template>
<div class="zq-drop-list" @mouseover="onDplOver($event)" @mouseout="onDplOut($event)">
<span>{{dplLable}}<i></i></span>
<ul v-dpl>
<li v-for="(item, index) in dataList" :key="index" @click="onLiClick(index, $event)">{{item[labelProperty]}}</li>
</ul>
</div>
</template>
<script>
export default {
name: "DropDownList",
data(){
return {
activeIndex:0
}
},
props:{
dataList:{
type:Array,
default(){
return [
{name: "选项一"},
{name: "选项二"}
]
}
},
labelProperty:{
type:String,
default(){ return "name" }
}
},
directives:{
dpl:{
bind(el){
el.style.display="none";
}
}
},
methods:{
onDplOver(event){
let ul=event.currentTarget.childNodes[1];
ul.style.display="block";
},
onDplOut(event){
let ul=event.currentTarget.childNodes[1];
ul.style.display="none";
},
onLiClick(index){
let path=event.path || (event.composedPath && event.composedPath()) //兼容火狐和safari
path[1].style.display="none";
this.activeIndex=index;
this.$emit("change", {
index:index,
value:this.dataList[index]
})
}
},
computed:{
dplLable(){
return this.dataList[this.activeIndex][this.labelProperty]
}
}
}
</script>
<style scoped lang="scss">
.zq-drop-list{
display: inline-block;
min-width: 100px;
position: relative;
span{
display: block;
height: 30px;
line-height: 30px;
background: #f1f1f1;
font-size: 14px;
text-align: center;
color: #333333;
border-radius: 4px;
i{
background: url(https://www.easyicon.net/api/resizeApi.php?id=1189852&size=16) no-repeat center center;
margin-left: 6px;
display: inline-block;
}
}
ul{
position: absolute;
top: 30px;
left: 0;
width: 100%;
margin: 0;
padding: 0;
border: solid 1px #f1f1f1;
border-radius: 4px;
overflow: hidden;
li{
list-style: none;
height: 30px;
line-height: 30px;
font-size: 14px;
border-bottom: solid 1px #f1f1f1;
background: #ffffff;
}
li:last-child{
border-bottom: none;
}
li:hover{
background: #f6f6f6;
}
}
}
</style>
以上为大家展示了vue如何实现一个下拉菜单组件,虽然比较简单,但也基本涉及到了组件开发常用的一些特性。
欢迎大家在评论区留言自己想了解的前端话题,我会继续推出更多精彩的文章!
作者:_乾_
链接:https://www.jianshu.com/p/bae49ca02795
窗苦读十余载
聊大终于等到你!
19级的小萌新注意啦!
您的录取通知书正迫不及待
翻山越海向您飞奔而去!
想必大家都在好奇
今年的录取通知书到底什么样子?
跟随大聊一起来直击现场
今天,录取通知书寄出
从今天开始,将有约8000份2019级新生录取通知书从聊城大学寄出,寄往27个省、自治区、直辖市。第一批寄出的1738份录取通知书将寄往十个省、自治区、直辖市,其他录取通知书随后也将陆续发出。
接下来
大聊独家最全面揭秘录取通知书
快来一览为快!
★【NO.1】
EMS快递封面
聊城大学2019年录取通知书的“外套”如上图所示,请收到录取通知书的新生仔细对照,以防上当受骗。
★ 【NO.2】
录取通知书
2019聊城大学录取通知书,设计上,首先在色彩上,正面、背面采用了大面积的古铜色为底色,内面采用了浅灰米色为底,两者叠加,凸显了浓浓的书卷气质。结构上,正面做了弧度裁切,像一个大箭头一样指向了有意识露出了内页下方“学在聊大,奠基人生”八个字,突出了聊大对莘莘学子的热切希望,也为即将成为聊大人的新生指明了方向!
正面聊大校名及录取通知书这几个字都采用了烫金印刷工艺,体现了通知书的珍贵感,聊大大门,作为聊大的一道风景,像一座桥梁一样贯通了通知书的左右两段,极具形式感和识别性,28根秩序排列的立柱,也彰显了聊大的历史厚重及大气感,它又像一个彩虹链接起了聊大另一个标志性建筑——西校图书馆,进一步,彰显了聊大的文化。
本通知书设计简洁大气,在继承传统文化的基础上,又有足够的现代人文气质彰显。有秩序的水纹设计植入,也充分体现了聊大的地域特色,暗喻,聊大这所坐落于中国著名的历史文化名城,素有“江北水城,运河古都”之称的聊城市,必将乘风破浪,再创辉煌。
★【NO.3】
《聊城大学2019新生入学手册》
《聊城大学2019新生入学手册》(包括:入学须知、收费标准、银行卡使用说明、易班迎新须知、报到安全指南、应征入伍宣传单、相关部门通讯方式等)。
★【NO.4】
高校本专科学生资助政策简介
我校历来十分重视家庭经济困难学生资助工作,建立了以生源地助学贷款为主要途径,包括奖助学金、勤工助学、学费减免、特殊困难补助、绿色通道在内的学生奖励机制和助学保障体系。
家庭经济困难的学生,请在入学前到当地政府或民政部门开具家庭困难证明材料,内容应包括家庭年收入状况、家庭人口数、家庭经济来源和家庭经济困难原因等,困难证明必须加盖村委会(或居委会、企事业单位)、乡(镇)政府或街办两级行政公章方能生效。
★【NO.5】
银行卡、行李标签
学校随录取通知书邮寄了两张未激活的银行卡,供新生缴费使用。一张农行卡、一张建行卡,选其一激活即可,其他详见新生入学手册银行卡使用说明。行李标签用于新生入学个人行李标记,以免发生遗失等情况。
★【NO.6】
录取通知书全家福
公费师范生的新生小可爱们录取通知书内还包括四份山东省师范生公费教育协议书哦~
工作人员正以最快的速度和最严谨的态度
将录取通知书分批寄出
相信不久以后
你便会收获到独一无二的喜悦!
大聊赶在萌新之前
拿着录取通知书
到学校标志地点
为您实景打卡~
西校区南大门
东校区逸夫图书馆
西校区羡林湖
桃李桥(彩虹桥)
餐厅
西校区紫藤宿舍
东校区日晷广场
西校区望月桥
新生录取通知书查询指南
@全体2019级新生:我校高考录取通知书将于7月21日开始封装,7月21日陆续发出,请同学们耐心等待!注意!所有方法只有在学校邮寄后才生效!!!另外,为防止新生信息泄露,我校并未给任何平台提供新生准考证号,故凡是用准考证号(考生号)查询的途径均不可查!请使用快递单号追踪查询!
录取通知书邮寄信息查询途径
1.进入聊城大学2019年普通高考录取结果查询地址:
https://admission-art.lcu.edu.cn/query2019/index.jsp
录取页面有EMS邮件号(快递单号)。查询到邮件号(快递单号)后,复制,到EMS官网上或EMS微信公众号输入邮件号(快递单号),就可以追踪到邮递信息啦。EMS邮件查询地址:
http://www.ems.com.cn/index.html
2.关注聊城大学微信号
点击底部菜单栏录取通知书
按步骤操作查询即可
大聊祝福即将进入大学的你们
珍惜当下,勇敢追梦
不忘初心,砥砺前行
在聊大,拥抱更加精彩的未来!
收到录取通知书的你
记得要和大聊分享你的喜悦哦~
参与“我与录取通知书合张影”活动
第一时间与自己的录取通知书合影
发送到大聊邮箱203521473@qq.com
大聊整理后会同大家分享你的喜悦哦~
资料来源 | 聊城大学招生处
编辑|王昱宸 李瑞峰 于春云
图片 | 姬嗣钰 梁安诺 朱绍辉 魏超
视频 | 薛杰 王亚茹 尹淑轩
责编|王黎
编审|王秀清
投稿邮箱|203521473@qq.com
*请认真填写需求信息,我们会在24小时内与您取得联系。