Commit 2fc5e4a0 by ArronYR

first commit

parents
//app.js
import req from './utils/Request.js'
App({
onLaunch: function(options) {
this.options = options
// 请求配置
this.configReq()
// 用户登录
this.checkUserLogin()
},
onShow: function(options) {
wx.showShareMenu({
withShareTicket: true,
success: function(ret) {
console.log('shareTickets:', ret)
}
})
},
configReq() {
//配置baseUrl和拦截器,baseUrl例如 /api
req.baseUrl(this.globalData.apiPath).interceptor(res => {
console.log(res)
})
},
/**
* 用户资料授权
*/
checkUserLogin: function(callback) {
let _app = this
if (_app.globalData.userInfo == null) {
_app.requestWxLogin(function(res) {
typeof callback == "function" && callback()
})
} else {
console.log("用户已登录", _app.globalData.userInfo)
typeof callback == "function" && callback()
}
},
/**
* 请求微信授权登陆
*/
requestWxLogin: function(callback) {
let that = this
wx.login({
success: function(res) {
if (res.code) {
//发起网络请求
let wxcode = res.code
wx.getUserInfo({
withCredentials: true,
lang: 'zh_CN',
success: function(data) {
console.info("1成功获取用户返回数据", wxcode, data);
that.requestServerLogin(wxcode, data, callback)
},
fail: function() {
console.info("1授权失败返回数据");
// 显示提示弹窗
wx.showModal({
title: '授权失败',
content: '你的微信授权未开启,将无法使用小程序!',
success: function(res) {
if (res.confirm) {
wx.openSetting({
success: function(data) {
if (data && data.authSetting["scope.userInfo"] == true) {
wx.getUserInfo({
withCredentials: true,
success: function(data) {
console.info("3成功获取用户返回数据");
that.requestServerLogin(wxcode, data, callback)
},
fail: function() {
console.info("3授权失败返回数据");
}
});
}
},
fail: function() {
console.info("设置失败返回数据");
}
});
} else if (res.cancel) {
console.log('用户坚持取消授权')
}
}
});
}
});
}
},
fail: function() {
console.info("登录失败返回数据");
}
});
},
/**
* 请求获取群id openGid 所需参数
*/
requestShareTicket: function(callback) {
let that = this
wx.login({
success: function(res) {
let wxcode = res.code
wx.getShareInfo({
shareTicket: that.options.shareTicket,
success: function(res) {
that.requestServerWithShareData(wxcode, {
encryptedData: res.encryptedData,
iv: res.iv
}, callback)
}
})
}
})
},
/**
* 请求服务器登陆
*/
requestServerLogin: function(wxcode, data, callback) {
let _app = this
req.post('user/login', {
code: wxcode,
signature: data.signature,
rawData: data.rawData,
encryptedData: data.encryptedData,
iv: data.iv,
scene: _app.options.query && _app.options.query.scene ? decodeURIComponent(_app.options.query.scene) : ''
}).then(res => res.data).then(res => {
if (!res.code) {
_app.globalData.userInfo = res.user
_app.globalData.token = res.token
typeof callback == "function" && callback(res.user)
}
if (_app.options.scene == 1044 && _app.options.shareTicket) {
_app.requestShareTicket(function(ret) {
console.log("Request Share Ticket", ret)
})
}
})
},
/**
* 请求服务器解析数据获取 openGid
*/
requestServerWithShareData(wxcode, data, callback) {
let _app = this
req.post('user/get_groupid', {
token: _app.globalData.token,
code: wxcode,
encryptedData: data.encryptedData,
iv: data.iv
}).then(res => res.data).then(res => {
typeof callback == "function" && callback(res)
})
},
globalData: {
userInfo: null,
token: '',
apiPath: "https://kt.imgondar.com/api/"
}
})
\ No newline at end of file
{
"pages": [
"pages/index/index",
"pages/webview/index",
"pages/auth/index",
"pages/search/index",
"pages/apply/index",
"pages/reserve/index",
"pages/me/index",
"pages/me/profile/index",
"pages/me/order/index",
"pages/me/vip/index",
"pages/me/collection/index",
"pages/guide/index",
"pages/guide/detail/index"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "WeChat",
"navigationBarTextStyle": "black"
}
}
\ No newline at end of file
/**app.wxss**/
.container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 200rpx 0;
box-sizing: border-box;
}
/* 用于收集 formid 的 button 样式 */
button.form-button {
background-color: transparent;
padding: 0;
margin: 0;
display: inline;
position: static;
border: 0;
padding-left: 0;
padding-right: 0;
border-radius: 0;
font-size: 0;
text-align: left;
line-height: normal;
}
button.form-button::after {
content: '';
width: 0;
height: 0;
-webkit-transform: scale(1);
transform: scale(1);
display: none;
background-color: transparent;
}
const Util = require('../utils/util.js')
const app = getApp()
module.exports = Behavior({
behaviors: [],
properties: {},
data: {},
attached: function () { },
methods: {
/**
* 获取手机号按钮回调事件
*/
__getPhoneNumber: function (event, callback) {
let that = this
wx.login({
success: function (res) {
let encryptedData = event.detail.encryptedData
let iv = event.detail.iv
that.__decodePhoneData(res.code, encryptedData, iv, function (res) {
typeof callback == "function" && callback(res)
})
}
})
},
/**
* 解密用户数据
*/
__decodePhoneData: function (code, encryptedData, iv, callback) {
let that = this
app.requestData('user/auth_phone', Util.sign({
token: app.globalData.token,
code: code,
encryptedData: encryptedData,
iv: iv
}), 'POST', function (res) {
if (!res.code) {
typeof callback == "function" && callback(res)
} else {
app.showToastWithImg('授权失败')
}
})
}
}
})
\ No newline at end of file
// components/banners/index.js
const Util = require('../../utils/util')
const formBehavior = require('../../behaviors/form.js')
const app = getApp()
Component({
behaviors: [formBehavior],
/**
* 组件的属性列表
*/
properties: {
api: {
type: String,
value: 'course/banners'
},
banners: {
type: Object,
}
},
/**
* 组件的初始数据
*/
data: {
banners: [],
indicatorDots: true,
autoplay: true,
interval: 5000,
duration: 1000
},
attached() {
// this._getBannerData()
},
/**
* 组件的方法列表
*/
methods: {
_tapBanner(event) {
let oid = event.currentTarget.dataset.oid
let type = event.currentTarget.dataset.type
let url = event.currentTarget.dataset.url
let type_text = event.currentTarget.dataset.txt
if (type == 1) {
wx.navigateTo({
url: '/pages/course/single/index?id=' + oid,
})
} else if (type == 2) {
wx.navigateTo({
url: '/pages/course/multiple/index?id=' + oid,
})
} else if (type == 3) {
wx.navigateTo({
url: '/pages/courses/coach/index?id=' + oid,
})
} else if (type == 4 && Util.isString(url)) {
wx.navigateTo({
url: '/pages/webview/index?url=' + url + '&t=' + type_text,
})
}
},
}
})
{
"component": true,
"usingComponents": {}
}
\ No newline at end of file
<!--components/banners/index.wxml-->
<view class='banners-wrapper'>
<view class='banners-swipper'>
<swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}">
<block wx:for="{{banners}}" wx:for-item="banner" wx:key="{{banner.id}}">
<swiper-item>
<view data-url="{{banner.url}}" data-type="{{banner.type}}" data-oid="{{banner.oid}}" data-txt="{{banner.type_text}}" catchtap='_tapBanner'>
<form bindsubmit="__collectFormId" report-submit='true'>
<button class='form-button' form-type='submit'>
<image src="{{banner.banner}}" class="banner-image" mode='aspectFill' />
</button>
</form>
</view>
</swiper-item>
</block>
</swiper>
</view>
</view>
\ No newline at end of file
/* components/banners/index.wxss */
@import "/styles/form.wxss";
.banners-wrapper {
width: 100%;
position: relative;
box-shadow: 0px 0px 15px #c6c6c6;
border-radius: 6px;
}
.banners-swipper {
width: 100%;
position: relative;
background: transparent;
border-radius: inherit;
overflow: hidden;
-webkit-transform: translateZ(0);
transform: translateZ(0);
-webkit-mask-image: -webkit-radial-gradient(circle, white 100%, black 100%);
}
.banner-image {
background: transparent;
width: 100%;
height: 150px;
}
Component({
externalClasses: ['i-class', 'i-class-mask', 'i-class-header'],
options: {
multipleSlots: true
},
properties: {
visible: {
type: Boolean,
value: false
},
maskClosable: {
type: Boolean,
value: true
},
showCancel: {
type: Boolean,
value: false
},
cancelText: {
type: String,
value: '取消'
},
actions: {
type: Array,
value: []
}
},
methods: {
handleClickMask () {
if (!this.data.maskClosable) return;
this.handleClickCancel();
},
handleClickItem ({ currentTarget = {} }) {
const dataset = currentTarget.dataset || {};
const { index } = dataset;
this.triggerEvent('click', { index });
},
handleClickCancel () {
this.triggerEvent('cancel');
}
}
});
{
"component": true,
"usingComponents":
{
"i-button": "../button/index",
"i-icon": "../icon/index"
}
}
<view class="i-as-mask i-class-mask {{ visible ? 'i-as-mask-show' : '' }}" bindtap="handleClickMask"></view>
<view class="i-class i-as {{ visible ? 'i-as-show' : '' }}">
<view class="i-as-header i-class-header"><slot name="header"></slot></view>
<view class="i-as-actions">
<view class="i-as-action-item" wx:for="{{ actions }}" wx:key="{{ item.name }}">
<i-button
bind:click="handleClickItem"
data-index="{{ index }}"
open-type="{{ item.openType }}"
type="ghost"
size="large"
long
>
<view class="i-as-btn-loading" wx:if="{{ item.loading }}"></view>
<i-icon wx:if="{{ item.icon }}" type="{{ item.icon }}" i-class="i-as-btn-icon"></i-icon>
<view class="i-as-btn-text" style="{{ item.color ? 'color: ' + item.color : '' }}">{{ item.name }}</view>
</i-button>
</view>
</view>
<view class="i-as-cancel" wx:if="{{ showCancel }}">
<i-button i-class="i-as-cancel-btn" type="ghost" size="large" long="true" bind:click="handleClickCancel">{{ cancelText }}</i-button>
</view>
</view>
.i-as{position:fixed;width:100%;box-sizing:border-box;left:0;right:0;bottom:0;background:#f7f7f7;transform:translate3d(0,100%,0);transform-origin:center;transition:all .2s ease-in-out;z-index:900;visibility:hidden}.i-as-show{transform:translate3d(0,0,0);visibility:visible}.i-as-mask{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.7);z-index:900;transition:all .2s ease-in-out;opacity:0;visibility:hidden}.i-as-mask-show{opacity:1;visibility:visible}.i-as-action-item{position:relative}.i-as-action-item::after{content:'';position:absolute;top:0;left:0;width:200%;height:200%;transform:scale(.5);transform-origin:0 0;pointer-events:none;box-sizing:border-box;border:0 solid #e9eaec;border-bottom-width:1px}.i-as-header{background:#fff;text-align:center;position:relative;font-size:12px;color:#80848f}.i-as-header::after{content:'';position:absolute;top:0;left:0;width:200%;height:200%;transform:scale(.5);transform-origin:0 0;pointer-events:none;box-sizing:border-box;border:0 solid #e9eaec;border-bottom-width:1px}.i-as-cancel{margin-top:6px}.i-as-btn-loading{display:inline-block;vertical-align:middle;margin-right:10px;width:12px;height:12px;background:0 0;border-radius:50%;border:2px solid #e5e5e5;border-color:#666 #e5e5e5 #e5e5e5 #e5e5e5;animation:btn-spin .6s linear;animation-iteration-count:infinite}.i-as-btn-text{display:inline-block;vertical-align:middle}.i-as-btn-icon{font-size:14px!important;margin-right:4px}@keyframes btn-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
options: {
multipleSlots: true
},
properties: {
//info, success, warning, error
type: {
type: String,
value: 'info'
},
closable: {
type: Boolean,
value: false
},
showIcon: {
type: Boolean,
default: false
},
desc: {
type: Boolean,
default: false
},
},
data: {
closed: false
},
methods: {
handleTap() {
this.setData({
closed: !this.data.closed,
});
this.triggerEvent('close');
},
}
});
{
"component": true,
"usingComponents":
{
"i-icon": "../icon/index"
}
}
<view class="i-class i-alert {{'i-alert-'+type}} {{showIcon?'i-alert-with-icon':''}} {{desc?'i-alert-with-desc':''}}" wx:if="{{!closed}}">
<view wx:if="{{ showIcon }}" class="i-alert-icon">
<i-icon type="prompt" wx:if="{{ type === 'info' }}" size="{{desc?24:16}}"></i-icon>
<i-icon type="success" wx:if="{{ type === 'success' }}" size="{{desc?24:16}}"></i-icon>
<i-icon type="warning" wx:if="{{ type === 'warning' }}" size="{{desc?24:16}}"></i-icon>
<i-icon type="delete" wx:if="{{ type === 'error' }}" size="{{desc?24:16}}"></i-icon>
</view>
<slot></slot>
<view class="i-alert-desc">
<slot name="desc"></slot>
</view>
<view class="i-alert-close" wx:if="{{ closable }}" bindtap="handleTap">
<i-icon type="close"></i-icon>
</view>
</view>
.i-alert{position:relative;margin:10px;padding:8px 48px 8px 16px;font-size:14px;border-radius:2px;color:#fff;background:#f7f7f7;color:#495060}.i-alert.i-alert-with-icon{padding:8px 48px 8px 38px}.i-alert-info{color:#fff;background:#2db7f5}.i-alert-success{color:#fff;background:#19be6b}.i-alert-warning{color:#fff;background:#f90}.i-alert-error{color:#fff;background:#ed3f14}.i-alert-icon{position:absolute;top:9px;left:16px;font-size:14px}.i-alert-desc{font-size:12px}.i-alert-with-desc{padding:16px;position:relative}.i-alert-with-desc.i-alert-with-icon{padding:16px 16px 16px 69px}.i-alert-with-desc .i-alert-icon{top:50%;left:24px;margin-top:-21px;font-size:28px}.i-alert-close{font-size:12px;position:absolute;right:16px;top:8px;overflow:hidden;cursor:pointer}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
properties: {
// circle || square
shape: {
type: String,
value: 'circle'
},
// small || large || default
size: {
type: String,
value: 'default'
},
src: {
type: String,
value: ''
}
}
});
{
"component": true
}
<view class="i-class i-avatar i-avatar-{{ shape }} i-avatar-{{ size }} {{ src ? 'i-avatar-image' : '' }}">
<image src="{{ src }}" wx:if="{{ src !== '' }}"></image>
<view class="i-avatar-string" wx:else><slot></slot></view>
</view>
\ No newline at end of file
.i-avatar{display:inline-block;text-align:center;background:#ccc;color:#fff;white-space:nowrap;position:relative;overflow:hidden;vertical-align:middle;width:32px;height:32px;line-height:32px;border-radius:16px;font-size:18px}.i-avatar .ivu-avatar-string{line-height:32px}.i-avatar-large{width:40px;height:40px;line-height:40px;border-radius:20px;font-size:24px}.i-avatar-large .ivu-avatar-string{line-height:40px}.i-avatar-small{width:24px;height:24px;line-height:24px;border-radius:12px;font-size:14px}.i-avatar-small .ivu-avatar-string{line-height:24px}.i-avatar-image{background:0 0}.i-avatar-square{border-radius:4px}.i-avatar>image{width:100%;height:100%}
\ No newline at end of file
Component({
externalClasses: ['i-class', 'i-class-alone'],
properties: {
count: {
type: Number,
value: 0,
observer: 'finalCount'
},
overflowCount: {
type: Number,
value: 99
},
dot: {
type: Boolean,
value: false
},
},
data: {
finalCount: 0
},
methods: {
finalCount() {
this.setData({
finalCount: parseInt(this.data.count) >= parseInt(this.data.overflowCount) ? `${this.data.overflowCount}+` : this.data.count
});
},
}
});
{
"component": true
}
<view class="i-class i-badge">
<slot></slot>
<view class="i-badge-dot" wx:if="{{ dot }}"></view>
<view class="i-badge-count i-class-alone" wx:elif="{{ count !== 0 }}">{{ finalCount }}</view>
</view>
.i-badge{position:relative;display:inline-block;line-height:1;vertical-align:middle}.i-badge-count{position:absolute;transform:translateX(50%);top:-6px;right:0;height:18px;border-radius:9px;min-width:18px;background:#ed3f14;border:1px solid transparent;color:#fff;line-height:18px;text-align:center;padding:0 5px;font-size:12px;white-space:nowrap;transform-origin:-10% center;z-index:10;box-shadow:0 0 0 1px #fff;box-sizing:border-box;text-rendering:optimizeLegibility}.i-badge-count-alone{top:auto;display:block;position:relative;transform:translateX(0)}.i-badge-dot{position:absolute;transform:translateX(-50%);transform-origin:0 center;top:-4px;right:-8px;height:8px;width:8px;border-radius:100%;background:#ed3f14;z-index:10;box-shadow:0 0 0 1px #fff}
\ No newline at end of file
function getCtx (selector) {
const pages = getCurrentPages();
const ctx = pages[pages.length - 1];
const componentCtx = ctx.selectComponent(selector);
if (!componentCtx) {
console.error('无法找到对应的组件,请按文档说明使用组件');
return null;
}
return componentCtx;
}
function Toast(options) {
const { selector = '#toast' } = options;
const ctx = getCtx(selector);
ctx.handleShow(options);
}
Toast.hide = function (selector = '#toast') {
const ctx = getCtx(selector);
ctx.handleHide();
};
function Message(options) {
const { selector = '#message' } = options;
const ctx = getCtx(selector);
ctx.handleShow(options);
}
module.exports = {
$Toast: Toast,
$Message: Message
};
\ No newline at end of file
Component({
externalClasses: ['i-class'],
properties: {
// default, primary, ghost, info, success, warning, error
type: {
type: String,
value: '',
},
inline: {
type: Boolean,
value: false
},
// default, large, small
size: {
type: String,
value: '',
},
// circle, square
shape: {
type: String,
value: 'square'
},
disabled: {
type: Boolean,
value: false,
},
loading: {
type: Boolean,
value: false,
},
long: {
type: Boolean,
value: false
},
openType: String,
appParameter: String,
hoverStopPropagation: Boolean,
hoverStartTime: {
type: Number,
value: 20
},
hoverStayTime: {
type: Number,
value: 70
},
lang: {
type: String,
value: 'en'
},
sessionFrom: {
type: String,
value: ''
},
sendMessageTitle: String,
sendMessagePath: String,
sendMessageImg: String,
showMessageCard: Boolean
},
methods: {
handleTap () {
if (this.data.disabled) return false;
this.triggerEvent('click');
},
bindgetuserinfo({ detail = {} } = {}) {
this.triggerEvent('getuserinfo', detail);
},
bindcontact({ detail = {} } = {}) {
this.triggerEvent('contact', detail);
},
bindgetphonenumber({ detail = {} } = {}) {
this.triggerEvent('getphonenumber', detail);
},
binderror({ detail = {} } = {}) {
this.triggerEvent('error', detail);
}
}
});
{
"component": true
}
<button
class="i-class i-btn {{ long ? 'i-btn-long' : '' }} {{ 'i-btn-' + size }} {{ 'i-btn-' + type }} {{ 'i-btn-' + shape }} {{ loading ? 'i-btn-loading' : '' }} {{ disabled ? 'i-btn-disabled' : ''}} {{ inline ? 'i-btn-inline' : '' }}"
hover-class="i-btn-hover"
bindtap="handleTap"
open-type="{{ openType }}"
app-parameter="{{ appParameter }}"
hover-stop-propagation="{{ hoverStopPropagation }}"
hover-start-time="{{ hoverStartTime }}"
hover-stay-time="{{ hoverStayTime }}"
session-from="{{ sessionFrom }}"
send-message-title="{{ sendMessageTitle }}"
send-message-path="{{ sendMessagePath }}"
send-message-img="{{ sendMessageImg }}"
show-message-card="{{ showMessageCard }}"
bindcontact="bindcontact"
bindgetuserinfo="bindgetuserinfo"
bindgetphonenumber="bindgetphonenumber"
binderror="binderror"
plain="true"
><view class="i-btn-loading-inner" wx:if="{{loading}}"></view><slot></slot></button>
\ No newline at end of file
.i-btn{text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-image:none;white-space:nowrap;user-select:none;font-size:14px;border-radius:2px;border:0!important;position:relative;text-decoration:none;height:44px;line-height:44px;box-shadow:inset 0 0 0 1px rgba(0,0,0,.1);color:#fff!important;background:#f7f7f7!important;color:#495060!important;margin:10px}.i-btn-hover{opacity:.9}.i-btn-long{border-radius:0;margin:0;box-shadow:none}.i-btn-large{height:48px;line-height:48px}.i-btn-small{height:40px;line-height:40px}.i-btn-primary{color:#fff!important;background:#2d8cf0!important}.i-btn-ghost{color:#fff!important;background:#fff!important;color:#495060!important}.i-btn-success{color:#fff!important;background:#19be6b!important}.i-btn-warning{color:#fff!important;background:#f90!important}.i-btn-error{color:#fff!important;background:#ed3f14!important}.i-btn-info{color:#fff!important;background:#2db7f5!important}.i-btn-circle{border-radius:44px}.i-btn-large.i-btn-circle{border-radius:48px}.i-btn-small.i-btn-circle{border-radius:40px}.i-btn-loading{opacity:.6}.i-btn-loading-inner{display:inline-block;margin-right:12px;vertical-align:middle;width:14px;height:14px;background:0 0;border-radius:50%;border:2px solid #fff;border-color:#fff #fff #fff transparent;animation:btn-spin .6s linear;animation-iteration-count:infinite}.i-btn-disabled{color:#bbbec4!important;background:#f7f7f7!important}.i-btn-inline{display:inline-block}@keyframes btn-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
options: {
multipleSlots: true
},
properties: {
full: {
type: Boolean,
value: false
},
thumb: {
type: String,
value: ''
},
title: {
type: String,
value: ''
},
extra: {
type: String,
value: ''
}
}
});
{
"component": true
}
<view class="i-class i-card {{ full ? 'i-card-full' : '' }}">
<view class="i-class i-card-header">
<view class="i-card-header-content">
<image class="i-card-header-thumb" src="{{ thumb }}" mode="aspectFit" wx:if="{{ thumb }}" />
{{ title }}
</view>
<view class="i-card-header-extra" wx:if="{{ extra }}">{{ extra }}</view>
</view>
<view class="i-class i-card-body"><slot name="content"></slot></view>
<view class="i-class i-card-footer"><slot name="footer"></slot></view>
</view>
.i-card{margin:0 16px;font-size:14px;overflow:hidden;position:relative;background:#fff;border:1rpx solid #dddee1;border-radius:5px}.i-card-full{margin:0;border-left:none;border-right:none;border-radius:0}.i-card-header{display:flex;padding:6px 16px;align-items:center}.i-card-header-content{flex:1;text-align:left}.i-card-header-thumb{display:inline-block;width:64px;height:64px;position:relative;margin-left:auto;margin-right:auto;overflow:hidden;background-size:cover;vertical-align:middle}.i-card-header-title{display:inline-block;vertical-align:middle;font-size:14px;color:#1c2438}.i-card-header-extra{flex:1;text-align:right;font-size:14px;color:#80848f}.i-card-body{position:relative;padding:6px 16px;color:#495060;font-size:14px}.i-card-body::before{content:'';position:absolute;top:0;left:0;width:200%;height:200%;transform:scale(.5);transform-origin:0 0;pointer-events:none;box-sizing:border-box;border:0 solid #e9eaec;border-top-width:1px}.i-card-footer{position:relative;padding:6px 16px;color:#80848f;font-size:12px}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
relations: {
'../cell/index': {
type: 'child',
linked () {
this._updateIsLastCell();
},
linkChanged () {
this._updateIsLastCell();
},
unlinked () {
this._updateIsLastCell();
}
}
},
methods: {
_updateIsLastCell() {
let cells = this.getRelationNodes('../cell/index');
const len = cells.length;
if (len > 0) {
let lastIndex = len - 1;
cells.forEach((cell, index) => {
cell.updateIsLastCell(index === lastIndex);
});
}
}
}
});
{
"component": true
}
<view class="i-class i-cell-group">
<slot></slot>
</view>
\ No newline at end of file
const warn = (msg, getValue) => {
console.warn(msg);
console.log('接受到的值为:', getValue);
};
Component({
externalClasses: ['i-class'],
options: {
multipleSlots: true
},
relations: {
'../cell-group/index': {
type: 'parent'
}
},
properties: {
// 左侧标题
title: {
type: String
},
// 标题下方的描述信息
label: {
type: String
},
// 右侧内容
value: {
type: String
},
// 只有点击 footer 区域才触发 tab 事件
onlyTapFooter: {
type: Boolean
},
// 是否展示右侧箭头并开启尝试以 url 跳转
isLink: {
type: null,
value: ''
},
// 链接类型,可选值为 navigateTo,redirectTo,switchTab,reLaunch
linkType: {
type: String,
value: 'navigateTo'
},
url: {
type: String,
value: ''
}
},
data: {
isLastCell: true
},
methods: {
navigateTo () {
const { url } = this.data;
const type = typeof this.data.isLink;
this.triggerEvent('click', {});
if (!this.data.isLink || !url || url === 'true' || url === 'false') return;
if (type !== 'boolean' && type !== 'string') {
warn('isLink 属性值必须是一个字符串或布尔值', this.data.isLink);
return;
}
if (['navigateTo', 'redirectTo', 'switchTab', 'reLaunch'].indexOf(this.data.linkType) === -1) {
warn('linkType 属性可选值为 navigateTo,redirectTo,switchTab,reLaunch', this.data.linkType);
return;
}
wx[this.data.linkType].call(wx, {url});
},
handleTap () {
if (!this.data.onlyTapFooter) {
this.navigateTo();
}
},
updateIsLastCell (isLastCell) {
this.setData({ isLastCell });
}
}
});
{
"component": true
}
<view bindtap="handleTap" class="i-class i-cell {{ isLastCell ? 'i-cell-last' : '' }} {{ isLink ? 'i-cell-access' : '' }}">
<view class="i-cell-icon">
<slot name="icon"></slot>
</view>
<view class="i-cell-bd">
<view wx:if="{{ title }}" class="i-cell-text">{{ title }}</view>
<view wx:if="{{ label }}" class="i-cell-desc">{{ label }}</view>
<slot></slot>
</view>
<view catchtap="navigateTo" class="i-cell-ft">
<block wx:if="{{value}}">{{ value }}</block>
<block wx:else>
<slot name="footer"></slot>
</block>
</view>
</view>
\ No newline at end of file
.i-cell{position:relative;padding:12px 15px;display:flex;background:#fff;align-items:center;line-height:1.4;font-size:14px;overflow:hidden}.i-cell::after{content:'';position:absolute;top:0;left:0;width:200%;height:200%;transform:scale(.5);transform-origin:0 0;pointer-events:none;box-sizing:border-box;border:0 solid #e9eaec;border-bottom-width:1px;left:15px;right:0}.i-cell-last::after{display:none}.i-cell-icon{margin-right:5px}.i-cell-icon:empty{display:none}.i-cell-bd{flex:1}.i-cell-text{line-height:24px;font-size:14px}.i-cell-desc{line-height:1.2;font-size:12px;color:#80848f}.i-cell-ft{position:relative;text-align:right;color:#495060}.i-cell-access .i-cell-ft{padding-right:13px}.i-cell-access .i-cell-ft::after{content:" ";display:inline-block;width:6px;height:6px;position:absolute;top:50%;right:2px;border-width:2px 2px 0 0;border-color:#dddee1;border-style:solid;transform:translateY(-50%) matrix(.71,.71,-.71,.71,0,0)}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
relations: {
'../checkbox/index': {
type: 'child',
linked() {
this.changeCurrent();
},
linkChanged() {
this.changeCurrent();
},
unlinked() {
this.changeCurrent();
}
}
},
properties: {
current: {
type: Array,
value: [],
observer: 'changeCurrent'
},
},
methods: {
changeCurrent(val = this.data.current) {
let items = this.getRelationNodes('../checkbox/index');
const len = items.length;
if (len > 0) {
items.forEach(item => {
item.changeCurrent(val.indexOf(item.data.value) !== -1);
});
}
},
emitEvent(current) {
this.triggerEvent('change', current);
}
}
});
{
"component": true,
"usingComponents":
{
"i-cell-group": "../cell-group/index"
}
}
<i-cell-group class="i-class">
<slot></slot>
</i-cell-group>
const prefixCls = 'i-checkbox';
Component({
externalClasses: ['i-class'],
relations: {
'../checkbox-group/index': {
type: 'parent'
}
},
properties: {
value: {
type: String,
value: ''
},
checked: {
type: Boolean,
value: false
},
disabled: {
type: Boolean,
value: false
},
color: {
type: String,
value: '#2d8cf0'
},
position: {
type: String,
value: 'left', //left right
observer: 'setPosition'
}
},
data: {
checked: true,
positionCls: `${prefixCls}-checkbox-left`,
},
attached() {
this.setPosition();
},
methods: {
changeCurrent(current) {
this.setData({ checked: current });
},
checkboxChange() {
if (this.data.disabled) return;
const item = { current: !this.data.checked, value: this.data.value };
const parent = this.getRelationNodes('../checkbox-group/index')[0];
parent ? parent.emitEvent(item) : this.triggerEvent('change', item);
},
setPosition() {
this.setData({
positionCls: this.data.position.indexOf('left') !== -1 ? `${prefixCls}-checkbox-left` : `${prefixCls}-checkbox-right`,
});
}
}
});
{
"component": true,
"usingComponents":
{
"i-cell": "../cell/index"
}
}
<view class="i-class i-checkbox" catchtap="checkboxChange">
<i-cell i-class="i-checkbox-cell">
<label>
<radio value="{{value}}" checked="{{checked}}" color="{{checked?color:''}}" disabled="{{disabled}}" class="i-checkbox-radio {{positionCls}}" />
<view class="i-checkbox-title">{{value}}</view>
</label>
</i-cell>
</view>
.i-checkbox-cell::after{display:block}.i-checkbox-checkbox-left{float:left}.i-checkbox-checkbox-right{float:right}.i-checkbox-radio{vertical-align:middle}.i-checkbox-title{display:inline-block;vertical-align:middle}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
relations: {
'../row/index': {
type: 'parent'
}
},
properties: {
span: {
value: 0,
type: Number
},
offset: {
value: 0,
type: Number
}
}
});
{
"component": true
}
\ No newline at end of file
<view class="i-class i-col {{ span ? 'i-col-span-' + span : '' }} {{ offset ? 'i-col-offset-' + offset : '' }}"><slot></slot></view>
\ No newline at end of file
.i-col{float:left;box-sizing:border-box;width:0}.i-col-span-1{display:block;width:4.16666667%}.i-col-offset-1{margin-left:4.16666667%}.i-col-span-2{display:block;width:8.33333333%}.i-col-offset-2{margin-left:8.33333333%}.i-col-span-3{display:block;width:12.5%}.i-col-offset-3{margin-left:12.5%}.i-col-span-4{display:block;width:16.66666667%}.i-col-offset-4{margin-left:16.66666667%}.i-col-span-5{display:block;width:20.83333333%}.i-col-offset-5{margin-left:20.83333333%}.i-col-span-6{display:block;width:25%}.i-col-offset-6{margin-left:25%}.i-col-span-7{display:block;width:29.16666667%}.i-col-offset-7{margin-left:29.16666667%}.i-col-span-8{display:block;width:33.33333333%}.i-col-offset-8{margin-left:33.33333333%}.i-col-span-9{display:block;width:37.5%}.i-col-offset-9{margin-left:37.5%}.i-col-span-10{display:block;width:41.66666667%}.i-col-offset-10{margin-left:41.66666667%}.i-col-span-11{display:block;width:45.83333333%}.i-col-offset-11{margin-left:45.83333333%}.i-col-span-12{display:block;width:50%}.i-col-offset-12{margin-left:50%}.i-col-span-13{display:block;width:54.16666667%}.i-col-offset-13{margin-left:54.16666667%}.i-col-span-14{display:block;width:58.33333333%}.i-col-offset-14{margin-left:58.33333333%}.i-col-span-15{display:block;width:62.5%}.i-col-offset-15{margin-left:62.5%}.i-col-span-16{display:block;width:66.66666667%}.i-col-offset-16{margin-left:66.66666667%}.i-col-span-17{display:block;width:70.83333333%}.i-col-offset-17{margin-left:70.83333333%}.i-col-span-18{display:block;width:75%}.i-col-offset-18{margin-left:75%}.i-col-span-19{display:block;width:79.16666667%}.i-col-offset-19{margin-left:79.16666667%}.i-col-span-20{display:block;width:83.33333333%}.i-col-offset-20{margin-left:83.33333333%}.i-col-span-21{display:block;width:87.5%}.i-col-offset-21{margin-left:87.5%}.i-col-span-22{display:block;width:91.66666667%}.i-col-offset-22{margin-left:91.66666667%}.i-col-span-23{display:block;width:95.83333333%}.i-col-offset-23{margin-left:95.83333333%}.i-col-span-24{display:block;width:100%}.i-col-offset-24{margin-left:100%}
\ No newline at end of file
Component({
externalClasses: ['i-class-content', 'i-class-title', 'i-class'],
relations: {
'../collapse/index': {
type: 'parent',
linked: function (target) {
const options = {
accordion: target.data.accordion
}
if (target.data.name === this.data.name) {
options.showContent = 'i-collapse-item-show-content';
}
this.setData(options);
}
}
},
properties: {
title: String,
name: String
},
data: {
showContent: '',
accordion: false
},
options: {
multipleSlots: true
},
methods: {
trigger(e) {
const data = this.data;
if (data.accordion) {
this.triggerEvent('collapse', {name: data.name}, {composed: true, bubbles: true});
} else {
this.setData({
showContent: data.showContent ? '' : 'i-collapse-item-show-content'
});
}
},
}
});
{
"component": true,
"usingComponents": {
"i-icon": "../icon/index"
}
}
<view id="{{name}}" class="i-class i-collapse-item ">
<view class="i-collapse-item-title-wrap" bindtap="trigger">
<i-icon size="16" type="enter" i-class="{{ showContent ? 'i-collapse-item-arrow-show' : 'i-collapse-item-arrow' }}"/>
<text class="i-collapse-item-title i-class-title">{{title}}</text>
</view>
<view class="i-collapse-item-content {{showContent}} i-class-content">
<slot name="content"></slot>
</view>
</view>
\ No newline at end of file
.i-collapse-item{padding:2px 8px;border-top:1px solid #dddee1}.i-collapse-item-title{vertical-align:middle}.i-collapse-item-title-wrap{padding:2px 0 0}.i-collapse-item-content{padding:6px;display:none}.i-collapse-item-show-content{display:block}.i-collapse-item-arrow{transition:transform .2s ease-in-out}.i-collapse-item-arrow-show{transition:transform .2s ease-in-out;transform:rotate(90deg)}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
relations: {
'../collapse-item/index': {
type: 'child'
}
},
properties: {
name: String,
accordion: Boolean
},
methods: {
clickfn(e) {
const params = e.detail;
const allList = this.getRelationNodes('../collapse-item/index');
allList.forEach((item) => {
if (params.name === item.data.name) {
item.setData({
showContent: 'i-collapse-item-show-content'
});
} else {
item.setData({
showContent: ''
});
}
});
},
}
});
{
"component": true
}
<view class="i-class i-collapse" bindcollapse="clickfn">
<slot></slot>
</view>
Component({
properties: {
target: Number,
showDay: Boolean,
callback: String,
format: Array,
clearTimer: Boolean
},
externalClasses: ['countdown-class'],
data: {
time: '',
resultFormat: [],
changeFormat: false
},
ready() {
this.getFormat();
},
methods: {
getFormat() {
const data = this.data;
const len = data.format.length;
if (!data.showDay) data.resultFormat.push('');
if (len >= 3) {
for (let i = 0; i < len; i++) {
if (data.resultFormat.length >= 4) break;
if (data.format[i]) {
data.resultFormat.push(data.format[i].toString());
}
}
if (data.resultFormat.length >= 4) data.changeFormat = true;
}
this.getLastTime();
},
init() {
const self = this;
setTimeout(function () {
self.getLastTime.call(self);
}, 1000);
},
getLastTime() {
const data = this.data;
const gapTime = Math.ceil((data.target - new Date().getTime()) / 1000);
let result = '';
let time = '00:00:00';
let day = '00';
const format = data.resultFormat;
if (gapTime > 0) {
day = this.formatNum(parseInt(gapTime / 86400));
let lastTime = gapTime % 86400;
const hour = this.formatNum(parseInt(lastTime / 3600));
lastTime = lastTime % 3600;
const minute = this.formatNum(parseInt(lastTime / 60));
const second = this.formatNum(lastTime % 60);
if (data.changeFormat) time = `${hour}${format[1]}${minute}${format[2]}${second}${format[3]}`;
else time = `${hour}:${minute}:${second}`;
if (!data.clearTimer) this.init.call(this);
} else {
this.endfn();
}
if (data.showDay) {
if (data.changeFormat) {
result = `${day}${format[0]} ${time}`;
} else {
result = `${day}d ${time}`;
}
} else {
result = time;
}
this.setData({
time: result
});
},
formatNum(num) {
return num > 9 ? num : `0${num}`;
},
endfn() {
this.triggerEvent('callback', {});
}
}
});
{
"component": true
}
<text class="countdown-class">
{{time}}
</text>
Component({
externalClasses: ['i-class'],
properties: {
content: {
type: String,
value: ''
},
height : {
type: Number,
value: 48
},
color : {
type : String,
value : '#80848f'
},
lineColor : {
type : String,
value : '#e9eaec'
},
size : {
type: String,
value: 12
}
}
});
{
"component": true
}
<view class="i-divider i-class" style="{{parse.getStyle(color,size,height)}}">
<view class="i-divider-content" wx:if="{{content !== ''}}">
{{content}}
</view>
<view class="i-divider-content" wx:else>
<slot></slot>
</view>
<view class="i-divider-line" style="background:{{lineColor}}"></view>
</view>
<wxs module="parse">
module.exports = {
getStyle : function(color,size,height){
var color = 'color:' + color +';';
var size = 'font-size:' + size + 'px;';
var height = 'height:' + height+'px;'
return color + size + height;
}
}
</wxs>
.i-divider{width:100%;text-align:center;font-size:12px;position:relative;display:flex;align-items:center;justify-content:center}.i-divider-line{position:absolute;left:0;width:100%;height:1rpx;background-color:#f7f7f7;top:50%}.i-divider-content{background:#fff;position:relative;z-index:1;display:inline-block;padding:0 10px}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
properties: {
visible: {
type: Boolean,
value: false
},
mask: {
type: Boolean,
value: true
},
maskClosable: {
type: Boolean,
value: true
},
mode: {
type: String,
value: 'left' // left right
}
},
data: {},
methods: {
handleMaskClick() {
if (!this.data.maskClosable) {
return;
}
this.triggerEvent('close', {});
}
}
});
{
"component": true
}
<view class="i-class i-drawer {{ visible ? 'i-drawer-show' : '' }} {{ 'i-drawer-' + mode }}">
<view wx:if="{{ mask }}" class="i-drawer-mask" bindtap="handleMaskClick"></view>
<view class="i-drawer-container">
<slot></slot>
</view>
</view>
.i-drawer{visibility:hidden}.i-drawer-show{visibility:visible}.i-drawer-show .i-drawer-mask{display:block;opacity:1}.i-drawer-show .i-drawer-container{opacity:1}.i-drawer-show.i-drawer-left .i-drawer-container,.i-drawer-show.i-drawer-right .i-drawer-container{transform:translate3d(0,-50%,0)}.i-drawer-mask{opacity:0;position:fixed;top:0;left:0;right:0;bottom:0;z-index:6;background:rgba(0,0,0,.6);transition:all .3s ease-in-out}.i-drawer-container{position:fixed;left:50%;top:50%;transform:translate3d(-50%,-50%,0);transform-origin:center;transition:all .3s ease-in-out;z-index:7;opacity:0}.i-drawer-left .i-drawer-container{left:0;top:50%;transform:translate3d(-100%,-50%,0)}.i-drawer-right .i-drawer-container{right:0;top:50%;left:auto;transform:translate3d(100%,-50%,0)}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
relations: {
'../grid-item/index': {
type: 'parent'
}
},
});
{
"component": true
}
<view class="i-class i-grid-icon"><slot></slot></view>
\ No newline at end of file
.i-grid-icon{display:block;width:28px;height:28px;margin:0 auto}.i-grid-icon image{width:100%;height:100%}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
relations: {
'../grid/index': {
type: 'parent'
},
'../grid-icon/index': {
type: 'child'
}
},
data: {
width: '33.33%'
}
});
{
"component": true
}
<view class="i-class i-grid-item" style="width: {{ width }}"><slot></slot></view>
\ No newline at end of file
.i-grid-item{position:relative;float:left;padding:20px 10px;width:33.33333333%;box-sizing:border-box;border-right:1rpx solid #e9eaec;border-bottom:1rpx solid #e9eaec}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
relations: {
'../grid-item/index': {
type: 'parent'
}
},
});
{
"component": true
}
<view class="i-class i-grid-label"><slot></slot></view>
\ No newline at end of file
.i-grid-label{margin-top:5px;display:block;text-align:center;color:#1c2438;font-size:14px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
relations: {
'../grid-item/index': {
type: 'child',
linked () {
this.setGridItemWidth();
},
linkChanged () {
this.setGridItemWidth();
},
unlinked () {
this.setGridItemWidth();
}
}
},
methods: {
setGridItemWidth () {
const nodes = this.getRelationNodes('../grid-item/index');
// const len = nodes.length;
// if (len < 3) {
// nodes.forEach(item => {
// item.setData({
// 'width': '33.33%'
// });
// });
// } else {
// const width = 100 / nodes.length;
// nodes.forEach(item => {
// item.setData({
// 'width': width + '%'
// });
// });
// }
const width = 100 / nodes.length;
nodes.forEach(item => {
item.setData({
'width': width + '%'
});
});
}
},
ready () {
this.setGridItemWidth();
}
});
{
"component": true
}
<view class="i-class i-grid"><slot></slot></view>
\ No newline at end of file
.i-grid{border-top:1rpx solid #e9eaec;border-left:1rpx solid #e9eaec;overflow:hidden}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
properties: {
type: {
type: String,
value: ''
},
custom: {
type: String,
value: ''
},
size: {
type: Number,
value: 14
},
color: {
type: String,
value: ''
}
}
});
{
"component": true
}
<view class="i-class i-icon {{ type === '' ? '' : 'i-icon-' + type }} {{ custom }}" style="font-size: {{ size }}px; {{ color ? 'color:' + color : '' }}"></view>
\ No newline at end of file
Component({
externalClasses: ['i-class'],
properties : {
name : {
type : String,
value : ''
}
},
relations : {
'../index/index' : {
type : 'parent'
}
},
data : {
top : 0,
height : 0,
currentName : ''
},
methods: {
updateDataChange() {
const className = '.i-index-item';
const query = wx.createSelectorQuery().in(this);
query.select( className ).boundingClientRect((res)=>{
this.setData({
top : res.top,
height : res.height,
currentName : this.data.name
})
}).exec()
}
}
})
\ No newline at end of file
{
"component": true
}
<view class="i-index-item i-class">
<view class="i-index-item-header">{{name}}</view>
<view class="i-index-item-content">
<slot></slot>
</view>
</view>
<wxs module="parse">
module.exports = {
}
</wxs>
.i-index-item-header{height:30px;line-height:30px;background:#eee;font-size:14px;padding-left:10px;width:100%;box-sizing:border-box}.i-index-item-content{font-size:14px}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
properties : {
height : {
type : String,
value : '300'
},
itemHeight : {
type : Number,
value : 18
}
},
relations : {
'../index-item/index' : {
type : 'child',
linked(){
this._updateDataChange();
},
linkChanged () {
this._updateDataChange();
},
unlinked () {
this._updateDataChange();
}
}
},
data : {
scrollTop : 0,
fixedData : [],
current : 0,
timer : null,
startTop : 0,
itemLength : 0,
currentName : '',
isTouches : false
},
methods : {
loop(){},
_updateDataChange( ){
const indexItems = this.getRelationNodes('../index-item/index');
const len = indexItems.length;
const fixedData = this.data.fixedData;
/*
* 使用函数节流限制重复去设置数组内容进而限制多次重复渲染
* 暂时没有研究微信在渲染的时候是否会进行函数节流
*/
if (len > 0) {
if( this.data.timer ){
clearTimeout( this.data.timer )
this.setData({
timer : null
})
}
this.data.timer = setTimeout(()=>{
const data = [];
indexItems.forEach((item) => {
if( item.data.name && fixedData.indexOf( item.data.name ) === -1 ){
data.push(item.data.name);
item.updateDataChange();
}
})
this.setData({
fixedData : data,
itemLength : indexItems.length
})
//组件加载完成之后重新设置顶部高度
this.setTouchStartVal();
},0);
this.setData({
timer : this.data.timer
})
}
},
handlerScroll(event){
const detail = event.detail;
const scrollTop = detail.scrollTop;
const indexItems = this.getRelationNodes('../index-item/index');
indexItems.forEach((item,index)=>{
let data = item.data;
let offset = data.top + data.height;
if( scrollTop < offset && scrollTop >= data.top ){
this.setData({
current : index,
currentName : data.currentName
})
}
})
},
getCurrentItem(index){
const indexItems = this.getRelationNodes('../index-item/index');
let result = {};
result = indexItems[index].data;
result.total = indexItems.length;
return result;
},
triggerCallback(options){
this.triggerEvent('change',options)
},
handlerFixedTap(event){
const eindex = event.currentTarget.dataset.index;
const item = this.getCurrentItem(eindex);
this.setData({
scrollTop : item.top,
currentName : item.currentName,
isTouches : true
})
this.triggerCallback({
index : eindex,
current : item.currentName
})
},
handlerTouchMove(event){
const data = this.data;
const touches = event.touches[0] || {};
const pageY = touches.pageY;
const rest = pageY - data.startTop;
let index = Math.ceil( rest/data.itemHeight );
index = index >= data.itemLength ? data.itemLength -1 : index;
const movePosition = this.getCurrentItem(index);
/*
* 当touch选中的元素和当前currentName不相等的时候才震动一下
* 微信震动事件
*/
if( movePosition.name !== this.data.currentName ){
wx.vibrateShort();
}
this.setData({
scrollTop : movePosition.top,
currentName : movePosition.name,
isTouches : true
})
this.triggerCallback({
index : index,
current : movePosition.name
})
},
handlerTouchEnd(){
this.setData({
isTouches : false
})
},
setTouchStartVal(){
const className = '.i-index-fixed';
const query = wx.createSelectorQuery().in(this);
query.select( className ).boundingClientRect((res)=>{
this.setData({
startTop : res.top
})
}).exec()
}
}
})
\ No newline at end of file
{
"component": true
}
<view class="i-index i-class">
<scroll-view
scroll-y
style="{{parse.setScrollStyle(height)}}"
bindscroll="handlerScroll"
scroll-top="{{scrollTop}}">
<slot></slot>
<view class="i-index-fixed"
catchtouchstart="handlerTouchMove"
catchtouchmove="handlerTouchMove"
catchtouchend="handlerTouchEnd">
<view class="i-index-fixed-item"
wx:for="{{fixedData}}"
wx:key="{{index}}"
data-index="{{index}}"
catchtap="handlerFixedTap">
{{item}}
</view>
</view>
<view class="i-index-tooltip" style="{{ isTouches ? 'display:block' : 'display:none' }}">{{currentName}}</view>
</scroll-view>
</view>
<wxs module="parse">
module.exports = {
setScrollStyle : function(height){
var units = ['%','px','rem','rpx','em','rem'];
var hasUnits = false;
for( var i = 0; i < units.length;i++ ){
var u = units[i];
if( height.indexOf( u ) > -1 ){
hasUnits = true;
break;
}
}
return 'height:'+ ( hasUnits ? height : height+'px' );
}
}
</wxs>
.i-index{width:100%;height:100%}.i-index-line{position:absolute;left:0;width:100%;height:1rpx;background-color:#f7f7f7;top:50%}.i-index-content{background:#fff;position:relative;z-index:1;display:inline-block;padding:0 10px}.i-index-fixed{position:fixed;right:0;top:50%;z-index:10;padding-left:10px;transform:translateY(-50%)}.i-index-fixed-item{display:block;height:18px;line-height:18px;padding:0 5px;text-align:center;color:#2d8cf0;font-size:12px;border-radius:50%}.i-index-fixed-item-current{background:#2d8cf0;color:#fff}.i-index-tooltip{position:fixed;left:50%;top:50%;transform:translate3d(-50%,-50%,0);background:rgba(0,0,0,.7);color:#fff;font-size:24px;border-radius:50%;width:80px;height:80px;line-height:80px;text-align:center}
\ No newline at end of file
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment