一.前言
继上一篇文章的首页搭建,今天来完成剩下的部分会议管理,投票管理及个人中心!!!
二.小程序自定义组件及其使用
官网:
开发者可以将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用;也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。自定义组件在使用时与基础组件非常相似。
2.1 自定义组件的使用
右击新建一个文件夹,创建一个component文件,只有Windows10会报,windows7不会,我们只要添加一个设置即可:
"ignoreDevUnusedFiles": false, "ignoreUploadUnusedFiles": false,
一个自定义组件由 json
wxml
wxss
js
4个文件组成。要编写一个自定义组件,首先需要在 json
文件中进行自定义组件声明(将 component
字段设为 true
可将这一组文件设为自定义组件):
{ "component": true }
在 wxss
文件中加入组件样式
<!-- 这是自定义组件的内部WXML结构 --> <view class="inner"> {{innerText}} </view> <slot></slot>
定义所需要的属性:
接着要在页面的 json
文件中进行引用组件。此时需要提供自定义组件文件路径:
{ "usingComponents": { "tabs": "/components/tabs/tabs" } }
效果:
三.使用自定义组件完成会议功能界面的实现
3.1 导航栏的实现
前端代码,写在了自定义组件中 tabs.wxml:
导航栏标题的判断选中的效果
<!-- 导航栏 --> <view class="tabs"> <view class="tabs_title"> <view wx:for="{{tabList}}" wx:key="id" class="title_item {{index==tabIndex?'item_active':''}}" bindtap="handleItemTap" data-index="{{index}}"> <view style="margin-bottom:5rpx">{{item}}</view> <view style="width:30px" class="{{index==tabIndex?'item_active1':''}}"></view> </view> </view> <view class="tabs_content"> <slot></slot> </view> </view>
导航栏的样式 tabs.wxss:
/* 导航栏样式 */ .tabs { position: fixed; top: 0; width: 100%; background-color: #fff; z-index: 99; border-bottom: 1px solid #efefef; padding-bottom: 20rpx; } .tabs_title { /* width: 400rpx; */ width: 90%; display: flex; font-size: 9pt; padding: 0 20rpx; } .title_item { color: #999; padding: 15rpx 0; display: flex; flex: 1; flex-flow: column nowrap; justify-content: center; align-items: center; } .item_active { /* color:#ED8137; */ color: #000000; font-size: 11pt; font-weight: 800; } .item_active1 { /* color:#ED8137; */ color: #000000; font-size: 11pt; font-weight: 800; border-bottom: 6rpx solid #333; border-radius: 2px; }
在js里面定义属性以及定义点击的事件 tabs.js:
/** * 组件的属性列表 */ properties: { // 这里定义属性,属性值可以在组件使用时指定 tabList:Object }, /** * 组件的方法列表 */ methods: { // 导航栏的方法 handleItemTap(e){ // 获取索引下标 const {index} = e.currentTarget.dataset; // 触发 父组件的事件 this.triggerEvent("tabsItemChange",{index}) this.setData({ tabIndex:index }) } }
接着在会议文件夹中的前端中写入 list.wxml:
<tabs tabList="{{tabs}}" bindtabsItemChange="tabsItemChange"> </tabs>
接着导入,在上篇文章就已经将所有的页面已经建好啦,现在只会写入代码即可在会议界面meeting的list.json导入:
"usingComponents": { "tabs": "/components/tabs/tabs" }
最后加入一些假数据 list.js:
/** * 页面的初始数据 */ data: { tabs:['已取消','进行中','已结束','全部会议'], }
效果:
3.2 会议界面内容的实现 metting
前端代码 list.wxml:
<!-- 设置与导航栏的间距 --> <view style="height: 40px;"></view> <block wx:for-items="{{lists}}" wx:for-item="item" wx:key="item.id"> <view class="list" data-id="{{item.id}}"> <view class="list-img"> <image class="video-img" mode="scaleToFill" src="{{item.image}}"></image> </view> <view class="list-detail"> <view class="list-title"><text>{{item.title}}</text></view> <view class="list-tag"> <view class="state">{{item.state}}</view> <view class="join"><text class="list-num">{{item.num}}</text>人报名</view> </view> <view class="list-info"><text>{{item.address}}</text>|<text>{{item.time}}</text></view> </view> </view> </block>
样式设置 list.wxss:
/* 会议样式 */ .mobi-title { font-size: 12pt; color: #777; line-height: 110%; font-weight: bold; width: 100%; padding: 15rpx; background-color: #f3f3f3; } .mobi-icon { padding: 0rpx 3rpx; border-radius: 3rpx; background-color: #ff7777; position: relative; margin-right: 10rpx; } /*list*/ .list { display: flex; flex-direction: row; width: 100%; padding: 0 20rpx 0 0; border-top: 1px solid #eeeeee; background-color: #fff; margin-bottom: 5rpx; /* border-radius: 20rpx; box-shadow: 0px 0px 10px 6px rgba(0,0,0,0.1); */ } .list-img { display: flex; margin: 10rpx 10rpx; width: 150rpx; height: 220rpx; justify-content: center; align-items: center; } .list-img .video-img { width: 120rpx; height: 120rpx; } .list-detail { margin: 10rpx 10rpx; display: flex; flex-direction: column; width: 600rpx; height: 220rpx; } .list-title text { font-size: 11pt; color: #333; font-weight: bold; } .list-detail .list-tag { display: flex; height: 70rpx; } .list-tag .state { font-size: 9pt; color: #81aaf7; width: 120rpx; border: 1px solid #93b9ff; border-radius: 2px; margin: 10rpx 0rpx; display: flex; justify-content: center; align-items: center; } .list-tag .join { font-size: 11pt; color: #bbb; margin-left: 20rpx; display: flex; justify-content: center; align-items: center; } .list-tag .list-num { font-size: 11pt; color: #ff6666; } .list-info { font-size: 9pt; color: #bbb; margin-top: 20rpx; } .bottom-line{ display: flex; height: 60rpx; justify-content: center; align-items: center; background-color: #f3f3f3; } .bottom-line text{ font-size: 9pt; color: #666; }
导入后台假数据:
根据导航栏的不同状态,各自写了一个数组数据 list.js:
/** * 页面的初始数据 */ data: { tabs:['已取消','进行中','已结束','全部会议'], lists: [ { 'id': '1', 'image': '/static/persons/1.jpg', 'title': '对话产品总监 | 深圳·北京PM大会 【深度对话小米/京东/等产品总监】', 'num':'304', 'state':'进行中', 'time': '10月09日 17:59', 'address': '深圳市·南山区' }, { 'id': '1', 'image': '/static/persons/2.jpg', 'title': 'AI WORLD 2016世界人工智能大会', 'num':'380', 'state':'进行中', 'time': '10月09日 17:39', 'address': '北京市·朝阳区' }, { 'id': '1', 'image': '/static/persons/3.jpg', 'title': 'H100太空商业大会', 'num':'500', 'state':'已取消', 'time': '10月09日 17:31', 'address': '大连市' }, { 'id': '1', 'image': '/static/persons/4.jpg', 'title': '报名年度盛事,大咖云集!2016凤凰国际论坛邀您“与世界对话”', 'num':'150', 'state':'进行中', 'time': '10月09日 17:21', 'address': '北京市·朝阳区' }, { 'id': '1', 'image': '/static/persons/5.jpg', 'title': '新质生活 · 品质时代 2016消费升级创新大会', 'num':'217', 'state':'已结束', 'time': '10月09日 16:59', 'address': '北京市·朝阳区' } ], lists1: [ { 'id': '1', 'image': '/static/persons/1.jpg', 'title': '对话产品总监 | 深圳·北京PM大会 【深度对话小米/京东/等产品总监】', 'num':'304', 'state':'进行中', 'time': '10月09日 17:59', 'address': '深圳市·南山区' }, { 'id': '1', 'image': '/static/persons/2.jpg', 'title': 'AI WORLD 2016世界人工智能大会', 'num':'380', 'state':'进行中', 'time': '10月09日 17:39', 'address': '北京市·朝阳区' }, { 'id': '1', 'image': '/static/persons/3.jpg', 'title': 'H100太空商业大会', 'num':'500', 'state':'进行中', 'time': '10月09日 17:31', 'address': '大连市' } ], lists2: [ { 'id': '1', 'image': '/static/persons/1.jpg', 'title': '对话产品总监 | 深圳·北京PM大会 【深度对话小米/京东/等产品总监】', 'num':'304', 'state':'已结束', 'time': '10月09日 17:59', 'address': '深圳市·南山区' }, { 'id': '1', 'image': '/static/persons/2.jpg', 'title': 'AI WORLD 2016世界人工智能大会', 'num':'380', 'state':'已结束', 'time': '10月09日 17:39', 'address': '北京市·朝阳区' } ], lists3: [ { 'id': '1', 'image': '/static/persons/1.jpg', 'title': '对话产品总监 | 深圳·北京PM大会 【深度对话小米/京东/等产品总监】', 'num':'304', 'state':'已取消', 'time': '10月09日 17:59', 'address': '深圳市·南山区' }, { 'id': '1', 'image': '/static/persons/2.jpg', 'title': 'AI WORLD 2016世界人工智能大会', 'num':'380', 'state':'已取消', 'time': '10月09日 17:39', 'address': '北京市·朝阳区' }, { 'id': '1', 'image': '/static/persons/3.jpg', 'title': 'H100太空商业大会', 'num':'500', 'state':'已取消', 'time': '10月09日 17:31', 'address': '大连市' }, { 'id': '1', 'image': '/static/persons/4.jpg', 'title': '报名年度盛事,大咖云集!2016凤凰国际论坛邀您“与世界对话”', 'num':'150', 'state':'已取消', 'time': '10月09日 17:21', 'address': '北京市·朝阳区' }, { 'id': '1', 'image': '/static/persons/5.jpg', 'title': '新质生活 · 品质时代 2016消费升级创新大会', 'num':'217', 'state':'已取消', 'time': '10月09日 16:59', 'address': '北京市·朝阳区' } ] },
改变导航栏页面的数据,根据会议状态做一个简单判断 list.js:
// 导航栏改变事件,改变值 tabsItemChange(e){ let tolists; if(e.detail.index==1){ tolists = this.data.lists1; }else if(e.detail.index==2){ tolists = this.data.lists2; }else if(e.detail.index==0){ tolists = this.data.lists3; }else{ tolists = this.data.lists; } this.setData({ lists: tolists }) },
效果:
四.投票管理界面 vote
前端代码 :
<!-- 导航栏 --> <tabs tabList="{{tabs}}" bindtabsItemChange="tabsItemChange"> </tabs> <!-- 设置与导航栏的间距 --> <view style="height: 40px;"></view> <block wx:for-items="{{vote1}}" wx:for-item="item" wx:key="item.id"> <view class="list" data-id="{{item.id}}"> <view class="list-detail"> <view class="list-title"><text>{{item.title}}</text><text class="state">{{item.state}}</text> </view> <view class="list-tag"> <view class="join"> 参与投票人数: <text class="list-num">{{item.sum}}</text></view> <view class="join">已经投票人数: <text class="list-num">{{item.num}}</text></view> </view> <view class="list-info">投票截止时间: <text>{{item.time}}</text></view> </view> </view> </block>
样式设计:
/* pages/vote/list/list.wxss */ /* 会议样式 */ /*list*/ .list { display: flex; flex-direction: row; width: 100%; padding: 0 20rpx 0 0; border-top: 1px solid #cac7c7; background-color: rgb(253, 244, 244); margin-bottom: 5rpx; } .list-title{ color: rgb(219, 85, 23); font-weight: 1000; font-size: smaller; display: flex; margin: 20rpx 10rpx; /* width: 300rpx; height: 120rpx; */ /* justify-content: center; */ align-items: center; } .join{ font-size: smaller; font-size: 11pt; color: rgb(85, 79, 79); margin-left: -300rpx; display: flex; justify-content: center; /* align-items: center; */ } .list-num{ font-weight: 680; color: red; } .state { font-size: 9pt; color: #81aaf7; width: 180rpx; border: 1px solid #93b9ff; border-radius: 2px; margin: 10rpx 0rpx; display: flex; justify-content: center; align-items: center; } .list-info { font-size: 9pt; color: rgb(17, 16, 16); margin-top: 20rpx; margin-left: 150px; }
引入自定义标签:
{ "usingComponents": { "tabs": "/components/tabs/tabs" } }
定义一些假数据:
/** * 页面的初始数据 */ data: { tabs:['待投票','历史投票','已投票'], vote1: [ { 'id': '1', 'title': '【关于罢免张三的董事长职位】', 'sum':'16人', 'state':'还未进行投票', 'time': '10月09日 17:59', 'num': '10人' }, { 'id': '1', 'title': '【世界人工智能大会是否上市】', 'sum':'20人', 'state':'还未进行投票', 'time': '10月09日 17:39', 'num': '7人' }, { 'id': '1', 'title': '【H100太空商业大会是否召开】', 'sum':'24人', 'state':'还未进行投票', 'time': '10月09日 17:31', 'num': '21人' }, { 'id': '1', 'title': '【关于李四的升职董事长的投票】', 'sum':'10人', 'state':'还未进行投票', 'time': '10月09日 17:21', 'num': '2人' } ], vote2: [ { 'id': '1', 'title': '【关于公司是否支持空降总监的会议】', 'sum':'23人', 'state':'同意', 'time': '10月09日 17:59', 'num': '23人' }, { 'id': '1', 'title': '【2016世界人工智能大会是否召开】', 'sum':'23人', 'state':'不同意', 'time': '10月09日 17:39', 'num': '23人' }, { 'id': '1', 'title': '【H100太空商业大会是否召开】', 'sum':'23人', 'state':'弃权', 'time': '10月09日 17:39', 'num': '23人' } ], vote3: [ { 'id': '1', 'title': '【关于王五的罢免的投票】', 'sum':'34人', 'state':'弃权', 'time': '10月09日 17:59', 'num': '31人' }, { 'id': '1', 'title': '【2016世界人工智能大会的召开】', 'sum':'34人', 'state':'同意', 'time': '10月09日 17:59', 'num': '31人' },{ 'id': '1', 'title': '【关于王五的罢免的投票】', 'sum':'34人', 'state':' 不同意', 'time': '10月09日 17:59', 'num': '31人' }, { 'id': '1', 'title': '【2016世界人工智能大会的召开】', 'sum':'34人', 'state':'同意', 'time': '10月09日 17:59', 'num': '31人' },{ 'id': '1', 'title': '【关于王五的罢免的投票】', 'sum':'34人', 'state':'同意', 'time': '10月09日 17:59', 'num': '31人' }, { 'id': '1', 'title': '【世界人工智能大会的召开】', 'sum':'34人', 'state':'弃权', 'time': '10月09日 17:59', 'num': '31人' } ] },
导航栏改变事件:
// 导航栏改变事件,改变值 tabsItemChange(e){ let tolists; if(e.detail.index==0){ tolists = this.data.vote1; }else if(e.detail.index==1){ tolists = this.data.vote2; }else if(e.detail.index==2){ tolists = this.data.vote3; } this.setData({ vote1: tolists }) },
效果:
五.个人中心
前端代码 ucenter:
<view class="user"> <image class="user-img" src="/static/persons/jennie1.jpg"></image> <view class="user-name">潇洒姿</view> <view class="user-oper">修改</view> </view> <view class="info"> <view class="item1"> <image class="item-icon" src="/static/tabBar/sdk.png"></image> <view class="item-title">我主持的会议</view> <view class="item-num">10</view> <view class="item-oper">></view> </view> <view class="item2"> <image class="item-icon" src="/static/tabBar/sdk.png"></image> <view class="item-title">我参与的会议</view> <view class="item-num">7</view> <view class="item-oper">></view> </view> </view> <view class="info"> <view class="item1"> <image class="item-icon" src="/static/tabBar/sdk.png"></image> <view class="item-title">我发布的投票</view> <view class="item-num">6</view> <view class="item-oper">></view> </view> <view class="item2"> <image class="item-icon" src="/static/tabBar/sdk.png"></image> <view class="item-title">我参与的投票</view> <view class="item-num">8</view> <view class="item-oper">></view> </view> </view> <view class="info"> <view class="item1"> <image class="item-icon" src="/static/tabBar/sdk.png"></image> <view class="item-title">消息</view> <view class="item-num">1</view> <view class="item-oper">></view> </view> <view class="item2"> <image class="item-icon" src="/static/tabBar/sdk.png"></image> <view class="item-title">设置</view> <view class="item-num">10</view> <view class="item-oper">></view> </view> </view>
样式设计:
/* pages/ucenter/index/index.wxss */ .user{ display: flex; align-items: center; border-bottom: 8px solid rgb(236, 216, 219); } .user-img{ width: 75px; height: 75px; margin: 10px; } .user-name{ font-weight: 900; margin: 0 200rpx 0 50rpx; margin-left: 10px; color: palevioletred; } .user-oper{ color: grey; width: 40px; margin-left: 10px; } .item-icon{ width: 34px; height: 34px; } .item1,.item2{ padding: 5px; display: flex; align-items: center; } .item-title{ width: 550rpx; } .item-num{ color:rgb(231, 188, 217); } .item1{ border-bottom: 1px solid rgb(236, 216, 219); } .item2{ border-bottom: 5px solid rgb(236, 216, 219); } .item-oper{ font-weight: 800; margin-left: 10px; width: 20px; color:rgb(100, 76, 84) }
效果: