Commit a416261c by 王榕

Initial commit

parents
.DS_Store
node_modules/
dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
const { api, imgName, getUserInfo, wxLogin} =require('./lib/util.js')
import Cmd from './lib/cmd.js'
import config from './config/index.js'
let timer=null
let socketRoute = ["pages/user_index/user_index","pages/socket/socket"]
App({
onLaunch: function (Ob) {
console.log('小程序',Ob)
// wx.onSocketOpen( (res)=> {
// this.socket.open = true
// // console.log('WebSocket连接已打开!')
// clearInterval(timer)
// let cmd = new Cmd(wx.getStorageSync('user').userMapp.nowVcuNo, wx.getStorageSync('user').token)
// this.sendSocketMessage(cmd.stringify('heart'))
// this.sendSocketMessage(cmd.stringify('firstDevice'))
// timer=setInterval(()=>{
// this.sendSocketMessage(cmd.stringify('heart'))
// },10000)
// })
// // wx.onSocketError((res)=> {
// // console.log('WebSocket打开错误!', res)
// // this.socket.open=false
// // })
// this.onSocketMessage()
// wx.onSocketClose((res)=> {
// // console.log('WebSocket 已关闭!', wx.getStorageSync('user').userMapp.id)
// clearInterval(timer)
// this.socket.open = false
// if (!this.socket.closeByhand) {
// this.socket.repeat += 1
// if (this.socket.repeat > 3) return
// this.socketLink(wx.getStorageSync('user').userMapp.id)
// }
// })
},
onShow(){
},
onSocketMessage(){
wx.onSocketMessage((res) => {
// console.log('收到服务器内容:', res.data)
getCurrentPages().forEach(item => {
if (socketRoute.includes(item.route)) {
item['setSocketUI'](res.data)
}
return item
})
})
},
socketLink(id) {
this.socketClose()
.then(_=>{
// console.log('success',_)
wx.connectSocket({
url: config.wss + id
})
})
.catch(_=>{
// console.log('fail', _)
wx.connectSocket({
url: config.wss + id,
fail(err){console.log('err:',err)}
})
})
},
socketClose(flag=false) {
// console.log('我关闭的')
if (flag){
this.socket.closeByhand=true
}
return new Promise((resolve,reject)=>{
wx.closeSocket({
success(res) {
resolve('关闭成功')
},
fail(err) {
reject('关闭失败')
}
})
})
},
sendSocketMessage(msg) {
// console.log('发送消息',msg)
return new Promise((resolve, reject) => {
if (this.socket.open) {
wx.sendSocketMessage({
data: msg,
success(){
resolve('发送成功')
},
fail(){
reject('发送失败')
}
})
}else{
wx.hideLoading()
reject('连接已关闭,请重试')
}
})
},
onHide(){},
globalData:{},
socket: {
vcuNo:'',
open: false,
closeByhand:false,
repeat:0,
alarmMsg:false,
}
})
\ No newline at end of file
{
"pages": [
"pages/user_index/user_index",
"pages/car_action/index",
"pages/batteryHeath/batteryHeath",
"pages/register2/register2",
"pages/pay/pay",
"pages/welcome2/welcome2",
"pages/device/index",
"pages/tofeedBackList/tofeedBackList",
"pages/feedBack/feedBack",
"pages/modifySelf/modifySelf",
"pages/battery/index",
"pages/setting/setting",
"pages/device_bind/device_bind",
"pages/my/my",
"pages/server_point/server_point",
"pages/user_travel_path/user_travel_path",
"pages/urgent/index",
"pages/user_message/user_message",
"pages/user_device_list/user_device_list",
"pages/user_buy_server/user_buy_server",
"pages/order/index",
"pages/change_password/index",
"pages/orderDetail/index",
"pages/user_travel_query/index",
"pages/shop/index",
"pages/forgetpassword/forgetpassword",
"pages/return_car_pedding/return_car_pedding",
"pages/server_detail/server_detail",
"pages/server/server",
"pages/evaluate/evaluate",
"pages/path_detail/path_detail",
"pages/agreement_use/agreement_use",
"pages/user_car_loc/user_car_loc",
"pages/qr_code/qr_code",
"pages/point_detail/point_detail",
"pages/rent_point/rent_point",
"pages/upload/upload",
"pages/carusers/carusers",
"pages/choose_rent_type/choose_rent_type",
"pages/search/search"
],
"permission": {
"scope.userLocation": {
"desc": "你的位置信息将用于获取附近的网点"
}
},
"window": {
"navigationBarTitleText": "智能电池",
"backgroundTextStyle": "dark",
"navigationBarBackgroundColor": "#17191a",
"navigationBarTextStyle": "white"
},
"usingComponents": {
"NavComponent": "/components/title/common"
},
"networkTimeout": {
"request": 5000
},
"sitemapLocation": "sitemap.json"
}
\ No newline at end of file
page{
min-height: 100%;
box-sizing: border-box;
background:#17191a;
color: #17191a;
}
view{
box-sizing: border-box;
}
button{
color: #17191a;
}
.abtn:active{
opacity: 0.7
}
.xFix{
height: 30rpx;
background: red;
}
\ No newline at end of file
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": true
}
\ No newline at end of file
<view class="wux-class {{ animateCss }}" bindtap="onTap" bindtransitionend="onTransitionEnd" bindanimationend="onAnimationEnd" wx:if="{{ animateStatus !== 'unmounted' }}">
<slot></slot>
</view>
\ No newline at end of file
.wux-animate--fadeIn-enter {
-webkit-transition: opacity .3s;
transition: opacity .3s;
opacity: 0;
}
.wux-animate--fadeIn-enter-active,
.wux-animate--fadeIn-enter-done {
opacity: 1;
}
.wux-animate--fadeIn-exit {
-webkit-transition: opacity .3s;
transition: opacity .3s;
opacity: 1;
}
.wux-animate--fadeIn-exit-active,
.wux-animate--fadeIn-exit-done {
opacity: 0;
}
.wux-animate--fadeInDown-enter {
-webkit-transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, transform .3s;
transition: opacity .3s, transform .3s, -webkit-transform .3s;
opacity: 0;
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
.wux-animate--fadeInDown-enter-active,
.wux-animate--fadeInDown-enter-done {
opacity: 1;
-webkit-transform: none;
transform: none;
}
.wux-animate--fadeInDown-exit {
-webkit-transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, transform .3s;
transition: opacity .3s, transform .3s, -webkit-transform .3s;
opacity: 1;
-webkit-transform: none;
transform: none;
}
.wux-animate--fadeInDown-exit-active,
.wux-animate--fadeInDown-exit-done {
opacity: 0;
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
.wux-animate--fadeInLeft-enter {
-webkit-transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, transform .3s;
transition: opacity .3s, transform .3s, -webkit-transform .3s;
opacity: 0;
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
.wux-animate--fadeInLeft-enter-active,
.wux-animate--fadeInLeft-enter-done {
opacity: 1;
-webkit-transform: none;
transform: none;
}
.wux-animate--fadeInLeft-exit {
-webkit-transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, transform .3s;
transition: opacity .3s, transform .3s, -webkit-transform .3s;
opacity: 1;
-webkit-transform: none;
transform: none;
}
.wux-animate--fadeInLeft-exit-active,
.wux-animate--fadeInLeft-exit-done {
opacity: 0;
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
.wux-animate--fadeInRight-enter {
-webkit-transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, transform .3s;
transition: opacity .3s, transform .3s, -webkit-transform .3s;
opacity: 0;
-webkit-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
}
.wux-animate--fadeInRight-enter-active,
.wux-animate--fadeInRight-enter-done {
opacity: 1;
-webkit-transform: none;
transform: none;
}
.wux-animate--fadeInRight-exit {
-webkit-transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, transform .3s;
transition: opacity .3s, transform .3s, -webkit-transform .3s;
opacity: 1;
-webkit-transform: none;
transform: none;
}
.wux-animate--fadeInRight-exit-active,
.wux-animate--fadeInRight-exit-done {
opacity: 0;
-webkit-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
}
.wux-animate--fadeInUp-enter {
-webkit-transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, transform .3s;
transition: opacity .3s, transform .3s, -webkit-transform .3s;
opacity: 0;
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
}
.wux-animate--fadeInUp-enter-active,
.wux-animate--fadeInUp-enter-done {
opacity: 1;
-webkit-transform: none;
transform: none;
}
.wux-animate--fadeInUp-exit {
-webkit-transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, transform .3s;
transition: opacity .3s, transform .3s, -webkit-transform .3s;
opacity: 1;
-webkit-transform: none;
transform: none;
}
.wux-animate--fadeInUp-exit-active,
.wux-animate--fadeInUp-exit-done {
opacity: 0;
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
}
.wux-animate--slideInUp-enter {
-webkit-transition: -webkit-transform .3s;
transition: -webkit-transform .3s;
transition: transform .3s;
transition: transform .3s, -webkit-transform .3s;
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
visibility: visible;
}
.wux-animate--slideInUp-enter-active,
.wux-animate--slideInUp-enter-done {
-webkit-transform: translateZ(0);
transform: translateZ(0);
}
.wux-animate--slideInUp-exit {
-webkit-transition: -webkit-transform .3s;
transition: -webkit-transform .3s;
transition: transform .3s;
transition: transform .3s, -webkit-transform .3s;
-webkit-transform: translateZ(0);
transform: translateZ(0);
}
.wux-animate--slideInUp-exit-active,
.wux-animate--slideInUp-exit-done {
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
visibility: visible;
}
.wux-animate--slideInDown-enter {
-webkit-transition: -webkit-transform .3s;
transition: -webkit-transform .3s;
transition: transform .3s;
transition: transform .3s, -webkit-transform .3s;
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
visibility: visible;
}
.wux-animate--slideInDown-enter-active,
.wux-animate--slideInDown-enter-done {
-webkit-transform: translateZ(0);
transform: translateZ(0);
}
.wux-animate--slideInDown-exit {
-webkit-transition: -webkit-transform .3s;
transition: -webkit-transform .3s;
transition: transform .3s;
transition: transform .3s, -webkit-transform .3s;
-webkit-transform: translateZ(0);
transform: translateZ(0);
}
.wux-animate--slideInDown-exit-active,
.wux-animate--slideInDown-exit-done {
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
visibility: visible;
}
.wux-animate--slideInLeft-enter {
-webkit-transition: -webkit-transform .3s;
transition: -webkit-transform .3s;
transition: transform .3s;
transition: transform .3s, -webkit-transform .3s;
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
visibility: visible;
}
.wux-animate--slideInLeft-enter-active,
.wux-animate--slideInLeft-enter-done {
-webkit-transform: translateZ(0);
transform: translateZ(0);
}
.wux-animate--slideInLeft-exit {
-webkit-transition: -webkit-transform .3s;
transition: -webkit-transform .3s;
transition: transform .3s;
transition: transform .3s, -webkit-transform .3s;
-webkit-transform: translateZ(0);
transform: translateZ(0);
}
.wux-animate--slideInLeft-exit-active,
.wux-animate--slideInLeft-exit-done {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
visibility: visible;
}
.wux-animate--slideInRight-enter {
-webkit-transition: -webkit-transform .3s;
transition: -webkit-transform .3s;
transition: transform .3s;
transition: transform .3s, -webkit-transform .3s;
-webkit-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
visibility: visible;
}
.wux-animate--slideInRight-enter-active,
.wux-animate--slideInRight-enter-done {
-webkit-transform: translateZ(0);
transform: translateZ(0);
}
.wux-animate--slideInRight-exit {
-webkit-transition: -webkit-transform .3s;
transition: -webkit-transform .3s;
transition: transform .3s;
transition: transform .3s, -webkit-transform .3s;
-webkit-transform: translateZ(0);
transform: translateZ(0);
}
.wux-animate--slideInRight-exit-active,
.wux-animate--slideInRight-exit-done {
-webkit-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
visibility: visible;
}
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: '',
},
color: {
type: String,
value: '#00A958',
},
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"
style='{{"background:"+color+";"+"color:#fff"}}'
><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;color:#495060;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: ['wux-class'],
options: {
multipleSlots: true,
},
properties: {
bordered: {
type: Boolean,
value: true,
},
full: {
type: Boolean,
value: false,
},
title: {
type: String,
value: '',
},
thumb: {
type: String,
value: '',
},
thumbStyle: {
type: String,
value: '',
},
extra: {
type: String,
value: '',
},
},
})
\ No newline at end of file
{
"component": true
}
\ No newline at end of file
<view class="wux-class wux-card {{ bordered ? 'wux-card--bordered' : '' }} {{ full ? 'wux-card--full' : '' }}">
<view class="wux-card__hd">
<view class="wux-card__content">
<image class="wux-card__thumb" src="{{ thumb }}" mode="aspectFit" style="{{ thumbStyle }}" wx:if="{{ thumb }}" />
<text>{{ title }}</text>
</view>
<view class="wux-card__extra" wx:if="{{ extra }}">{{ extra }}</view>
</view>
<view class="wux-card__bd">
<slot name="body"></slot>
</view>
<view class="wux-card__ft">
<slot name="footer"></slot>
</view>
</view>
\ No newline at end of file
.wux-card {
position: relative;
min-height: 192rpx;
padding-bottom: 12rpx;
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-box-orient: vertical;
-webkit-flex-direction: column;
flex-direction: column;
background-color: #fff;
margin:10px 0;
}
.wux-card--bordered:before {
content: " ";
position: absolute;
top: 0;
left: 0;
width: 200%;
height: 200%;
-webkit-transform: scale(0.5);
transform: scale(0.5);
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
pointer-events: none;
box-sizing: border-box;
border: 0 solid #D9D9D9;
border-radius: 20rpx;
border-top-width: 2rpx;
border-right-width: 2rpx;
border-bottom-width: 2rpx;
border-left-width: 2rpx;
}
.wux-card--full:before {
border-radius: 0;
border-right-width: 0;
border-left-width: 0;
}
.wux-card__hd {
display: -webkit-box;
display: -webkit-flex;
display: flex;
font-size: 34rpx;
padding: 18rpx 30rpx;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
}
.wux-card__content {
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
text-align: left;
color: #000;
}
.wux-card__thumb {
display: inline-block;
width: 64rpx;
height: 64rpx;
position: relative;
margin-left: auto;
margin-right: 10rpx;
overflow: hidden;
vertical-align: middle;
}
.wux-card__extra {
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
text-align: right;
font-size: 34rpx;
color: #888;
}
.wux-card__bd {
position: relative;
padding: 30rpx 30rpx 12rpx;
font-size: 30rpx;
color: #333;
min-height: 80rpx;
}
.wux-card__bd:before {
content: " ";
position: absolute;
left: 0;
top: 0;
right: 0;
height: 2rpx;
border-top: 2rpx solid #D9D9D9;
color: #D9D9D9;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
.wux-card__ft {
display: -webkit-box;
display: -webkit-flex;
display: flex;
font-size: 28rpx;
color: #888;
padding: 0 30rpx;
}
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);
});
}
}
}
});
<view class="i-class i-cell-group">
<slot></slot>
</view>
\ No newline at end of file
Component({
externalClasses: [
'custom-class',
'title-class',
'label-class',
'value-class',
'left-icon-class',
'right-icon-class'
],
options: {
multipleSlots: true,
addGlobalClass: true
},
properties: {
title: null,
value: null,
url: String,
icon: String,
label: String,
center: Boolean,
isLink: Boolean,
required: Boolean,
clickable: Boolean,
titleWidth: String,
customStyle: String,
arrowDirection: String,
linkType: {
type: String,
value: 'navigateTo'
},
border: {
type: Boolean,
value: true
}
},
methods: {
onClick() {
const { url } = this.data;
if (url) {
wx[this.data.linkType]({ url });
}
this.triggerEvent('click');
}
}
});
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
\ No newline at end of file
<view
class="custom-class van-cell {{ center ? 'van-cell--center' : '' }} {{ required ? 'van-cell--required' : '' }} {{ isLink || clickable ? 'van-cell--clickable' : '' }} {{ border ? 'van-hairline' : '' }}"
style="{{ customStyle }}"
bind:tap="onClick"
>
<van-icon wx:if="{{ icon }}" custom-class="van-cell__left-icon left-icon-class" name="{{ icon }}" />
<slot wx:else name="icon" />
<view wx:if="{{ title }}" class="van-cell__title title-class" style="{{ titleWidth ? 'max-width: ' + titleWidth + ';min-width: ' + titleWidth : '' }}">
{{ title }}
<view wx:if="{{ label }}" class="van-cell__label label-class">{{ label }}</view>
</view>
<slot name="title" />
<view class="van-cell__value value-class">
<view wx:if="{{ value }}">{{ value }}</view>
<slot wx:else />
</view>
<van-icon
wx:if="{{ isLink }}"
name="arrow"
custom-class="van-cell__right-icon right-icon-class {{ arrowDirection ? 'van-cell__right-icon--' + arrowDirection : '' }}"
/>
<slot wx:else name="right-icon" />
<slot name="extra" />
</view>
.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom::after,.van-hairline--left::after,.van-hairline--right::after,.van-hairline--surround::after,.van-hairline--top-bottom::after,.van-hairline--top::after,.van-hairline::after{content:'';position:absolute;top:0;left:0;width:200%;height:200%;-webkit-transform:scale(.5);transform:scale(.5);-webkit-transform-origin:0 0;transform-origin:0 0;pointer-events:none;box-sizing:border-box;border:0 solid #e5e5e5}.van-hairline--top::after{border-top-width:1px}.van-hairline--left::after{border-left-width:1px}.van-hairline--right::after{border-right-width:1px}.van-hairline--bottom::after{border-bottom-width:1px}.van-hairline--top-bottom::after{border-width:1px 0}.van-hairline--surround::after{border-width:1px}.van-cell{width:100%;display:-webkit-box;display:-webkit-flex;display:flex;padding:10px 15px;box-sizing:border-box;line-height:24px;position:relative;background-color:#fff;color:#333;font-size:14px}.van-cell::after{left:15px;right:0;width:auto;-webkit-transform:scale(1,.5);transform:scale(1,.5);border-bottom-width:1px}.van-cell-group{background-color:#fff}.van-cell__label{font-size:12px;line-height:1.2;color:#666}.van-cell__title,.van-cell__value{-webkit-box-flex:1;-webkit-flex:1;flex:1}.van-cell__value{overflow:hidden;text-align:right;vertical-align:middle}.van-cell__left-icon{font-size:16px;line-height:24px;margin-right:5px;vertical-align:middle}.van-cell__right-icon{color:#999;font-size:12px;line-height:24px;margin-left:5px}.van-cell__right-icon--left::before{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.van-cell__right-icon--up::before{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.van-cell__right-icon--down::before{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.van-cell--clickable:active{background-color:#e8e8e8}.van-cell--required{overflow:visible}.van-cell--required::before{content:'*';position:absolute;left:7px;font-size:14px;color:#f44}.van-cell--center{-webkit-box-align:center;-webkit-align-items:center;align-items:center}
\ No newline at end of file
Component({
properties: {
title: String,
padding: Boolean
},
externalClasses: ['custom-class']
});
<view class="custom-class demo-block {{ padding ? 'demo-block--padding' : '' }}">
<view wx:if="{{ title }}" class="demo-block__title">{{ title }}</view>
<slot />
</view>
.demo-block__title {
margin: 0;
font-weight: 400;
font-size: 16px;
color: rgba(0, 0, 0, 0.8);
padding: 20px 15px 15px;
}
.demo-block--padding {
padding: 0 15px;
}
.demo-block--padding .demo-block__title {
padding-left: 0;
}
Component({
externalClasses: ['i-class'],
relations: {
'../grid-item/index': {
type: 'parent'
}
},
});
<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'],
properties: {
page: {
type: String,
value: ''
},
},
relations: {
'../grid/index': {
type: 'parent'
},
'../grid-icon/index': {
type: 'child'
}
},
data: {
width: '33.33%'
},
methods: {
toDetailPage() {
console.log('ddd')
},
toDetailPage() {
const page = this.data.page
console.log(page)
if (page === '') return
wx.navigateTo({
url: page
})
},
}
});
\ No newline at end of file
<view class="i-class i-grid-item" catchtap='toDetailPage' 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 dotted #383838;
border-bottom: 1rpx dotted #383838;
}
Component({
externalClasses: ['i-class'],
relations: {
'../grid-item/index': {
type: 'parent'
}
},
});
<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: #f9970e;
font-size: 14px;
height: 20px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
Component({
externalClasses: ['i-class'],
properties: {
list: {
type: String,
value: ''
},
},
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(this.data.list){
nodes.forEach(item => {
item.setData({
'width': 100 / Number(this.data.list) + '%'
});
});
return
};
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();
}
});
\ No newline at end of file
{
"component": true
}
<view class="i-class i-grid"><slot></slot></view>
\ No newline at end of file
.i-grid {
border-top: 1rpx solid transparent;
border-left: 1rpx solid transparent;
overflow: hidden;
background-color: #000;
}
/**
* Simple bind, faster than native
*
* @param {Function} fn
* @param {Object} ctx
* @return {Function}
*/
const bind = (fn, ctx) => {
return (...args) => {
return args.length ? fn.apply(ctx, args) : fn.call(ctx)
}
}
/**
* Object assign
*/
const assign = (...args) => Object.assign({}, ...args)
export default Behavior({
properties: {
visible: {
type: Boolean,
value: false,
},
},
methods: {
/**
* 合并参数并绑定方法
*
* @param {Object} opts 参数对象
* @param {Object} fns 方法挂载的属性
*/
$$mergeOptionsAndBindMethods(opts = {}, fns = this.fns) {
const options = Object.assign({}, opts)
for (const key in options) {
if (options.hasOwnProperty(key) && typeof options[key] === 'function') {
fns[key] = bind(options[key], this)
delete options[key]
}
}
return options
},
/**
* Promise setData
* @param {Array} args 参数对象
*/
$$setData(...args) {
const params = assign({}, ...args)
return new Promise((resolve) => {
this.setData(params, resolve)
})
},
/**
* 延迟指定时间执行回调函数
* @param {Function} callback 回调函数
* @param {Number} timeout 延迟时间
*/
$$requestAnimationFrame(callback = () => {}, timeout = 1000 / 60) {
return new Promise((resolve) => setTimeout(resolve, timeout)).then(callback)
},
},
/**
* 组件生命周期函数,在组件实例进入页面节点树时执行
*/
created() {
this.fns = {}
},
/**
* 组件生命周期函数,在组件实例被从页面节点树移除时执行
*/
detached() {
this.fns = {}
},
})
\ No newline at end of file
export const colors = {
'light': '#ddd',
'stable': '#b2b2b2',
'positive': '#387ef5',
'calm': '#11c1f3',
'balanced': '#33cd5f',
'energized': '#ffc900',
'assertive': '#ef473a',
'royal': '#886aea',
'dark': '#444',
}
export const isPresetColor = (color) => {
if (!color) {
return false
}
return colors[color] ? colors[color] : color
}
\ No newline at end of file
/**
* 获取触摸点位置信息
*/
export const getTouchPoints = (e, index = 0) => {
const { pageX: x, pageY: y } = e.touches[index] || e.changedTouches[index]
return {
x,
y,
}
}
/**
* 获取触摸点个数
*/
export const getPointsNumber = (e) => e.touches && e.touches.length || e.changedTouches && e.changedTouches.length
/**
* 判断是否为同一点
*/
export const isEqualPoints = (p1, p2) => p1.x === p2.x && p1.y === p2.y
/**
* 判断是否为相近的两点
*/
export const isNearbyPoints = (p1, p2, DOUBLE_TAP_RADIUS = 25) => {
const xMove = Math.abs(p1.x - p2.x)
const yMove = Math.abs(p1.y - p2.y)
return xMove < DOUBLE_TAP_RADIUS & yMove < DOUBLE_TAP_RADIUS
}
/**
* 获取两点之间的距离
*/
export const getPointsDistance = (p1, p2) => {
const xMove = Math.abs(p1.x - p2.x)
const yMove = Math.abs(p1.y - p2.y)
return Math.sqrt(xMove * xMove + yMove * yMove)
}
\ No newline at end of file
/**
* 过滤对象的函数属性
* @param {Object} opts
*/
const mergeOptionsToData = (opts = {}) => {
const options = Object.assign({}, opts)
for (const key in options) {
if (options.hasOwnProperty(key) && typeof options[key] === 'function') {
delete options[key]
}
}
return options
}
export default mergeOptionsToData
\ No newline at end of file
Component({
options: {
addGlobalClass: true
},
externalClasses: ['custom-class'],
properties: {
info: null,
name: String,
size: String,
color: String,
classPrefix: {
type: String,
value: 'van-icon'
}
},
methods: {
onClick() {
this.triggerEvent('click');
}
}
});
{
"component": true
}
<view
class="custom-class {{ classPrefix }} {{ classPrefix }}-{{ name }}"
style="{{ color ? 'color: ' + color : '' }}; {{ size ? 'font-size: ' + size : '' }}"
bind:tap="onClick"
>
<view wx:if="{{ info !== null }}" class="van-icon__info">{{ info }}</view>
</view>
@font-face{font-style:normal;font-weight:400;font-family:vant-icon;src:url(https://img.yzcdn.cn/vant/vant-icon-76f274.ttf) format('truetype')}.van-icon{position:relative;display:inline-block;font:normal normal normal 14px/1 vant-icon;font-size:inherit;text-rendering:auto}.van-icon__info{color:#fff;left:100%;top:-.5em;font-size:.5em;padding:0 .3em;text-align:center;min-width:1.2em;line-height:1.2;position:absolute;border-radius:.6em;box-sizing:border-box;background-color:#f44;-webkit-transform:translateX(-50%);transform:translateX(-50%);font-family:PingFang SC,Helvetica Neue,Arial,sans-serif}.van-icon::before{display:inline-block}.van-icon-add-o::before{content:"\F000"}.van-icon-add::before{content:"\F001"}.van-icon-add2::before{content:"\F002"}.van-icon-after-sale::before{content:"\F003"}.van-icon-aim::before{content:"\F004"}.van-icon-alipay::before{content:"\F005"}.van-icon-arrow-left::before{content:"\F006"}.van-icon-arrow::before{content:"\F007"}.van-icon-balance-pay::before{content:"\F008"}.van-icon-browsing-history::before{content:"\F009"}.van-icon-card::before{content:"\F00A"}.van-icon-cart::before{content:"\F00B"}.van-icon-cash-back-record::before{content:"\F00C"}.van-icon-cash-on-deliver::before{content:"\F00D"}.van-icon-certificate::before{content:"\F00E"}.van-icon-chat::before{content:"\F00F"}.van-icon-check::before{content:"\F010"}.van-icon-checked::before{content:"\F011"}.van-icon-clear::before{content:"\F012"}.van-icon-clock::before{content:"\F013"}.van-icon-close::before{content:"\F014"}.van-icon-completed::before{content:"\F015"}.van-icon-contact::before{content:"\F016"}.van-icon-coupon::before{content:"\F017"}.van-icon-credit-pay::before{content:"\F018"}.van-icon-debit-pay::before{content:"\F019"}.van-icon-delete::before{content:"\F01A"}.van-icon-description::before{content:"\F01B"}.van-icon-discount::before{content:"\F01C"}.van-icon-ecard-pay::before{content:"\F01D"}.van-icon-edit-data::before{content:"\F01E"}.van-icon-edit::before{content:"\F01F"}.van-icon-exchange-record::before{content:"\F020"}.van-icon-exchange::before{content:"\F021"}.van-icon-fail::before{content:"\F022"}.van-icon-free-postage::before{content:"\F023"}.van-icon-gift-card-pay::before{content:"\F024"}.van-icon-gift-card::before{content:"\F025"}.van-icon-gift::before{content:"\F026"}.van-icon-gold-coin::before{content:"\F027"}.van-icon-goods-collect::before{content:"\F028"}.van-icon-home::before{content:"\F029"}.van-icon-hot-sale::before{content:"\F02A"}.van-icon-hot::before{content:"\F02B"}.van-icon-idcard::before{content:"\F02C"}.van-icon-info-o::before{content:"\F02D"}.van-icon-like-o::before{content:"\F02E"}.van-icon-like::before{content:"\F02F"}.van-icon-location::before{content:"\F030"}.van-icon-logistics::before{content:"\F031"}.van-icon-more-o::before{content:"\F032"}.van-icon-more::before{content:"\F033"}.van-icon-new-arrival::before{content:"\F034"}.van-icon-new::before{content:"\F035"}.van-icon-other-pay::before{content:"\F036"}.van-icon-passed::before{content:"\F037"}.van-icon-password-not-view::before{content:"\F038"}.van-icon-password-view::before{content:"\F039"}.van-icon-pause::before{content:"\F03A"}.van-icon-peer-pay::before{content:"\F03B"}.van-icon-pending-deliver::before{content:"\F03C"}.van-icon-pending-evaluate::before{content:"\F03D"}.van-icon-pending-orders::before{content:"\F03E"}.van-icon-pending-payment::before{content:"\F03F"}.van-icon-phone::before{content:"\F040"}.van-icon-photo::before{content:"\F041"}.van-icon-photograph::before{content:"\F042"}.van-icon-play::before{content:"\F043"}.van-icon-point-gift::before{content:"\F044"}.van-icon-points-mall::before{content:"\F045"}.van-icon-points::before{content:"\F046"}.van-icon-qr-invalid::before{content:"\F047"}.van-icon-qr::before{content:"\F048"}.van-icon-question::before{content:"\F049"}.van-icon-receive-gift::before{content:"\F04A"}.van-icon-records::before{content:"\F04B"}.van-icon-search::before{content:"\F04C"}.van-icon-send-gift::before{content:"\F04D"}.van-icon-setting::before{content:"\F04E"}.van-icon-share::before{content:"\F04F"}.van-icon-shop-collect::before{content:"\F050"}.van-icon-shop::before{content:"\F051"}.van-icon-shopping-cart::before{content:"\F052"}.van-icon-sign::before{content:"\F053"}.van-icon-stop::before{content:"\F054"}.van-icon-success::before{content:"\F055"}.van-icon-tosend::before{content:"\F056"}.van-icon-underway::before{content:"\F057"}.van-icon-upgrade::before{content:"\F058"}.van-icon-value-card::before{content:"\F059"}.van-icon-wap-home::before{content:"\F05A"}.van-icon-wap-nav::before{content:"\F05B"}.van-icon-warn::before{content:"\F05C"}.van-icon-wechat::before{content:"\F05D"}
\ 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({
behaviors: ['wx://form-field'],
externalClasses: ['i-class'],
properties: {
title: {
type: String
},
// text || textarea || password || number
type: {
type: String,
value: 'text'
},
disabled: {
type: Boolean,
value: false
},
placeholder: {
type: String,
value: ''
},
autofocus: {
type: Boolean,
value: false
},
mode: {
type: String,
value: 'normal'
},
right: {
type: Boolean,
value: false
},
error: {
type: Boolean,
value: false
},
maxlength: {
type: Number
}
},
methods: {
handleInputChange(event) {
const { detail = {} } = event;
const { value = '' } = detail;
this.setData({ value });
this.triggerEvent('change', event);
},
handleInputFocus(event) {
this.triggerEvent('focus', event);
},
handleInputBlur(event) {
this.triggerEvent('blur', event);
}
}
});
{
"component": true
}
<view class="i-class i-cell i-input {{ error ? 'i-input-error' : '' }} {{ mode === 'wrapped' ? 'i-input-wrapped' : '' }}">
<view wx:if="{{ title }}" class="i-cell-hd i-input-title">{{ title }}</view>
<textarea
wx:if="{{ type === 'textarea' }}"
auto-height
disabled="{{ disabled }}"
focus="{{ autofocus }}"
value="{{ value }}"
placeholder="{{ placeholder }}"
maxlength="{{ maxlength }}"
class="i-input-input i-cell-bd {{ right ? 'i-input-input-right' : '' }}"
placeholder-class="i-input-placeholder"
bindinput="handleInputChange"
bindfocus="handleInputFocus"
bindblur="handleInputBlur"
></textarea>
<input
wx:else
type="{{ type }}"
disabled="{{ disabled }}"
focus="{{ autofocus }}"
value="{{ value }}"
placeholder="{{ placeholder }}"
maxlength="{{ maxlength }}"
class="i-input-input i-cell-bd {{ right ? 'i-input-input-right' : '' }}"
placeholder-class="i-input-placeholder"
bindinput="handleInputChange"
bindfocus="handleInputFocus"
bindblur="handleInputBlur"
/>
</view>
.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)}.i-input{padding:7px 15px;color:#495060}.i-input-wrapped{margin:10px 15px;background-color:#fff}.i-input-wrapped::after{left:0;border-width:1px;border-radius:4px}.i-input-error{color:#ed3f14}.i-input-title{color:#495060;min-width:65px;padding-right:10px}.i-input-input{flex:1;line-height:1.6;padding:4px 0;min-height:22px;height:auto;font-size:14px}.i-input-placeholder{font-size:14px}.i-input-input-right{text-align:right}.i-input.i-input-wrapped::after{display:block}.i-input-wrapped.i-input-error::after{border-color:#ed3f14}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
properties: {
loading: {
type: Boolean,
value: true
},
tip: {
type: String,
value: ''
}
},
});
<view class="i-class i-load-more {{ loading ? '' : 'i-load-more-line' }}">
<view class="i-load-more-loading" wx:if="{{ loading }}"></view>
<view class="i-load-more-tip">
<view wx:if="{{ tip !== '' }}">{{ tip }}</view>
<view wx:elif="{{ tip === '' && loading }}">正在加载</view>
<view class="i-load-more-empty" wx:else></view>
</view>
</view>
\ No newline at end of file
.i-load-more{width:65%;margin:1.5em auto;line-height:1.6em;font-size:14px;text-align:center}.i-load-more-loading{display:inline-block;margin-right:12px;vertical-align:middle;width:14px;height:14px;background:0 0;border-radius:50%;border:2px solid #e9eaec;border-color:#e9eaec #e9eaec #e9eaec #2d8cf0;animation:btn-spin .6s linear;animation-iteration-count:infinite}.i-load-more-tip{display:inline-block;vertical-align:middle;color:#495060}.i-load-more-line{border-top:1px solid #dddee1;display:flex;border-top:0}.i-load-more-line::before{position:relative;top:-1px;-webkit-box-flex:1;-webkit-flex:1;flex:1;content:'';border-top:1px solid #dddee1}.i-load-more-line::after{position:relative;top:-1px;-webkit-box-flex:1;-webkit-flex:1;flex:1;content:'';border-top:1px solid #dddee1}.i-load-more-line .i-load-more-tip{position:relative;top:-.9em;padding:0 .55em}.i-load-more-empty{width:4px;height:4px;border-radius:50%;background-color:#e5e5e5;display:inline-block;position:relative;vertical-align:0;top:-.16em}@keyframes btn-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}
\ No newline at end of file
const default_data = {
visible: false,
content: '',
duration: 2,
type: 'default', // default || success || warning || error
};
let timmer = null;
Component({
externalClasses: ['i-class'],
data: {
...default_data
},
methods: {
handleShow (options) {
const { type = 'default', duration = 2 } = options;
this.setData({
...options,
type,
duration,
visible: true
});
const d = this.data.duration * 1000;
if (timmer) clearTimeout(timmer);
if (d !== 0) {
timmer = setTimeout(() => {
this.handleHide();
timmer = null;
}, d);
}
},
handleHide () {
this.setData({
...default_data
});
}
}
});
\ No newline at end of file
{
"component": true
}
<view class="i-class i-message i-message-{{type}} {{ visible ? 'i-message-show' : '' }}">
{{ content }}
</view>
\ No newline at end of file
.i-message{display:block;width:100%;min-height:32px;line-height:2.3;position:fixed;top:0;left:0;right:0;background:#2d8cf0;color:#fff;text-align:center;font-size:14px;z-index:1010;opacity:0;-webkit-transform:translateZ(0) translateY(-100%);transition:all .4s ease-in-out}.i-message-show{-webkit-transform:translateZ(0) translateY(0);opacity:1}.i-message-default{background:#2d8cf0}.i-message-success{background:#19be6b}.i-message-warning{background:#f90}.i-message-error{background:#ed3f14}
\ No newline at end of file
Component({
externalClasses: ['i-class', 'i-class-mask'],
properties: {
visible: {
type: Boolean,
value: false
},
title: {
type: String,
value: ''
},
showOk: {
type: Boolean,
value: true
},
showCancel: {
type: Boolean,
value: true
},
okText: {
type: String,
value: '确定'
},
cancelText: {
type: String,
value: '取消'
},
// 按钮组,有此值时,不显示 ok 和 cancel 按钮
actions: {
type: Array,
value: []
},
// horizontal || vertical
actionMode: {
type: String,
value: 'horizontal'
}
},
methods: {
handleClickItem ({ currentTarget = {} }) {
const dataset = currentTarget.dataset || {};
const { index } = dataset;
this.triggerEvent('click', { index });
},
handleClickOk () {
this.triggerEvent('ok');
},
handleClickCancel () {
this.triggerEvent('cancel');
}
}
});
{
"component": true,
"usingComponents": {
"i-grid": "../grid/index",
"i-grid-item": "../grid-item/index",
"i-button": "../button/index",
"i-icon": "../icon/index"
}
}
<view class="i-modal-mask i-class-mask {{ visible ? 'i-modal-mask-show' : '' }}"></view>
<view class="i-class i-modal {{ visible ? 'i-modal-show' : '' }}">
<view class="i-modal-main">
<view class="i-modal-content">
<view class="i-modal-title" wx:if="{{ title }}">{{ title }}</view>
<view class="i-modal-body"><slot></slot></view>
<view class="i-modal-actions" wx:if="{{ actions.length }}">
<block wx:if="{{ actionMode === 'horizontal' }}">
<i-grid i-class="i-modal-grid">
<i-grid-item i-class="{{ actions.length === (index + 1) ? 'i-modal-grid-item-last' : 'i-modal-grid-item' }}" wx:for="{{ actions }}" wx:key="{{ item.name }}">
<template is="button" data="{{ item, index }}"></template>
</i-grid-item>
</i-grid>
</block>
<block wx:else>
<view class="i-modal-action-vertical" wx:for="{{ actions }}" wx:key="{{ item.name }}">
<template is="button" data="{{ item, index }}"></template>
</view>
</block>
</view>
<view class="i-modal-actions" wx:else>
<i-grid i-class="i-modal-grid" wx:if="{{ showOk || showCancel }}">
<i-grid-item i-class="i-modal-grid-item" wx:if="{{ showCancel }}">
<i-button i-class="i-modal-btn-cancel" long type="ghost" bind:click="handleClickCancel">{{ cancelText }}</i-button>
</i-grid-item>
<i-grid-item i-class="i-modal-grid-item-last" wx:if="{{ showOk }}">
<i-button i-class="i-modal-btn-ok" long type="ghost" bind:click="handleClickOk">{{ okText }}</i-button>
</i-grid-item>
</i-grid>
</view>
</view>
</view>
</view>
<template name="button">
<i-button long type="ghost" data-index="{{ index }}" bind:click="handleClickItem">
<view class="i-modal-btn-loading" wx:if="{{ item.loading }}"></view>
<i-icon wx:if="{{ item.icon }}" type="{{ item.icon }}" i-class="i-modal-btn-icon"></i-icon>
<view class="i-modal-btn-text" style="{{ item.color ? 'color: ' + item.color : '' }}">{{ item.name }}</view>
</i-button>
</template>
\ No newline at end of file
.i-modal{position:fixed;overflow:auto;top:0;right:0;bottom:0;left:0;height:100%;z-index:1000;display:flex;outline:0;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center;transform:translateZ(1px);opacity:0;visibility:hidden}.i-modal-show{visibility:visible;opacity:1}.i-modal-mask{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.7);z-index:1000;transition:all .2s ease-in-out;opacity:0;visibility:hidden}.i-modal-mask-show{opacity:1;visibility:visible}.i-modal-main{width:270px;position:relative}.i-modal-content{border-radius:7px;padding-top:15px;position:relative;background-color:#fff;border:0;background-clip:padding-box;text-align:center;height:100%;overflow:hidden}.i-modal-body{max-height:100px;margin-bottom:15px;font-size:14px;color:#80848f;height:100%;line-height:1.5;overflow:auto}.i-modal-title{padding:6px 15px 15px;margin:0;font-size:18px;line-height:1;color:#1c2438;text-align:center}.i-modal-actions{margin:0 1px}.i-modal-action-vertical{position:relative}.i-modal-action-vertical: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-top-width:1px}.i-modal-grid{border-radius:0 0 7px 7px;border-left:none}.i-modal-grid-item,.i-modal-grid-item-last{padding:0;border-bottom:none}.i-modal-grid-item-last{border-right:none}.i-modal-btn-ok{color:#2d8cf0!important}.i-modal-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-modal-btn-text{display:inline-block;vertical-align:middle}.i-modal-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
const app = getApp();
Component({
properties: {
vTitle: {
type: String,
value: ""
},
isSearch:{
type: Boolean,
value: false
}
},
data: {
haveBack: true, // 是否有返回按钮,true 有 false 没有 若从分享页进入则没有返回按钮
statusBarHeight: 0, // 状态栏高度
navbarHeight: 0, // 顶部导航栏高度
navbarBtn: { // 胶囊位置信息
height: 0,
width: 0,
top: 0,
bottom: 0,
right: 0
},
cusnavH: 0, //title高度
},
// 微信7.0.0支持wx.getMenuButtonBoundingClientRect()获得胶囊按钮高度
attached: function () {
if (!app.globalData.systeminfo) {
app.globalData.systeminfo = wx.getSystemInfoSync();
}
if (!app.globalData.headerBtnPosi) app.globalData.headerBtnPosi = wx.getMenuButtonBoundingClientRect();
console.log(app.globalData)
let statusBarHeight = app.globalData.systeminfo.statusBarHeight // 状态栏高度
let headerPosi = app.globalData.headerBtnPosi // 胶囊位置信息
console.log(statusBarHeight)
console.log(headerPosi)
let btnPosi = { // 胶囊实际位置,坐标信息不是左上角原点
height: headerPosi.height,
width: headerPosi.width,
top: headerPosi.top - statusBarHeight, // 胶囊top - 状态栏高度
bottom: headerPosi.bottom - headerPosi.height - statusBarHeight, // 胶囊bottom - 胶囊height - 状态栏height (胶囊实际bottom 为距离导航栏底部的长度)
right: app.globalData.systeminfo.windowWidth - headerPosi.right // 这里不能获取 屏幕宽度,PC端打开小程序会有BUG,要获取窗口高度 - 胶囊right
}
let haveBack;
if (getCurrentPages().length != 1) { // 当只有一个页面时,并且是从分享页进入
haveBack = false;
} else {
haveBack = true;
}
var cusnavH = btnPosi.height + btnPosi.top + btnPosi.bottom // 导航高度
console.log( app.globalData.systeminfo.windowWidth, headerPosi.width)
this.setData({
haveBack: haveBack, // 获取是否是通过分享进入的小程序
statusBarHeight: statusBarHeight,
navbarHeight: headerPosi.bottom + btnPosi.bottom, // 胶囊bottom + 胶囊实际bottom
navbarBtn: btnPosi,
cusnavH: cusnavH
});
//将实际nav高度传给父类页面
this.triggerEvent('commonNavAttr',{
height: headerPosi.bottom + btnPosi.bottom
});
},
methods: {
_goBack: function () {
wx.navigateBack({
delta: 1
});
},
bindKeyInput:function(e){
console.log(e.detail.value);
}
}
})
\ No newline at end of file
{
"component": true,
"usingComponents": {},
"navigationStyle": "custom"
}
\ No newline at end of file
<view class="custom_nav" style="height:{{navbarHeight}}px;">
<view class="custom_nav_box" style="height:{{navbarHeight}}px;">
<view class="custom_nav_bar" style="top:{{statusBarHeight}}px; height:{{cusnavH}}px;">
<block wx:if="{{isSearch}}">
<input class="navSearch"style="height:{{navbarBtn.height-2}}px;line-height:{{navbarBtn.height-4}}px; top:{{navbarBtn.top+1}}px; left:{{navbarBtn.right}}px; border-radius:{{navbarBtn.height/2}}px;" maxlength="10" bindinput="bindKeyInput" placeholder="输入文字搜索"/>
</block>
<block wx:else>
<view class="custom_nav_icon {{!haveBack||'borderLine'}}" style="height:{{navbarBtn.height}}px;line-height:{{navbarBtn.height-2}}px; top:{{navbarBtn.top}}px; left:{{navbarBtn.right}}px; border-radius:{{navbarBtn.height/2}}px;">
<view wx:if="{{haveBack}}" class="icon-back" bindtap='_goBack'>
<image src='/images/back.png' mode='aspectFill' class='back-pre'></image>
</view>
<view wx:if="{{haveBack}}" class='navbar-v-line'></view>
<view class="icon-home">
<navigator class="home_a" url="/pages/home/index" open-type="switchTab">
<image src='/images/home.png' mode='aspectFill' class='back-home'></image>
</navigator>
</view>
</view>
<view class="nav_title" style="height:{{cusnavH}}px; line-height:{{cusnavH}}px;">
{{vTitle}}
</view>
</block>
</view>
</view>
</view>
\ No newline at end of file
/* components/plugins/nav/test.wxss */
.custom_nav {
width: 100%;
background: #3a7dd7;
position: relative;
z-index: 99999;
}
.custom_nav_box {
position: fixed;
width: 100%;
background: #3a7dd7;
z-index: 99999;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.3);
}
.custom_nav_bar {
position: relative;
z-index: 9;
}
.custom_nav_box .nav_title {
font-size: 28rpx;
color: #fff;
text-align: center;
position: absolute;
max-width: 360rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
z-index: 1;
}
.custom_nav_box .custom_nav_icon {
position:absolute;
z-index: 2;
display: inline-block;
border-radius: 50%;
vertical-align: top;
font-size:0;
box-sizing: border-box;
}
.custom_nav_box .custom_nav_icon.borderLine {
border: 1rpx solid rgba(255, 255, 255, 0.3);
background: rgba(0, 0, 0, 0.1);
}
.navbar-v-line {
width: 1px;
margin-top: 14rpx;
height: 32rpx;
background-color: rgba(255, 255, 255, 0.3);
display: inline-block;
vertical-align: top;
}
.icon-back {
display: inline-block;
width: 74rpx;
padding-left: 20rpx;
vertical-align: top;
/* margin-top: 12rpx;
vertical-align: top; */
height: 100%;
}
.icon-home {
/* margin-top: 8rpx;
vertical-align: top; */
display: inline-block;
width: 80rpx;
text-align: center;
vertical-align: top;
height: 100%;
}
.icon-home .home_a {
height: 100%;
display: inline-block;
vertical-align: top;
width: 35rpx;
}
.custom_nav_box .back-pre,
.custom_nav_box .back-home {
width: 35rpx;
height: 35rpx;
vertical-align: middle;
}
.navSearch {
width: 200px;
background: #fff;
font-size: 14px;
position: absolute;
padding: 0 20rpx;
z-index: 9;
}
\ No newline at end of file
const {
api,
mapApi,
imgName,
getUserInfo,
wxLogin,
alertTip,
toastTip,
authAgainByUser,
userLocation,
getRgbColor,
} = require('../../lib/util.js')
const moment = require('../../lib/moment.js')
let deviceTimer = null
Component({
externalClasses: ['wr-nav'],
options: {
multipleSlots: true // 在组件定义时的选项中启用多slot支持
},
data: {
navs: [{
name: '主页',
check: false,
url: '/pages/user_index/user_index',
img: './home.png',
}, {
name: '车况',
check: false,
url: '/pages/device/index',
img: './device.png',
}, {
name: '服务点',
check: false,
url: '/pages/server_point/server_point',
img: './server.png',
}, {
name: '我的',
url: '/pages/my/my',
check: false,
img: './my.png',
}],
lock: true,
user: {}
},
properties: {
nowIndex: {
type: Number,
value: 0,
}
},
attached() {
let navs = this.data.navs.map(elt => {
elt.check = false
return elt
})
navs[this.data.nowIndex].check = true
this.setData({
navs
})
// ui定时器
const user = wx.getStorageSync('user').userMapp
if (!user || !user.nowVcuNo) {
return
}
this.setData({
user
})
clearInterval(deviceTimer)
// this.getCarDetail()
// deviceTimer = setInterval(() => {
// this.getCarDetail()
// }, 5000)
},
detached() {
clearInterval(deviceTimer)
},
methods: {
toggleLockStatus() {
if (this.data.lock) { //关
this.netOpenCar()
} else {
this.netCloseCar()
}
},
getCarDetail() {
api.get('device/base/deviceDetail', {}, true)
.then(res => {
let {
data,
model: {
deviceInfo
}
} = res
let carData = {
...data,
...deviceInfo
}
this.triggerEvent('uidata', carData)
this.setData({
lock: carData.lock_state == '1' ? false : true //锁 1开锁状态
})
})
.catch(err => {
console.error(1, err)
})
},
//关锁
netCloseCar() {
api.post('device/base/lockAndUnLock?state=2', {
state: 2
})
.then(res => {
alertTip('锁车成功')
this.setData({
'lock': true,
})
})
.catch(err => {
alertTip(err)
})
},
//开锁
netOpenCar() {
api.post('device/base/lockAndUnLock?state=1', {
state: 1
})
.then(res => {
alertTip('开锁成功')
this.setData({
'lock': false,
})
})
.catch(err => {
alertTip(err)
})
},
}
});
\ No newline at end of file
{
"component": true
}
<!-- <view class='wr-nav-body'>
<view class='wr-body-content'>
<slot></slot>
</view>
<view class='wr-nav-bottom'>
<view class='wr-nav-content'>
<view class='wr-nav-navs'>
<navigator class='wr-nav-item {{item.check?"check":""}}' wx:for='{{navs}}' wx:key='{{item.name}}' url='{{item.url}}' open-type='redirect'>
<image src='{{item.img}}'></image>
<text>{{item.name}}</text>
</navigator>
</view>
<view class='car-action-body'>
<view class='nav-car-action {{lock?"":"open"}}' bindtap='toggleLockStatus'>
<image src='./lock.png' wx:if='{{lock}}'></image>
<image src='./unlock.png' wx:else></image>
</view>
</view>
</view>
</view>
</view> -->
<view>
<slot></slot>
</view>
\ No newline at end of file
/* .wr-nav-body {
min-height: 100vh;
width: 100vw;
overflow: hidden;
padding-bottom: 115rpx;
background-color: #000;
color: #f9970e;
}
.wr-body-content{
height: 100%;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
.wr-nav-body .wr-nav-bottom {
position: fixed;
left: 0;
width: 100%;
bottom: 0;
height: 115rpx;
background-color: #000000;
}
.wr-nav-body .wr-nav-content {
width: 100%;
height: 100%;
display: flex;
align-items: center;
}
.wr-nav-body .wr-nav-content .nav-car-action {
width: 280rpx;
height: 280rpx;
border-radius: 50%;
position: absolute;
right: -101rpx;
bottom: -101rpx;
background-color: rgba(249, 151, 14, 1);
border: 16rpx solid #000000;
}
.wr-nav-body .wr-nav-content .nav-car-action.open {
background-color: rgba(165, 214, 63, 1);
}
.wr-nav-body .wr-nav-content .nav-car-action image{
width: 108rpx;
height: 108rpx;
position: relative;
left: 46rpx;
top: 40rpx;
}
.wr-nav-body .wr-nav-bottom .wr-nav-navs {
width: 575rpx;
display: flex;
justify-content: space-around;
align-items: center;
height: 100%;
}
.wr-nav-body .wr-nav-bottom .wr-nav-item {
display: flex;
flex-direction: column;
align-items: center;
opacity: 0.6;
}
.wr-nav-body .wr-nav-bottom .wr-nav-item.check {
opacity: 1;
}
.car-action-body{
align-self: flex-end;
width: 175rpx;
height: 173rpx;
position: relative;
overflow: hidden;
}
.wr-nav-item image {
width: 57rpx;
height: 57rpx;
}
.wr-nav-item text {
font-size: 20rpx;
text-align: center;
} */
// pages/star/star.js
const { imgName } = require('../../lib/util.js')
Component({
/**
* 组件的属性列表
*/
properties: {
titleList:{
type: Array, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
observer: function (newVal, oldVal) {
} // 属性被改变时执行的函数(可选),也可以写成在methods段中定义的方法名字符串, 如:'_propertyChange'
},
},
/**
* 组件的初始数据
*/
data: {
activeNum: 0,
},
/**
* 组件的方法列表
*/
methods: {
//点击改变分数的函数
changeScore(e) {
// var myEventDetail = {} // detail对象,提供给事件监听函数
// var myEventOption = {} // 触发事件的选项
if (!this.data.edit) return
this.setData(
{
selfScore: Number(e.target.id) + 1
}
)
this._setStar()
},
_changeTab(e) {
let oldIndex = this.data.activeNum
let newIndex=Number(e.currentTarget.id)
let res=null//tabIn 返回false的情况可以取消tab
this.data.titleList.forEach((item,ix)=>{
if(ix == oldIndex){
if (item.tabOut){
item.tabOut()
}
}
if (ix == newIndex) {
if (item.tabIn) {
res = item.tabIn() == false ? false : true
} else {
res=true
}
}
return item
})
if(res){
this.setData({
activeNum: newIndex
})
this.triggerEvent('tabChange', { activeIndex: newIndex })
}
}
}
})
{
"component": true,
"usingComponents": {}
}
\ No newline at end of file
<!--components/navbar/navbar.wxml-->
<view class='wr-tab-header'>
<view class='wr-tab-item {{activeNum==index?"active":""}}' wx:for='{{titleList}}' wx:key='{{index}}' id='{{index}}' catchtap='_changeTab'>
<text>{{item.name}}</text>
</view>
</view>
\ No newline at end of file
/* components/navbar/navbar.wxss */
.wr-tab-header{
flex: 0 0 auto;
display: flex;
justify-content: space-around;
}
.wr-tab-item{
flex: 1 0 10rpx;
text-align: center;
padding: 10rpx;
border-bottom: 2px solid transparent;
}
.active{
color: #f9970e;
border-bottom: 2px solid #f9970e;
}
\ No newline at end of file
Component({
externalClasses: ['i-class'],
properties: {
title: {
type: String,
value: ''
},
// 标题顶部距离
hideTop: {
type: Boolean,
value: false
},
hideBorder: {
type: Boolean,
value: false
}
}
});
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
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