做者:李大前端
.icon{ width:78rpx; height:78rpx; border-radius: 100%; margin-left:26rpx; margin-top:40rpx; }
<view style="background:{{'#FAFAFA'}}"> <view class="dicussion_title" id="title_bar">這裏是 {{club_name}} 的討論區</view> <view class='swiper_container' style='height: {{swiperHeight + "px"}}'> <swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" circular="{{circular}}" vertical="{{vertical}}" interval="{{interval}}" duration="{{duration}}" style='width:100%;height:100%' current="{{question_id}}" next-margin='28rpx' previous-margin='28rpx' bindchange='onSlideChanged' > <block wx:for="{{qa_list}}" wx:for-index="q_index"> <swiper-item> <scroll-view scroll-y style='height: {{swiperHeight}}px' bindscroll="scroll" scroll-top='{{scrollTop}}' scroll-with-animation='{{true}}' scroll-into-view='{{scroll_into_view}}'> <view class="qa_list" id='qa_list_border'> <view class="qa_container"> <view> <image src="{{qa_list[q_index].q_raiser_icon}}" class='icon'></image> </view> <view class="vertical_flex"> <view class="user_name_text">{{qa_list[q_index].q_raiser_name}}</view> <view class="qa_text qa_text_base">{{qa_list[q_index].ques_text}}</view> </view> </view> <view class="ques_time"> <view> <image src="/images/icons/qa/question.png" class='q_icon'></image> </view> <view class="ques_time_text">提問於 {{qa_list[q_index].ques_time}}</view> </view> <view class="div_line_full"></view> <view wx:if="{{qa_list[q_index].ans_list.length==0}}"> <view class="no_ans_text">暫時無人理會,你能幫幫TA嗎?</view> </view> <view wx:for="{{qa_list[q_index].ans_list}}" wx:for-index="i" wx:for-item="ans"> <view class="qa_container" id="qa_mark"> <view> <image src="{{ans.a_raiser_icon}}" class='icon'></image> </view> <view class="vertical_flex"> <view class="user"> <view class="user_name_text">{{ans.a_raiser_name}}</view> <view style="margin-top:36rpx;margin-left:12rpx" wx:for="{{ans.special_tag}}" wx:for-item="tag"> <van-tag wx:if="{{tag == '置頂'}}" color="#F44336" size="club_tag"> <text class="tag-font">置頂</text> </van-tag> <van-tag wx:if="{{tag != '置頂'}}" color="#42A5F5" size="club_tag"> <text class="tag-font">{{tag}}</text> </van-tag> </view> </view> <view class="ans_time_text qa_text_base">{{ans.ans_time}}</view> <view class="qa_text qa_text_base">{{ans.ans_text}}</view> </view> </view> <view class="like" data-q_index='{{q_index}}' data-a_index='{{i}}' bindtap='likeBtnClicked'> <view> <image src="/images/icons/qa/liked.png" class='like_icon' wx:if="{{ans.liked}}"></image> <image src="/images/icons/qa/like.png" class='like_icon' wx:if="{{!ans.liked}}"></image> </view> <view class='like_cnt'>{{ans.like}}</view> </view> <view class=" div_line " wx:if="{{i != qa_list[q_index].ans_list.length - 1}}"></view> </view> </view> <view class="bottom_margin_large"></view> </scroll-view> </swiper-item> </block> </swiper> </view> <view class="commenter" id='comment_bar' style='bottom:{{commenter_position}}px'> <view class="input_place"> <input placeholder="快來討論這個問題吧,4~40字" value="{{ans_input}}" style='width:466rpx;margin-top:4rpx;' cursor-spacing="32rpx" bindinput='inputTyping' adjust-position="{{false}}" bindfocus="focused" bindblur="blurred"></input> </view> <view class="submit_btn" bindtap='submitAnswer' data-question_id='{{q_index}}'>發送</view> </view> </view>
/*commenter*/ .commenter{ position: fixed; display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: center; align-items: center; margin-right: 0rpx; margin-top:0rpx; margin-bottom:0rpx; background-color:#FFFFFF; border-top-color: #BBBBBB; border-top-width: 2rpx; border-top-style: solid; } .input_place{ margin-left: 16rpx; width:530rpx; height:64rpx; border-radius: 64rpx; font-size:28rpx; display: flex; flex-direction: row; flex-wrap:wrap; justify-content: flex-start; align-items: center; background-color: #EEEEEE; color: #888484; padding-left:32rpx; border-style:solid; border-width:16rpx; border-color:#FFFFFF; } .submit_btn{ margin-left: 4rpx; margin-right: 24rpx; width: 120rpx; height: 64rpx; display: flex; flex-direction: row; flex-wrap:wrap; justify-content: center; align-items: center; background-color: #F44336; color: #FFFFFF; font-size: 28rpx; border-radius: 32rpx; } /*commenter end*/ .swiper_container{ overflow: hidden; position: fixed; width:100%; background-color: #FAFAFA; } .icon{ width:78rpx; height:78rpx; border-radius: 100%; margin-left:26rpx; margin-top:40rpx; } .vertical_flex{ display: flex; flex-direction: column; justify-content: flex-start; flex-wrap: nowrap; } .user_name_text{ font-size:30rpx; font-weight: 500; margin-top:45rpx; margin-left:14rpx; } .qa_time{ margin-left:18rpx; color:#AAAAAA; font-size:18rpx; } .qa_list{ background: #fff; margin-top:10rpx; margin-left:12rpx; margin-right:12rpx; margin-bottom:20rpx; display: flex; flex-direction: column; justify-content: center; border-radius: 24rpx; } .border_backup{ border-radius: 16rpx;border-color: #BBBBBB;border-width: 2rpx;border-style: solid; } .first_qa_top_margin{ margin-top:20rpx; } .regular_top_margin{ margin-top:32rpx; } .dicussion_title{ display: flex; justify-content: center; font-size:26rpx; color:#939090; padding-top:26rpx; font-weight: 400; } .qa_container{ display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: flex-start; align-items: flex-start; } .qa_text_base{ margin-left : 18rpx; margin-right: 36rpx; } .qa_text{ margin-top:14rpx; font-size: 26rpx; font-weight: 500; line-height: 36rpx; } .ques_time{ display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: flex-end; align-items: center; margin-right: 45rpx; margin-top:28rpx; margin-bottom:8rpx; } .q_icon{ margin-top:8rpx; width: 40rpx; height: 40rpx; border-radius: 0%; } .ques_time_text{ margin-left:8rpx; color:#888484; font-size:22rpx; } .ans_time_text{ color:#888484; font-size:18rpx; } .zero_ans_text{ margin-top:14rpx; font-size: 24rpx; line-height: 45rpx; color: #BBBBBB; } .div_line_full{ height: 2rpx; width: 100%; background-color:#EEEEEE; } .div_line{ height: 2rpx; width: 90%; background-color:#EEEEEE; margin-left: 5%; } .like{ display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: flex-end; align-items: center; margin-right:40rpx; margin-bottom: 14rpx; } .like_cnt{ font-size: 30rpx; color: #101010; margin-left:6rpx; } .like_icon{ margin-top:4rpx; width: 36rpx; height: 36rpx; border-radius: 0%; } .user{ display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: flex-start; align-items: center; } .tag-font{ font-size: 24rpx; color: #FFFFFF; } .no_ans_text{ display: flex; justify-content: center; font-size:24rpx; color:#BBBBBB; margin-top:32rpx; font-weight: 400; margin-bottom: 24rpx; } ::-webkit-scrollbar { width: 0; height: 0; color: transparent; } .bottom_margin_large{ background-color: #FAFAFA; width : 100%; height : 80rpx; }
<scroll-view scroll-y style='height: {{swiperHeight}}px' bindscroll="scroll" scroll-top='{{scrollTop}}' scroll-with-animation='{{true}}' scroll-into-view='{{scroll_into_view}}'> </scroll-view>
wx.getSystemInfo({ success: function (res) { wx.createSelectorQuery().select('#title_bar').boundingClientRect(function (rect) { var title_bar_bottom = rect.bottom that.setData({ scrollHeight: res.windowHeight - title_bar_bottom, swiperHeight: res.windowHeight - title_bar_bottom - comment_bar_height - 10 }) }).exec(); } });
其餘交互邏輯的實現也很相似,都是經過js和xml數據動態綁定設置實現web
開發中筆者參考的組件庫有WeUI,Vant,WuxUI,WussUI。每次須要實現新的交互邏輯時都先翻閱一下組件庫尋找能夠套用的交互模式,或者抽取多個組件的部分進行嵌套使用改造,最終拼湊實現出一個完整的功能。json
<wux-popup position="top" visible="{{ pop_up_tab_visible }}" bind:close="pop_up_tab_set_invisible"> <view class="weui-search-bar "> <view class="weui-search-bar__form"> <view class="weui-search-bar__box"> <icon class="weui-icon-search_in-box" type="search" size="14"></icon> <input type="text" class="weui-search-bar__input" placeholder="輸入用戶id搜索" value="{{inputVal}}" focus="{{inputShowed}}" bindinput="inputTyping" /> <view class="weui-icon-clear" wx:if="{{inputVal.length > 0}}" bindtap="clearInput"> <icon type="clear" size="14"></icon> </view> </view> <label class="weui-search-bar__label" hidden="{{inputShowed}}" bindtap="showInput"> <icon class="weui-icon-search" type="search" size="14"></icon> <view class="weui-search-bar__text">輸入用戶id搜索</view> </label> </view> <view class="weui-search-bar__cancel-btn" hidden="{{!inputShowed}}" bindtap="hideInput" style='font-size:30rpx;padding-top:5rpx'>取消</view> </view> <view class="weui-cells searchbar-result" style='border-radius:16rpx' wx:if="{{inputVal.length > 0}}"> <view class="weui-cells_after-title"> <block wx:for="{{search_result_list}}" wx:for-index="key"> <view class="weui-cells {{i==0? 'weui-cells_after-title' : ''}}" style='margin-top:0rpx;margin-bottom:0rpx;'> <view class="weui-cell" style='background-color:#f6f6f6' > <view class="weui-cell__hd" style="position: relative;margin-right: 20rpx;"> <image src="{{item.usr_icon}}" style="width: 60rpx; height: 60rpx; display: block; border-radius:50%;" bindtap='jumpToUserDetailFromSearchResult' data-usr_index="{{key}}" /> </view> <view class="vertical_split"> <view class="weui-cell__bd" bindtap='jumpToUserDetailFromSearchResult' data-usr_index="{{key}}"> <view class="username" style="font-size: 26rpx;">{{item.name}}</view> <view style="font-size: 18rpx;color: #888888;">學號:{{item.student_id}}</view> </view> <view class="btn remove_btn search_result_btn" data-usr_index="{{key}}" bindtap='added'>添加</view> </view> </view> </view> </block> <view class="bottom_margin" style='background-color:#f6f6f6;height:16rpx' ></view> </view> </view> </wux-popup> </view>
//club_main.js jumpToClubDetailDescription: function (e) { var club_id = e.currentTarget.dataset.club_id wx.navigateTo({ url: '/pages/club_detail/club_detail?club_id=' + club_id }) }, //club_detail.js onLoad: function(options) { let that = this var club_id = options.club_id that.setData({ club_id:club_id }) that.request_club_detail(that, club_id) //省略許多其餘與此處展現無關的初始化邏輯 }
request_followed_club_list: function (that) { util.$get('/clubs/followed') .then((res) => { var followed_club_list = res.data.data.clubs_list for (var i = 0; i < followed_club_list.length; i++) { followed_club_list[i].icon_url = baseImageServerUrl + followed_club_list[i].icon_url } that.setData({ followed_club_list: followed_club_list }) }) },
function baseRequest(params, method) { let promise = new Promise((resolve, reject) => { let url = params.url let data = params.data wx.request({ url: url.indexOf('http') !== -1 ? url : baseUrl + url, data: data, method: method, header: { 'content-type': 'application/json', 'cookie': wx.getStorageSync('cookie') }, success(res) { if (res.data.success) { resolve(res) } else if (res.data.code === status.STATUS_CODE.ACCESS_NOT_LOGIN) { wx.redirectTo({ url: '/pages/login/login?not_first=true', }) } else { resolve(res) } }, fail(res) { reject(res) } }) }) return promise } function $get(url, data = '') { let params = { url: url, data: data } return baseRequest(params, 'GET') } function $post(url, data) { let params = { url: url, data: data } return baseRequest(params, 'POST') } function $put(url, data) { let params = { url: url, data: data } return baseRequest(params, 'PUT') } function $delete(url, data = '') { let params = { url: url, data: data } return baseRequest(params, 'DELETE') } module.exports = { formatTime: formatTime, $get: $get, $post: $post, $put: $put, $delete: $delete }