Commit f7fc96e5 by 李嘉林

临时删除

parent 10b16f19
......@@ -82,15 +82,19 @@ module.exports = merge(baseWebpackConfig, {
// inject: true
// }),
new FriendlyErrorsPlugin(),
// new UglifyJsPlugin({
// sourceMap: true,
// uglifyOptions: {
// compress: {
// warnings: false,
// drop_console: true,
// pure_funcs: ['console.log']
// }
// }
// })
new UglifyJsPlugin({
sourceMap: true,
uglifyOptions: {
// 删除注释
output: {
comments: false
},
compress: {
warnings: false,
drop_console: true,
pure_funcs: ['console.log']
}
}
})
]
})
......@@ -115,6 +115,10 @@ if (useUglifyJs) {
webpackConfig.plugins.push(new UglifyJsPlugin({
sourceMap: true,
uglifyOptions: {
// 删除注释
output: {
comments: false
},
compress: {
warnings: false,
drop_console: true,
......
const componentOptions = {
// 组件选项
options: {
multipleSlots: true
},
behaviors: [],
properties: {
datas: {
type: Object
}
},
// 组件数据
data: {
isPageHidden: false // 页面是否处于隐藏状态
},
// 数据监听器
observers: {},
// 组件方法
methods: {
init() {}
},
// 组件生命周期
lifetimes: {
created() {},
attached() {
this.init();
},
ready() {},
moved() {},
detached() {}
},
definitionFilter() {},
// 页面生命周期
pageLifetimes: {
// 页面被展示
show() {
const { isPageHidden } = this.data;
// show事件发生前,页面不是处于隐藏状态时
if (!isPageHidden) {
return;
}
// 重新执行定时器等操作
},
// 页面被隐藏
hide() {
this.setData({
isPageHidden: true
});
// 清除定时器等操作
},
// 页面尺寸变化时
resize() {}
}
};
Component(componentOptions)
{
"component": true,
"usingComponents": {
"banner": "/static/nativeComponents/Banner/index",
"goods-list": "/static/nativeComponents/GoodsList/index",
"time-limited-discount": "/static/nativeComponents/TimeLimitedDiscount/index",
"waterfall-flow": "/static/nativeComponents/module/WaterfallFlow/index",
"van-button": "/static/vant/button/index",
"area-navigation": "/static/nativeComponents/AreaNavigation/index",
"cube-nav": "/static/nativeComponents/CubeNav/index",
"float-button": "/static/nativeComponents/FloatButton/index",
"goods-search": "/static/nativeComponents/GoodsSearch/index",
"notice": "/static/nativeComponents/Notice/index",
"pop-up": "/static/nativeComponents/PopUp/index",
"share-popup": "/static/nativeComponents/SharePopup/index",
"speedy-nav": "/static/nativeComponents/SpeedyNav/index",
"video-player": "/static/nativeComponents/VideoPlayer/index",
"transverse-label": "/static/nativeComponents/TransverseLabel/index"
}
}
\ No newline at end of file
<!-- 组件集合 -->
<view class="ComponentsList">
<block wx:for="{{datas}}">
<block wx:if="{{item.componentCode=='banner' && item.componentInfo.visible == 1}}">
<banner datas="{{item}}"></banner>
</block>
<block wx:elif="{{item.componentCode=='goods-list' && item.componentInfo.visible == 1}}">
<goods-list class="goodsListItem" datas="{{item}}"></goods-list>
</block>
<block wx:elif="{{item.componentCode=='area-navigation' && item.componentInfo.visible == 1}}">
<area-navigation datas="{{item}}" :changeLocation="changeLocation"></area-navigation>
</block>
<block wx:elif="{{item.componentCode=='cube-nav' && item.componentInfo.visible == 1}}">
<cube-nav datas="{{item}}"></cube-nav>
</block>
<block wx:elif="{{item.componentCode=='time-limited-discount' && item.componentInfo.visible == 1}}">
<time-limited-discount datas="{{item}}"></time-limited-discount>
</block>
<block wx:elif="{{item.componentCode=='links' && item.componentInfo.visible == 1}}">
<links datas="{{item}}"></links>
</block>
<block wx:elif="{{item.componentCode=='interval' && item.componentInfo.visible == 1}}">
<interval datas="{{item}}"></interval>
</block>
<block wx:elif="{{item.componentCode=='partition' && item.componentInfo.visible == 1}}">
<partition datas="{{item}}"></partition>
</block>
<block wx:elif="{{item.componentCode=='shop-popup' && item.componentInfo.visible == 1}}">
<shop-popup datas="{{item}}"></shop-popup>
</block>
<block wx:elif="{{item.componentCode=='float-button' && item.componentInfo.visible == 1}}">
<float-button datas="{{item}}"></float-button>
</block>
<block wx:elif="{{item.componentCode=='text-text' && item.componentInfo.visible == 1}}">
<text-text datas="{{item}}"></text-text>
</block>
<block wx:elif="{{item.componentCode=='img-text' && item.componentInfo.visible == 1}}">
<img-text datas="{{item}}"></img-text>
</block>
<block wx:elif="{{item.componentCode=='goods-search' && item.componentInfo.visible == 1}}">
<goods-search datas="{{item}}"></goods-search>
</block>
<block wx:elif="{{item.componentCode=='notice' && item.componentInfo.visible == 1}}">
<notice datas="{{item}}"></notice>
</block>
<block wx:elif="{{item.componentCode=='pop-up' && item.componentInfo.visible == 1}}">
<pop-up datas="{{item}}"></pop-up>
</block>
<block wx:elif="{{item.componentCode=='coupon' && item.componentInfo.visible == 1}}">
<coupon datas="{{item}}"></coupon>
</block>
<block wx:elif="{{item.componentCode=='integral-turntable' && item.componentInfo.visible == 1}}">
<integralTurntable datas="{{item}}"></integralTurntable>
</block>
<block wx:elif="{{item.componentCode=='speedy-nav' && item.componentInfo.visible == 1}}">
<speedy-nav datas="{{item}}"></speedy-nav>
</block>
<block wx:elif="{{item.componentCode=='video-player' && item.componentInfo.visible == 1}}">
<video-player datas="{{item}}" :indexs="index"></video-player>
</block>
<block wx:elif="{{item.componentCode=='official-account' && item.componentInfo.visible == 1}}">
<official-account></official-account>
</block>
</block>
</view>
const componentOptions = {
// 组件选项
options: {
multipleSlots: true,
styleIsolation: "shared"
},
behaviors: [],
properties: {
datas: {
type: Object
}
},
// 组件数据
data: {
isPageHidden: false, // 页面是否处于隐藏状态
active: 0
},
// 数据监听器
observers: {},
// 组件方法
methods: {
init() {},
onChange(event) {}
},
// 组件生命周期
lifetimes: {
created() {},
attached() {
this.init();
},
ready() {},
moved() {},
detached() {}
},
definitionFilter() {},
// 页面生命周期
pageLifetimes: {
// 页面被展示
show() {
const { isPageHidden } = this.data;
// show事件发生前,页面不是处于隐藏状态时
if (!isPageHidden) {
return;
}
// 重新执行定时器等操作
},
// 页面被隐藏
hide() {
this.setData({
isPageHidden: true
});
// 清除定时器等操作
},
// 页面尺寸变化时
resize() {}
}
};
Component(componentOptions)
{
"component": true,
"usingComponents": {
"van-tabs":"/static/vant/tabs/index",
"van-tab":"/static/vant/tab/index",
"components-list":"./ComponentsList/index"
}
}
<view class="TransverseLabel" style="--defaultTabTextColor:{{datas.componentData.defaultTabTextColor}};--defaultTabTextSize:{{datas.componentData.defaultTabTextSize*2}}rpx;--defaultTabBackgroundColor:{{datas.componentData.defaultTabBackgroundColor}};--defaultTabUnderlineColor:{{datas.componentData.defaultTabUnderlineColor}};--selectTabTextColor:{{datas.componentData.selectTabTextColor}};--selectTabTextSize:{{datas.componentData.selectTabTextSize*2}}rpx;--selectTabBackgroundColor:{{datas.componentData.selectTabBackgroundColor}};--selectTabUnderlineColor:{{datas.componentData.selectTabUnderlineColor}};--tabBackgroundColor:{{datas.componentData.tabBackgroundColor}};">
<van-tabs
custom-class="vanTabs {{datas.componentData.tabStyle==1?'tabStyle1':'tabStyle2'}}"
nav-class="tabNav tabLayout{{datas.componentData.tabLayout}}"
tab-class="vanTab"
tab-active-class="vanActiveTab"
active="{{ active }}"
animated="{{true}}"
sticky="{{datas.componentData.stickyTop}}"
swipeable="{{true}}"
bind:change="onChange"
line-width="{{50}}"
color="{{'#333'}}"
>
<van-tab
title="{{item.title}}"
wx:for="{{datas.componentData.tabList}}"
wx:if="{{item.visible==undefined||item.visible==1}}"
>
<components-list datas="{{item.contentList}}"></components-list>
</van-tab>
</van-tabs>
</view>
.vanTabs{
position: relative;
}
.vanTab .van-ellipsis{
padding: 0 20rpx;
margin: 0 12rpx;
}
.van-tab {
position: relative;
z-index: 98;
}
/* 样式1 */
.tabStyle1 .van-tabs__line {
width: 100%;
height: 30px;
bottom: 7px;
border-radius: 38px;
}
.tabStyle1 .tabTitle {
color: var(--main-color);
}
.tabStyle1 .selectTitle {
color: #fff;
}
.tabStyle1 .defaultTabTextSize {
font-size: var(--defaultTabTextSize);
}
.tabStyle1 .defaultTabTextColor {
color: var(--defaultTabTextColor);
}
.tabStyle1 .selectTabTextSize {
font-size: var(--selectTabTextSize);
}
.tabStyle1 .selectTabTextColor {
color: var(--selectTabTextColor);
}
/* 样式2 */
.tabStyle2 .van-tabs__line{
}
/* 标签背景色 */
.tabNav {
background: var(--tabBackgroundColor);
}
/* 布局 */
.tabLayout1 .van-tab{
flex: none;
}
.tabLayout2{
justify-content: center;
}
.tabLayout2 .van-tab{
flex: none;
}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
props: {
title: String,
border: {
type: Boolean,
value: true,
},
},
});
<view
wx:if="{{ title }}"
class="van-cell-group__title"
>
{{ title }}
</view>
<view class="custom-class van-cell-group {{ border ? 'van-hairline--top-bottom' : '' }}">
<slot />
</view>
@import '../common/index.wxss';.van-cell-group__title{padding:16px 16px 8px;padding:var(--cell-group-title-padding,16px 16px 8px);font-size:14px;font-size:var(--cell-group-title-font-size,14px);line-height:16px;line-height:var(--cell-group-title-line-height,16px);color:#969799;color:var(--cell-group-title-color,#969799)}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'row',
type: 'ancestor',
current: 'col',
},
props: {
span: Number,
offset: Number,
},
data: {
viewStyle: '',
},
methods: {
setGutter(gutter) {
const padding = `${gutter / 2}px`;
const viewStyle = gutter
? `padding-left: ${padding}; padding-right: ${padding};`
: '';
if (viewStyle !== this.data.viewStyle) {
this.setData({ viewStyle });
}
},
},
});
<wxs src="../wxs/utils.wxs" module="utils" />
<view
class="custom-class {{ utils.bem('col', [span]) }} {{ offset ? 'van-col--offset-' + offset : '' }}"
style="{{ viewStyle }}"
>
<slot />
</view>
@import '../common/index.wxss';.van-col{float:left;box-sizing:border-box}.van-col--1{width:4.16666667%}.van-col--offset-1{margin-left:4.16666667%}.van-col--2{width:8.33333333%}.van-col--offset-2{margin-left:8.33333333%}.van-col--3{width:12.5%}.van-col--offset-3{margin-left:12.5%}.van-col--4{width:16.66666667%}.van-col--offset-4{margin-left:16.66666667%}.van-col--5{width:20.83333333%}.van-col--offset-5{margin-left:20.83333333%}.van-col--6{width:25%}.van-col--offset-6{margin-left:25%}.van-col--7{width:29.16666667%}.van-col--offset-7{margin-left:29.16666667%}.van-col--8{width:33.33333333%}.van-col--offset-8{margin-left:33.33333333%}.van-col--9{width:37.5%}.van-col--offset-9{margin-left:37.5%}.van-col--10{width:41.66666667%}.van-col--offset-10{margin-left:41.66666667%}.van-col--11{width:45.83333333%}.van-col--offset-11{margin-left:45.83333333%}.van-col--12{width:50%}.van-col--offset-12{margin-left:50%}.van-col--13{width:54.16666667%}.van-col--offset-13{margin-left:54.16666667%}.van-col--14{width:58.33333333%}.van-col--offset-14{margin-left:58.33333333%}.van-col--15{width:62.5%}.van-col--offset-15{margin-left:62.5%}.van-col--16{width:66.66666667%}.van-col--offset-16{margin-left:66.66666667%}.van-col--17{width:70.83333333%}.van-col--offset-17{margin-left:70.83333333%}.van-col--18{width:75%}.van-col--offset-18{margin-left:75%}.van-col--19{width:79.16666667%}.van-col--offset-19{margin-left:79.16666667%}.van-col--20{width:83.33333333%}.van-col--offset-20{margin-left:83.33333333%}.van-col--21{width:87.5%}.van-col--offset-21{margin-left:87.5%}.van-col--22{width:91.66666667%}.van-col--offset-22{margin-left:91.66666667%}.van-col--23{width:95.83333333%}.van-col--offset-23{margin-left:95.83333333%}.van-col--24{width:100%}.van-col--offset-24{margin-left:100%}
\ No newline at end of file
/// <reference types="miniprogram-api-typings" />
export declare function setContentAnimate(
context: WechatMiniprogram.Component.TrivialInstance,
expanded: boolean,
mounted: boolean
): void;
import { canIUseAnimate } from '../common/version';
import { getRect } from '../common/utils';
function useAnimate(context, expanded, mounted, height) {
const selector = '.van-collapse-item__wrapper';
if (expanded) {
context.animate(
selector,
[
{ height: 0, ease: 'ease-in-out', offset: 0 },
{ height: `${height}px`, ease: 'ease-in-out', offset: 1 },
{ height: `auto`, ease: 'ease-in-out', offset: 1 },
],
mounted ? 300 : 0,
() => {
context.clearAnimation(selector);
}
);
return;
}
context.animate(
selector,
[
{ height: `${height}px`, ease: 'ease-in-out', offset: 0 },
{ height: 0, ease: 'ease-in-out', offset: 1 },
],
300,
() => {
context.clearAnimation(selector);
}
);
}
function useAnimation(context, expanded, mounted, height) {
const animation = wx.createAnimation({
duration: 0,
timingFunction: 'ease-in-out',
});
if (expanded) {
if (height === 0) {
animation.height('auto').top(1).step();
} else {
animation
.height(height)
.top(1)
.step({
duration: mounted ? 300 : 1,
})
.height('auto')
.step();
}
context.setData({
animation: animation.export(),
});
return;
}
animation.height(height).top(0).step({ duration: 1 }).height(0).step({
duration: 300,
});
context.setData({
animation: animation.export(),
});
}
export function setContentAnimate(context, expanded, mounted) {
getRect(context, '.van-collapse-item__content')
.then((rect) => rect.height)
.then((height) => {
canIUseAnimate()
? useAnimate(context, expanded, mounted, height)
: useAnimation(context, expanded, mounted, height);
});
}
import { VantComponent } from '../common/component';
import { setContentAnimate } from './animate';
VantComponent({
classes: ['title-class', 'content-class'],
relation: {
name: 'collapse',
type: 'ancestor',
current: 'collapse-item',
},
props: {
name: null,
title: null,
value: null,
icon: String,
label: String,
disabled: Boolean,
clickable: Boolean,
border: {
type: Boolean,
value: true,
},
isLink: {
type: Boolean,
value: true,
},
},
data: {
expanded: false,
},
mounted() {
this.updateExpanded();
this.mounted = true;
},
methods: {
updateExpanded() {
if (!this.parent) {
return;
}
const { value, accordion } = this.parent.data;
const { children = [] } = this.parent;
const { name } = this.data;
const index = children.indexOf(this);
const currentName = name == null ? index : name;
const expanded = accordion
? value === currentName
: (value || []).some((name) => name === currentName);
if (expanded !== this.data.expanded) {
setContentAnimate(this, expanded, this.mounted);
}
this.setData({ index, expanded });
},
onClick() {
if (this.data.disabled) {
return;
}
const { name, expanded } = this.data;
const index = this.parent.children.indexOf(this);
const currentName = name == null ? index : name;
this.parent.switch(currentName, !expanded);
},
},
});
{
"component": true,
"usingComponents": {
"van-cell": "../cell/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="van-collapse-item custom-class {{ index !== 0 ? 'van-hairline--top' : '' }}">
<van-cell
title="{{ title }}"
title-class="title-class"
icon="{{ icon }}"
value="{{ value }}"
label="{{ label }}"
is-link="{{ isLink }}"
clickable="{{ clickable }}"
border="{{ border && expanded }}"
class="{{ utils.bem('collapse-item__title', { disabled, expanded }) }}"
right-icon-class="van-cell__right-icon"
custom-class="van-cell"
hover-class="van-cell--hover"
bind:click="onClick"
>
<slot
name="title"
slot="title"
/>
<slot
name="icon"
slot="icon"
/>
<slot name="value" />
<slot
name="right-icon"
slot="right-icon"
/>
</van-cell>
<view
class="{{ utils.bem('collapse-item__wrapper') }}"
style="height: 0;"
animation="{{ animation }}"
>
<view
class="van-collapse-item__content content-class"
>
<slot />
</view>
</view>
</view>
@import '../common/index.wxss';.van-collapse-item__title .van-cell__right-icon{-webkit-transform:rotate(90deg);transform:rotate(90deg);transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;transition:-webkit-transform var(--collapse-item-transition-duration,.3s);transition:transform var(--collapse-item-transition-duration,.3s);transition:transform var(--collapse-item-transition-duration,.3s),-webkit-transform var(--collapse-item-transition-duration,.3s)}.van-collapse-item__title--expanded .van-cell__right-icon{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.van-collapse-item__title--disabled .van-cell,.van-collapse-item__title--disabled .van-cell__right-icon{color:#c8c9cc!important;color:var(--collapse-item-title-disabled-color,#c8c9cc)!important}.van-collapse-item__title--disabled .van-cell--hover{background-color:#fff!important;background-color:var(--white,#fff)!important}.van-collapse-item__wrapper{overflow:hidden}.van-collapse-item__content{padding:15px;padding:var(--collapse-item-content-padding,15px);color:#969799;color:var(--collapse-item-content-text-color,#969799);font-size:13px;font-size:var(--collapse-item-content-font-size,13px);line-height:1.5;line-height:var(--collapse-item-content-line-height,1.5);background-color:#fff;background-color:var(--collapse-item-content-background-color,#fff)}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'collapse-item',
type: 'descendant',
current: 'collapse',
},
props: {
value: {
type: null,
observer: 'updateExpanded',
},
accordion: {
type: Boolean,
observer: 'updateExpanded',
},
border: {
type: Boolean,
value: true,
},
},
methods: {
updateExpanded() {
this.children.forEach((child) => {
child.updateExpanded();
});
},
switch(name, expanded) {
const { accordion, value } = this.data;
const changeItem = name;
if (!accordion) {
name = expanded
? (value || []).concat(name)
: (value || []).filter((activeName) => activeName !== name);
} else {
name = expanded ? name : '';
}
if (expanded) {
this.$emit('open', changeItem);
} else {
this.$emit('close', changeItem);
}
this.$emit('change', name);
this.$emit('input', name);
},
},
});
<view class="custom-class van-collapse {{ border ? 'van-hairline--top-bottom' : '' }}">
<slot />
</view>
@import '../common/index.wxss';
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
props: {
dashed: {
type: Boolean,
value: false,
},
hairline: {
type: Boolean,
value: false,
},
contentPosition: {
type: String,
value: '',
},
fontSize: {
type: Number,
value: '',
},
borderColor: {
type: String,
value: '',
},
textColor: {
type: String,
value: '',
},
customStyle: {
type: String,
value: '',
},
},
});
{
"component": true,
"usingComponents": {}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<view
class="custom-class {{ utils.bem('divider', [{dashed, hairline}, contentPosition]) }}"
style="{{ borderColor ? 'border-color: ' + borderColor + ';' : '' }}{{ textColor ? 'color: ' + textColor + ';' : '' }} {{ fontSize ? 'font-size: ' + fontSize + 'px;' : '' }} {{ customStyle }}"
>
<slot />
</view>
@import '../common/index.wxss';.van-divider{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;margin:16px 0;margin:var(--divider-margin,16px 0);color:#969799;color:var(--divider-text-color,#969799);font-size:14px;font-size:var(--divider-font-size,14px);line-height:24px;line-height:var(--divider-line-height,24px);border:0 solid #ebedf0;border-color:var(--divider-border-color,#ebedf0)}.van-divider:after,.van-divider:before{display:block;-webkit-flex:1;flex:1;box-sizing:border-box;height:1px;border-color:inherit;border-style:inherit;border-width:1px 0 0}.van-divider:before{content:""}.van-divider--hairline:after,.van-divider--hairline:before{-webkit-transform:scaleY(.5);transform:scaleY(.5)}.van-divider--dashed{border-style:dashed}.van-divider--center:before,.van-divider--left:before,.van-divider--right:before{margin-right:16px;margin-right:var(--divider-content-padding,16px)}.van-divider--center:after,.van-divider--left:after,.van-divider--right:after{content:"";margin-left:16px;margin-left:var(--divider-content-padding,16px)}.van-divider--left:before{max-width:10%;max-width:var(--divider-content-left-width,10%)}.van-divider--right:after{max-width:10%;max-width:var(--divider-content-right-width,10%)}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
field: true,
relation: {
name: 'dropdown-menu',
type: 'ancestor',
current: 'dropdown-item',
linked() {
this.updateDataFromParent();
},
},
props: {
value: {
type: null,
observer: 'rerender',
},
title: {
type: String,
observer: 'rerender',
},
disabled: Boolean,
titleClass: {
type: String,
observer: 'rerender',
},
options: {
type: Array,
value: [],
observer: 'rerender',
},
popupStyle: String,
},
data: {
transition: true,
showPopup: false,
showWrapper: false,
displayTitle: '',
},
methods: {
rerender() {
wx.nextTick(() => {
this.parent && this.parent.updateItemListData();
});
},
updateDataFromParent() {
if (this.parent) {
const {
overlay,
duration,
activeColor,
closeOnClickOverlay,
direction,
} = this.parent.data;
this.setData({
overlay,
duration,
activeColor,
closeOnClickOverlay,
direction,
});
}
},
onOpen() {
this.$emit('open');
},
onOpened() {
this.$emit('opened');
},
onClose() {
this.$emit('close');
},
onClosed() {
this.$emit('closed');
this.setData({ showWrapper: false });
},
onOptionTap(event) {
const { option } = event.currentTarget.dataset;
const { value } = option;
const shouldEmitChange = this.data.value !== value;
this.setData({ showPopup: false, value });
this.$emit('close');
this.rerender();
if (shouldEmitChange) {
this.$emit('change', value);
}
},
toggle(show, options = {}) {
const { showPopup } = this.data;
if (typeof show !== 'boolean') {
show = !showPopup;
}
if (show === showPopup) {
return;
}
this.setData({
transition: !options.immediate,
showPopup: show,
});
if (show) {
this.parent.getChildWrapperStyle().then((wrapperStyle) => {
this.setData({ wrapperStyle, showWrapper: true });
this.rerender();
});
} else {
this.rerender();
}
},
},
});
{
"component": true,
"usingComponents": {
"van-popup": "../popup/index",
"van-cell": "../cell/index",
"van-icon": "../icon/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<view
wx:if="{{ showWrapper }}"
class="{{ utils.bem('dropdown-item', direction) }}"
style="{{ wrapperStyle }}"
>
<van-popup
show="{{ showPopup }}"
custom-style="position: absolute;{{ popupStyle }}"
overlay-style="position: absolute;"
overlay="{{ overlay }}"
position="{{ direction === 'down' ? 'top' : 'bottom' }}"
duration="{{ transition ? duration : 0 }}"
close-on-click-overlay="{{ closeOnClickOverlay }}"
bind:enter="onOpen"
bind:leave="onClose"
bind:close="toggle"
bind:after-enter="onOpened"
bind:after-leave="onClosed"
>
<van-cell
wx:for="{{ options }}"
wx:key="value"
data-option="{{ item }}"
class="{{ utils.bem('dropdown-item__option', { active: item.value === value } ) }}"
clickable
icon="{{ item.icon }}"
bind:tap="onOptionTap"
>
<view
slot="title"
class="van-dropdown-item__title"
style="{{ item.value === value ? 'color:' + activeColor : '' }}"
>
{{ item.text }}
</view>
<van-icon
wx:if="{{ item.value === value }}"
name="success"
class="van-dropdown-item__icon"
color="{{ activeColor }}"
/>
</van-cell>
<slot />
</van-popup>
</view>
@import '../common/index.wxss';.van-dropdown-item{position:fixed;right:0;left:0;overflow:hidden}.van-dropdown-item__option{text-align:left}.van-dropdown-item__option--active .van-dropdown-item__icon,.van-dropdown-item__option--active .van-dropdown-item__title{color:#ee0a24;color:var(--dropdown-menu-option-active-color,#ee0a24)}.van-dropdown-item--up{top:0}.van-dropdown-item--down{bottom:0}.van-dropdown-item__icon{display:block;line-height:inherit}
\ No newline at end of file
export interface Option {
text: string;
value: string | number;
icon: string;
}
import { VantComponent } from '../common/component';
import { addUnit, getRect, getSystemInfoSync } from '../common/utils';
let ARRAY = [];
VantComponent({
field: true,
relation: {
name: 'dropdown-item',
type: 'descendant',
current: 'dropdown-menu',
linked() {
this.updateItemListData();
},
unlinked() {
this.updateItemListData();
},
},
props: {
activeColor: {
type: String,
observer: 'updateChildrenData',
},
overlay: {
type: Boolean,
value: true,
observer: 'updateChildrenData',
},
zIndex: {
type: Number,
value: 10,
},
duration: {
type: Number,
value: 200,
observer: 'updateChildrenData',
},
direction: {
type: String,
value: 'down',
observer: 'updateChildrenData',
},
closeOnClickOverlay: {
type: Boolean,
value: true,
observer: 'updateChildrenData',
},
closeOnClickOutside: {
type: Boolean,
value: true,
},
},
data: {
itemListData: [],
},
beforeCreate() {
const { windowHeight } = getSystemInfoSync();
this.windowHeight = windowHeight;
ARRAY.push(this);
},
destroyed() {
ARRAY = ARRAY.filter((item) => item !== this);
},
methods: {
updateItemListData() {
this.setData({
itemListData: this.children.map((child) => child.data),
});
},
updateChildrenData() {
this.children.forEach((child) => {
child.updateDataFromParent();
});
},
toggleItem(active) {
this.children.forEach((item, index) => {
const { showPopup } = item.data;
if (index === active) {
item.toggle();
} else if (showPopup) {
item.toggle(false, { immediate: true });
}
});
},
close() {
this.children.forEach((child) => {
child.toggle(false, { immediate: true });
});
},
getChildWrapperStyle() {
const { zIndex, direction } = this.data;
return getRect(this, '.van-dropdown-menu').then((rect) => {
const { top = 0, bottom = 0 } = rect;
const offset = direction === 'down' ? bottom : this.windowHeight - top;
let wrapperStyle = `z-index: ${zIndex};`;
if (direction === 'down') {
wrapperStyle += `top: ${addUnit(offset)};`;
} else {
wrapperStyle += `bottom: ${addUnit(offset)};`;
}
return wrapperStyle;
});
},
onTitleTap(event) {
const { index } = event.currentTarget.dataset;
const child = this.children[index];
if (!child.data.disabled) {
ARRAY.forEach((menuItem) => {
if (
menuItem &&
menuItem.data.closeOnClickOutside &&
menuItem !== this
) {
menuItem.close();
}
});
this.toggleItem(index);
}
},
},
});
<wxs src="../wxs/utils.wxs" module="utils" />
<wxs src="./index.wxs" module="computed" />
<view class="van-dropdown-menu van-dropdown-menu--top-bottom">
<view
wx:for="{{ itemListData }}"
wx:key="index"
data-index="{{ index }}"
class="{{ utils.bem('dropdown-menu__item', { disabled: item.disabled }) }}"
bind:tap="onTitleTap"
>
<view
class="{{ item.titleClass }} {{ utils.bem('dropdown-menu__title', { active: item.showPopup, down: item.showPopup === (direction === 'down') }) }}"
style="{{ item.showPopup ? 'color:' + activeColor : '' }}"
>
<view class="van-ellipsis">
{{ computed.displayTitle(item) }}
</view>
</view>
</view>
<slot />
</view>
/* eslint-disable */
function displayTitle(item) {
if (item.title) {
return item.title;
}
var match = item.options.filter(function(option) {
return option.value === item.value;
});
var displayTitle = match.length ? match[0].text : '';
return displayTitle;
}
module.exports = {
displayTitle: displayTitle
};
@import '../common/index.wxss';.van-dropdown-menu{display:-webkit-flex;display:flex;box-shadow:0 2px 12px rgba(100,101,102,.12);-webkit-user-select:none;user-select:none;height:50px;height:var(--dropdown-menu-height,50px);background-color:#fff;background-color:var(--dropdown-menu-background-color,#fff)}.van-dropdown-menu__item{display:-webkit-flex;display:flex;-webkit-flex:1;flex:1;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;min-width:0}.van-dropdown-menu__item:active{opacity:.7}.van-dropdown-menu__item--disabled:active{opacity:1}.van-dropdown-menu__item--disabled .van-dropdown-menu__title{color:#969799;color:var(--dropdown-menu-title-disabled-text-color,#969799)}.van-dropdown-menu__title{position:relative;box-sizing:border-box;max-width:100%;padding:0 8px;padding:var(--dropdown-menu-title-padding,0 8px);color:#323233;color:var(--dropdown-menu-title-text-color,#323233);font-size:15px;font-size:var(--dropdown-menu-title-font-size,15px);line-height:18px;line-height:var(--dropdown-menu-title-line-height,18px)}.van-dropdown-menu__title:after{position:absolute;top:50%;right:-4px;margin-top:-5px;border-color:transparent transparent currentcolor currentcolor;border-style:solid;border-width:3px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:.8;content:""}.van-dropdown-menu__title--active{color:#ee0a24;color:var(--dropdown-menu-title-active-text-color,#ee0a24)}.van-dropdown-menu__title--down:after{margin-top:-1px;-webkit-transform:rotate(135deg);transform:rotate(135deg)}
\ No newline at end of file
import { VantComponent } from '../common/component';
const PRESETS = ['error', 'search', 'default', 'network'];
VantComponent({
props: {
description: String,
image: {
type: String,
value: 'default',
},
},
created() {
if (PRESETS.indexOf(this.data.image) !== -1) {
this.setData({
imageUrl: `https://img.yzcdn.cn/vant/empty-image-${this.data.image}.png`,
});
} else {
this.setData({ imageUrl: this.data.image });
}
},
});
{
"component": true,
"usingComponents": {}
}
\ No newline at end of file
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="custom-class van-empty">
<view class="van-empty__image">
<slot name="image"></slot>
</view>
<view class="van-empty__image">
<image wx:if="{{ imageUrl }}" class="van-empty__image__img" src="{{ imageUrl }}" />
</view>
<view class="van-empty__description">
<slot name="description"></slot>
</view>
<view class="van-empty__description">
{{ description }}
</view>
<view class="van-empty__bottom">
<slot></slot>
</view>
</view>
@import '../common/index.wxss';.van-empty{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;padding:32px 0}.van-empty__image{width:160px;height:160px}.van-empty__image:empty{display:none}.van-empty__image__img{width:100%;height:100%}.van-empty__image:not(:empty)+.van-empty__image{display:none}.van-empty__description{margin-top:16px;padding:0 60px;color:#969799;font-size:14px;line-height:20px}.van-empty__description:empty,.van-empty__description:not(:empty)+.van-empty__description{display:none}.van-empty__bottom{margin-top:24px}
\ No newline at end of file
import { VantComponent } from '../common/component';
import { button } from '../mixins/button';
import { openType } from '../mixins/open-type';
VantComponent({
mixins: [button, openType],
classes: ['custom-class', 'loading-class', 'error-class', 'image-class'],
props: {
src: {
type: String,
observer() {
this.setData({
error: false,
loading: true,
});
},
},
round: Boolean,
width: null,
height: null,
radius: null,
lazyLoad: Boolean,
useErrorSlot: Boolean,
useLoadingSlot: Boolean,
showMenuByLongpress: Boolean,
fit: {
type: String,
value: 'fill',
},
showError: {
type: Boolean,
value: true,
},
showLoading: {
type: Boolean,
value: true,
},
},
data: {
error: false,
loading: true,
viewStyle: '',
},
methods: {
onLoad(event) {
this.setData({
loading: false,
});
this.$emit('load', event.detail);
},
onError(event) {
this.setData({
loading: false,
error: true,
});
this.$emit('error', event.detail);
},
onClick(event) {
this.$emit('click', event.detail);
},
},
});
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-loading": "../loading/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<wxs src="./index.wxs" module="computed" />
<view
style="{{ computed.rootStyle({ width, height, radius }) }}"
class="custom-class {{ utils.bem('image', { round })}}"
bind:tap="onClick"
>
<image
wx:if="{{ !error }}"
src="{{ src }}"
mode="{{ computed.mode(fit) }}"
lazy-load="{{ lazyLoad }}"
class="image-class van-image__img"
show-menu-by-longpress="{{ showMenuByLongpress }}"
bind:load="onLoad"
bind:error="onError"
/>
<view
wx:if="{{ loading && showLoading }}"
class="loading-class van-image__loading"
>
<slot wx:if="{{ useLoadingSlot }}" name="loading" />
<van-icon wx:else name="photo" custom-class="van-image__loading-icon" />
</view>
<view
wx:if="{{ error && showError }}"
class="error-class van-image__error"
>
<slot wx:if="{{ useErrorSlot }}" name="error" />
<van-icon wx:else name="photo-fail" custom-class="van-image__error-icon" />
</view>
</view>
/* eslint-disable */
var style = require('../wxs/style.wxs');
var addUnit = require('../wxs/add-unit.wxs');
function rootStyle(data) {
return style([
{
width: addUnit(data.width),
height: addUnit(data.height),
'border-radius': addUnit(data.radius),
},
data.radius ? 'overflow: hidden' : null,
]);
}
var FIT_MODE_MAP = {
none: 'center',
fill: 'scaleToFill',
cover: 'aspectFill',
contain: 'aspectFit',
widthFix: 'widthFix',
heightFix: 'heightFix',
};
function mode(fit) {
return FIT_MODE_MAP[fit];
}
module.exports = {
rootStyle: rootStyle,
mode: mode,
};
@import '../common/index.wxss';.van-image{position:relative;display:inline-block}.van-image--round{overflow:hidden;border-radius:50%}.van-image--round .van-image__img{border-radius:inherit}.van-image__error,.van-image__img,.van-image__loading{display:block;width:100%;height:100%}.van-image__error,.van-image__loading{position:absolute;top:0;left:0;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;color:#969799;color:var(--image-placeholder-text-color,#969799);font-size:14px;font-size:var(--image-placeholder-font-size,14px);background-color:#f7f8fa;background-color:var(--image-placeholder-background-color,#f7f8fa)}.van-image__loading-icon{color:#dcdee0;color:var(--image-loading-icon-color,#dcdee0);font-size:32px!important;font-size:var(--image-loading-icon-size,32px)!important}.van-image__error-icon{color:#dcdee0;color:var(--image-error-icon-color,#dcdee0);font-size:32px!important;font-size:var(--image-error-icon-size,32px)!important}
\ No newline at end of file
import { getRect } from '../common/utils';
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'index-bar',
type: 'ancestor',
current: 'index-anchor',
},
props: {
useSlot: Boolean,
index: null,
},
data: {
active: false,
wrapperStyle: '',
anchorStyle: '',
},
methods: {
scrollIntoView(scrollTop) {
getRect(this, '.van-index-anchor-wrapper').then((rect) => {
wx.pageScrollTo({
duration: 0,
scrollTop: scrollTop + rect.top - this.parent.data.stickyOffsetTop,
});
});
},
},
});
<view
class="van-index-anchor-wrapper"
style="{{ wrapperStyle }}"
>
<view
class="van-index-anchor {{ active ? 'van-index-anchor--active van-hairline--bottom' : '' }}"
style="{{ anchorStyle }}"
>
<slot wx:if="{{ useSlot }}"/>
<block wx:else>
<text>{{ index }}</text>
</block>
</view>
</view>
@import '../common/index.wxss';.van-index-anchor{padding:0 16px;padding:var(--index-anchor-padding,0 16px);color:#323233;color:var(--index-anchor-text-color,#323233);font-weight:500;font-weight:var(--index-anchor-font-weight,500);font-size:14px;font-size:var(--index-anchor-font-size,14px);line-height:32px;line-height:var(--index-anchor-line-height,32px);background-color:initial;background-color:var(--index-anchor-background-color,transparent)}.van-index-anchor--active{right:0;left:0;color:#07c160;color:var(--index-anchor-active-text-color,#07c160);background-color:#fff;background-color:var(--index-anchor-active-background-color,#fff)}
\ No newline at end of file
import { VantComponent } from '../common/component';
import { getRect, getSystemInfoSync } from '../common/utils';
VantComponent({
classes: ['title-class'],
props: {
title: String,
fixed: {
type: Boolean,
observer: 'setHeight',
},
placeholder: {
type: Boolean,
observer: 'setHeight',
},
leftText: String,
rightText: String,
customStyle: String,
leftArrow: Boolean,
border: {
type: Boolean,
value: true,
},
zIndex: {
type: Number,
value: 1,
},
safeAreaInsetTop: {
type: Boolean,
value: true,
},
},
data: {
height: 46,
},
created() {
const { statusBarHeight } = getSystemInfoSync();
this.setData({
statusBarHeight,
height: 46 + statusBarHeight,
});
},
mounted() {
this.setHeight();
},
methods: {
onClickLeft() {
this.$emit('click-left');
},
onClickRight() {
this.$emit('click-right');
},
setHeight() {
if (!this.data.fixed || !this.data.placeholder) {
return;
}
wx.nextTick(() => {
getRect(this, '.van-nav-bar').then((res) => {
if (res && 'height' in res) {
this.setData({ height: res.height });
}
});
});
},
},
});
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<wxs src="./index.wxs" module="computed" />
<view wx:if="{{ fixed && placeholder }}" style="height: {{ height }}px;" />
<view
class="{{ utils.bem('nav-bar', { fixed }) }} custom-class {{ border ? 'van-hairline--bottom' : '' }}"
style="{{ computed.barStyle({ zIndex, statusBarHeight, safeAreaInsetTop }) }}; {{ customStyle }}"
>
<view class="van-nav-bar__content">
<view class="van-nav-bar__left" bind:tap="onClickLeft">
<block wx:if="{{ leftArrow || leftText }}">
<van-icon
wx:if="{{ leftArrow }}"
size="16px"
name="arrow-left"
custom-class="van-nav-bar__arrow"
/>
<view
wx:if="{{ leftText }}"
class="van-nav-bar__text"
hover-class="van-nav-bar__text--hover"
hover-stay-time="70"
>{{ leftText }}</view>
</block>
<slot wx:else name="left" />
</view>
<view class="van-nav-bar__title title-class van-ellipsis">
<block wx:if="{{ title }}">{{ title }}</block>
<slot wx:else name="title" />
</view>
<view class="van-nav-bar__right" bind:tap="onClickRight">
<view
wx:if="{{ rightText }}"
class="van-nav-bar__text"
hover-class="van-nav-bar__text--hover"
hover-stay-time="70"
>{{ rightText }}</view>
<slot wx:else name="right" />
</view>
</view>
</view>
/* eslint-disable */
var style = require('../wxs/style.wxs');
function barStyle(data) {
return style({
'z-index': data.zIndex,
'padding-top': data.safeAreaInsetTop ? data.statusBarHeight + 'px' : 0,
});
}
module.exports = {
barStyle: barStyle,
};
@import '../common/index.wxss';.van-nav-bar{position:relative;text-align:center;-webkit-user-select:none;user-select:none;height:46px;height:var(--nav-bar-height,46px);line-height:46px;line-height:var(--nav-bar-height,46px);background-color:#fff;background-color:var(--nav-bar-background-color,#fff)}.van-nav-bar__content{position:relative;height:100%}.van-nav-bar__text{display:inline-block;vertical-align:middle;margin:0 -16px;margin:0 -var(--padding-md,16px);padding:0 16px;padding:0 var(--padding-md,16px);color:#1989fa;color:var(--nav-bar-text-color,#1989fa)}.van-nav-bar__text--hover{background-color:#f2f3f5;background-color:var(--active-color,#f2f3f5)}.van-nav-bar__arrow{vertical-align:middle;font-size:16px!important;font-size:var(--nav-bar-arrow-size,16px)!important;color:#1989fa!important;color:var(--nav-bar-icon-color,#1989fa)!important}.van-nav-bar__arrow+.van-nav-bar__text{margin-left:-20px;padding-left:25px}.van-nav-bar--fixed{position:fixed;top:0;left:0;width:100%}.van-nav-bar__title{max-width:60%;margin:0 auto;color:#323233;color:var(--nav-bar-title-text-color,#323233);font-weight:500;font-weight:var(--font-weight-bold,500);font-size:16px;font-size:var(--nav-bar-title-font-size,16px)}.van-nav-bar__left,.van-nav-bar__right{position:absolute;top:0;bottom:0;display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;font-size:14px;font-size:var(--font-size-md,14px)}.van-nav-bar__left{left:16px;left:var(--padding-md,16px)}.van-nav-bar__right{right:16px;right:var(--padding-md,16px)}
\ No newline at end of file
import { VantComponent } from '../common/component';
import { getRect, requestAnimationFrame } from '../common/utils';
VantComponent({
props: {
text: {
type: String,
value: '',
observer() {
wx.nextTick(() => {
this.init();
});
},
},
mode: {
type: String,
value: '',
},
url: {
type: String,
value: '',
},
openType: {
type: String,
value: 'navigate',
},
delay: {
type: Number,
value: 1,
},
speed: {
type: Number,
value: 50,
observer() {
wx.nextTick(() => {
this.init();
});
},
},
scrollable: {
type: Boolean,
value: true,
},
leftIcon: {
type: String,
value: '',
},
color: String,
backgroundColor: String,
background: String,
wrapable: Boolean,
},
data: {
show: true,
},
created() {
this.resetAnimation = wx.createAnimation({
duration: 0,
timingFunction: 'linear',
});
},
destroyed() {
this.timer && clearTimeout(this.timer);
},
methods: {
init() {
Promise.all([
getRect(this, '.van-notice-bar__content'),
getRect(this, '.van-notice-bar__wrap'),
]).then((rects) => {
const [contentRect, wrapRect] = rects;
if (
contentRect == null ||
wrapRect == null ||
!contentRect.width ||
!wrapRect.width
) {
return;
}
const { speed, scrollable, delay } = this.data;
if (scrollable || wrapRect.width < contentRect.width) {
const duration = (contentRect.width / speed) * 1000;
this.wrapWidth = wrapRect.width;
this.contentWidth = contentRect.width;
this.duration = duration;
this.animation = wx.createAnimation({
duration,
timingFunction: 'linear',
delay,
});
this.scroll();
}
});
},
scroll() {
this.timer && clearTimeout(this.timer);
this.timer = null;
this.setData({
animationData: this.resetAnimation
.translateX(this.wrapWidth)
.step()
.export(),
});
requestAnimationFrame(() => {
this.setData({
animationData: this.animation
.translateX(-this.contentWidth)
.step()
.export(),
});
});
this.timer = setTimeout(() => {
this.scroll();
}, this.duration);
},
onClickIcon(event) {
if (this.data.mode === 'closeable') {
this.timer && clearTimeout(this.timer);
this.timer = null;
this.setData({ show: false });
this.$emit('close', event.detail);
}
},
onClick(event) {
this.$emit('click', event);
},
},
});
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<view
wx:if="{{ show }}"
class="custom-class {{ utils.bem('notice-bar', { withicon: mode, wrapable }) }}"
style="color: {{ color }}; background-color: {{ backgroundColor }}; background: {{ background }}"
bind:tap="onClick"
>
<van-icon
wx:if="{{ leftIcon }}"
size="16px"
name="{{ leftIcon }}"
class="van-notice-bar__left-icon"
/>
<slot wx:else name="left-icon" />
<view class="van-notice-bar__wrap">
<view class="van-notice-bar__content {{ !scrollable && !wrapable ? 'van-ellipsis' : '' }}" animation="{{ animationData }}">
{{ text }}
</view>
</view>
<van-icon
wx:if="{{ mode === 'closeable' }}"
class="van-notice-bar__right-icon"
name="cross"
catch:tap="onClickIcon"
/>
<navigator
wx:elif="{{ mode === 'link' }}"
url="{{ url }}"
open-type="{{ openType }}"
>
<van-icon class="van-notice-bar__right-icon" name="arrow" />
</navigator>
<slot wx:else name="right-icon" />
</view>
@import '../common/index.wxss';.van-notice-bar{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;height:40px;height:var(--notice-bar-height,40px);padding:0 16px;padding:var(--notice-bar-padding,0 16px);font-size:14px;font-size:var(--notice-bar-font-size,14px);color:#ed6a0c;color:var(--notice-bar-text-color,#ed6a0c);line-height:24px;line-height:var(--notice-bar-line-height,24px);background-color:#fffbe8;background-color:var(--notice-bar-background-color,#fffbe8)}.van-notice-bar--withicon{position:relative;padding-right:40px}.van-notice-bar--wrapable{height:auto;padding:8px 16px;padding:var(--notice-bar-wrapable-padding,8px 16px)}.van-notice-bar--wrapable .van-notice-bar__wrap{height:auto}.van-notice-bar--wrapable .van-notice-bar__content{position:relative;white-space:normal}.van-notice-bar__left-icon{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;margin-right:4px;vertical-align:middle}.van-notice-bar__left-icon,.van-notice-bar__right-icon{font-size:16px;font-size:var(--notice-bar-icon-size,16px);min-width:22px;min-width:var(--notice-bar-icon-min-width,22px)}.van-notice-bar__right-icon{position:absolute;top:10px;right:15px}.van-notice-bar__wrap{position:relative;-webkit-flex:1;flex:1;overflow:hidden;height:24px;height:var(--notice-bar-line-height,24px)}.van-notice-bar__content{position:absolute;white-space:nowrap}.van-notice-bar__content.van-ellipsis{max-width:100%}
\ No newline at end of file
import { VantComponent } from '../common/component';
import { WHITE } from '../common/color';
import { getSystemInfoSync } from '../common/utils';
VantComponent({
props: {
message: String,
background: String,
type: {
type: String,
value: 'danger',
},
color: {
type: String,
value: WHITE,
},
duration: {
type: Number,
value: 3000,
},
zIndex: {
type: Number,
value: 110,
},
safeAreaInsetTop: {
type: Boolean,
value: false,
},
top: null,
},
data: {
show: false,
},
created() {
const { statusBarHeight } = getSystemInfoSync();
this.setData({ statusBarHeight });
},
methods: {
show() {
const { duration, onOpened } = this.data;
clearTimeout(this.timer);
this.setData({ show: true });
wx.nextTick(onOpened);
if (duration > 0 && duration !== Infinity) {
this.timer = setTimeout(() => {
this.hide();
}, duration);
}
},
hide() {
const { onClose } = this.data;
clearTimeout(this.timer);
this.setData({ show: false });
wx.nextTick(onClose);
},
onTap(event) {
const { onClick } = this.data;
if (onClick) {
onClick(event.detail);
}
},
},
});
{
"component": true,
"usingComponents": {
"van-transition": "../transition/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<van-transition
name="slide-down"
show="{{ show }}"
custom-class="van-notify__container"
custom-style="z-index: {{ zIndex }}; top: {{ utils.addUnit(top) }}"
bind:tap="onTap"
>
<view
class="van-notify van-notify--{{ type }}"
style="background:{{ background }};color:{{ color }};"
>
<view
wx:if="{{ safeAreaInsetTop }}"
style="height: {{ statusBarHeight }}px"
/>
<text>{{ message }}</text>
</view>
</van-transition>
@import '../common/index.wxss';.van-notify{text-align:center;word-wrap:break-word;padding:6px 15px;padding:var(--notify-padding,6px 15px);font-size:14px;font-size:var(--notify-font-size,14px);line-height:20px;line-height:var(--notify-line-height,20px)}.van-notify__container{position:fixed;top:0;left:0;box-sizing:border-box;width:100%}.van-notify--primary{background-color:#1989fa;background-color:var(--notify-primary-background-color,#1989fa)}.van-notify--success{background-color:#07c160;background-color:var(--notify-success-background-color,#07c160)}.van-notify--danger{background-color:#ee0a24;background-color:var(--notify-danger-background-color,#ee0a24)}.van-notify--warning{background-color:#ff976a;background-color:var(--notify-warning-background-color,#ff976a)}
\ No newline at end of file
interface NotifyOptions {
type?: 'primary' | 'success' | 'danger' | 'warning';
color?: string;
zIndex?: number;
top?: number;
message: string;
context?: any;
duration?: number;
selector?: string;
background?: string;
safeAreaInsetTop?: boolean;
onClick?: () => void;
onOpened?: () => void;
onClose?: () => void;
}
declare function Notify(options: NotifyOptions | string): any;
declare namespace Notify {
var clear: (options?: NotifyOptions | undefined) => void;
}
export default Notify;
import { WHITE } from '../common/color';
const defaultOptions = {
selector: '#van-notify',
type: 'danger',
message: '',
background: '',
duration: 3000,
zIndex: 110,
top: 0,
color: WHITE,
safeAreaInsetTop: false,
onClick: () => {},
onOpened: () => {},
onClose: () => {},
};
function parseOptions(message) {
if (message == null) {
return {};
}
return typeof message === 'string' ? { message } : message;
}
function getContext() {
const pages = getCurrentPages();
return pages[pages.length - 1];
}
export default function Notify(options) {
options = Object.assign(
Object.assign({}, defaultOptions),
parseOptions(options)
);
const context = options.context || getContext();
const notify = context.selectComponent(options.selector);
delete options.context;
delete options.selector;
if (notify) {
notify.setData(options);
notify.show();
return notify;
}
console.warn('未找到 van-notify 节点,请确认 selector 及 context 是否正确');
}
Notify.clear = function (options) {
options = Object.assign(
Object.assign({}, defaultOptions),
parseOptions(options)
);
const context = options.context || getContext();
const notify = context.selectComponent(options.selector);
if (notify) {
notify.hide();
}
};
import { VantComponent } from '../common/component';
VantComponent({
classes: ['header-class', 'footer-class'],
props: {
desc: String,
title: String,
status: String,
useFooterSlot: Boolean,
},
});
{
"component": true,
"usingComponents": {
"van-cell": "../cell/index"
}
}
<view class="van-panel van-hairline--top-bottom custom-class">
<van-cell
wx:if="{{ title || desc || status }}"
title="{{ title }}"
label="{{ desc }}"
value="{{ status }}"
custom-class="header-class"
value-class="van-panel__header-value"
/>
<slot wx:else name="header" />
<view class="van-panel__content">
<slot />
</view>
<view wx:if="{{ useFooterSlot }}" class="van-panel__footer van-hairline--top footer-class">
<slot name="footer" />
</view>
</view>
@import '../common/index.wxss';.van-panel{background:#fff;background:var(--panel-background-color,#fff)}.van-panel__header-value{color:#ee0a24;color:var(--panel-header-value-color,#ee0a24)}.van-panel__footer{padding:8px 16px;padding:var(--panel-footer-padding,8px 16px)}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
field: true,
relation: {
name: 'radio',
type: 'descendant',
current: 'radio-group',
linked(target) {
this.updateChild(target);
},
},
props: {
value: {
type: null,
observer: 'updateChildren',
},
disabled: {
type: Boolean,
observer: 'updateChildren',
},
},
methods: {
updateChildren() {
(this.children || []).forEach((child) => this.updateChild(child));
},
updateChild(child) {
const { value, disabled } = this.data;
child.setData({
value,
disabled: disabled || child.data.disabled,
});
},
},
});
@import '../common/index.wxss';
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
field: true,
relation: {
name: 'radio-group',
type: 'ancestor',
current: 'radio',
},
classes: ['icon-class', 'label-class'],
props: {
name: null,
value: null,
disabled: Boolean,
useIconSlot: Boolean,
checkedColor: String,
labelPosition: {
type: String,
value: 'right',
},
labelDisabled: Boolean,
shape: {
type: String,
value: 'round',
},
iconSize: {
type: null,
value: 20,
},
},
methods: {
emitChange(value) {
const instance = this.parent || this;
instance.$emit('input', value);
instance.$emit('change', value);
},
onChange() {
if (!this.data.disabled) {
this.emitChange(this.data.name);
}
},
onClickLabel() {
const { disabled, labelDisabled, name } = this.data;
if (!disabled && !labelDisabled) {
this.emitChange(name);
}
},
},
});
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="van-radio custom-class">
<view
wx:if="{{ labelPosition === 'left' }}"
class="label-class {{ utils.bem('radio__label', [labelPosition, { disabled }]) }}"
bindtap="onClickLabel"
>
<slot />
</view>
<view class="van-radio__icon-wrap" style="font-size: {{ utils.addUnit(iconSize) }};" bindtap="onChange">
<slot wx:if="{{ useIconSlot }}" name="icon" />
<van-icon
wx:else
name="success"
class="{{ utils.bem('radio__icon', [shape, { disabled, checked: value === name }]) }}"
style="font-size: {{ utils.addUnit(iconSize) }};{{ checkedColor && !disabled && value === name ? 'border-color:' + checkedColor + '; background-color:' + checkedColor + ';' : '' }}"
custom-class="icon-class"
custom-style="line-height: {{ utils.addUnit(iconSize) }};font-size: .8em;display: block;"
/>
</view>
<view
wx:if="{{ labelPosition === 'right' }}"
class="label-class {{ utils.bem('radio__label', [labelPosition, { disabled }]) }}"
bindtap="onClickLabel"
>
<slot />
</view>
</view>
@import '../common/index.wxss';.van-radio{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;overflow:hidden;-webkit-user-select:none;user-select:none}.van-radio__icon-wrap{-webkit-flex:none;flex:none}.van-radio__icon{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;width:1em;height:1em;color:transparent;text-align:center;transition-property:color,border-color,background-color;border:1px solid #c8c9cc;border:1px solid var(--radio-border-color,#c8c9cc);font-size:20px;font-size:var(--radio-size,20px);transition-duration:.2s;transition-duration:var(--radio-transition-duration,.2s)}.van-radio__icon--round{border-radius:100%}.van-radio__icon--checked{color:#fff;color:var(--white,#fff);background-color:#1989fa;background-color:var(--radio-checked-icon-color,#1989fa);border-color:#1989fa;border-color:var(--radio-checked-icon-color,#1989fa)}.van-radio__icon--disabled{background-color:#ebedf0;background-color:var(--radio-disabled-background-color,#ebedf0);border-color:#c8c9cc;border-color:var(--radio-disabled-icon-color,#c8c9cc)}.van-radio__icon--disabled.van-radio__icon--checked{color:#c8c9cc;color:var(--radio-disabled-icon-color,#c8c9cc)}.van-radio__label{word-wrap:break-word;margin-left:10px;margin-left:var(--radio-label-margin,10px);color:#323233;color:var(--radio-label-color,#323233);line-height:20px;line-height:var(--radio-size,20px)}.van-radio__label--left{float:left;margin:0 10px 0 0;margin:0 var(--radio-label-margin,10px) 0 0}.van-radio__label--disabled{color:#c8c9cc;color:var(--radio-disabled-label-color,#c8c9cc)}.van-radio__label:empty{margin:0}
\ No newline at end of file
import { getAllRect } from '../common/utils';
import { VantComponent } from '../common/component';
import { canIUseModel } from '../common/version';
VantComponent({
field: true,
classes: ['icon-class'],
props: {
value: {
type: Number,
observer(value) {
if (value !== this.data.innerValue) {
this.setData({ innerValue: value });
}
},
},
readonly: Boolean,
disabled: Boolean,
allowHalf: Boolean,
size: null,
icon: {
type: String,
value: 'star',
},
voidIcon: {
type: String,
value: 'star-o',
},
color: {
type: String,
value: '#ffd21e',
},
voidColor: {
type: String,
value: '#c7c7c7',
},
disabledColor: {
type: String,
value: '#bdbdbd',
},
count: {
type: Number,
value: 5,
observer(value) {
this.setData({ innerCountArray: Array.from({ length: value }) });
},
},
gutter: null,
touchable: {
type: Boolean,
value: true,
},
},
data: {
innerValue: 0,
innerCountArray: Array.from({ length: 5 }),
},
methods: {
onSelect(event) {
const { data } = this;
const { score } = event.currentTarget.dataset;
if (!data.disabled && !data.readonly) {
this.setData({ innerValue: score + 1 });
if (canIUseModel()) {
this.setData({ value: score + 1 });
}
wx.nextTick(() => {
this.$emit('input', score + 1);
this.$emit('change', score + 1);
});
}
},
onTouchMove(event) {
const { touchable } = this.data;
if (!touchable) return;
const { clientX } = event.touches[0];
getAllRect(this, '.van-rate__icon').then((list) => {
const target = list
.sort((item) => item.right - item.left)
.find((item) => clientX >= item.left && clientX <= item.right);
if (target != null) {
this.onSelect(
Object.assign(Object.assign({}, event), { currentTarget: target })
);
}
});
},
},
});
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<view
class="van-rate custom-class"
bind:touchmove="onTouchMove"
>
<view
class="van-rate__item"
wx:for="{{ innerCountArray }}"
wx:key="index"
style="padding-right: {{ index !== count - 1 ? utils.addUnit(gutter) : '' }}"
>
<van-icon
name="{{ index + 1 <= innerValue ? icon : voidIcon }}"
class="van-rate__icon"
style="font-size: {{ utils.addUnit(size) }}"
custom-class="icon-class"
data-score="{{ index }}"
color="{{ disabled ? disabledColor : index + 1 <= innerValue ? color : voidColor }}"
bind:click="onSelect"
/>
<van-icon
wx:if="{{ allowHalf }}"
name="{{ index + 0.5 <= innerValue ? icon : voidIcon }}"
class="{{ utils.bem('rate__icon', ['half']) }}"
style="font-size: {{ utils.addUnit(size) }}"
custom-class="icon-class"
data-score="{{ index - 0.5 }}"
color="{{ disabled ? disabledColor : index + 0.5 <= innerValue ? color : voidColor }}"
bind:click="onSelect"
/>
</view>
</view>
@import '../common/index.wxss';.van-rate{display:-webkit-inline-flex;display:inline-flex;-webkit-user-select:none;user-select:none}.van-rate__item{position:relative;padding:0 2px;padding:0 var(--rate-horizontal-padding,2px)}.van-rate__icon{display:block;height:1em;font-size:20px;font-size:var(--rate-icon-size,20px)}.van-rate__icon--half{position:absolute;top:0;width:.5em;overflow:hidden;left:2px;left:var(--rate-horizontal-padding,2px)}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'col',
type: 'descendant',
current: 'row',
linked(target) {
if (this.data.gutter) {
target.setGutter(this.data.gutter);
}
},
},
props: {
gutter: {
type: Number,
observer: 'setGutter',
},
},
data: {
viewStyle: '',
},
mounted() {
if (this.data.gutter) {
this.setGutter();
}
},
methods: {
setGutter() {
const { gutter } = this.data;
const margin = `-${Number(gutter) / 2}px`;
const viewStyle = gutter
? `margin-right: ${margin}; margin-left: ${margin};`
: '';
this.setData({ viewStyle });
this.getRelationNodes('../col/index').forEach((col) => {
col.setGutter(this.data.gutter);
});
},
},
});
<view class="custom-class van-row" style="{{ viewStyle }}">
<slot />
</view>
@import '../common/index.wxss';.van-row:after{display:table;clear:both;content:""}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
props: {
// whether to show popup
show: Boolean,
// overlay custom style
overlayStyle: Object,
// z-index
zIndex: {
type: Number,
value: 100,
},
title: String,
cancelText: {
type: String,
value: '取消',
},
description: String,
options: {
type: Array,
value: [],
},
overlay: {
type: Boolean,
value: true,
},
safeAreaInsetBottom: {
type: Boolean,
value: true,
},
closeOnClickOverlay: {
type: Boolean,
value: true,
},
duration: {
type: null,
value: 300,
},
},
methods: {
onClickOverlay() {
this.$emit('click-overlay');
},
onCancel() {
this.onClose();
this.$emit('cancel');
},
onSelect(event) {
this.$emit('select', event.detail);
},
onClose() {
this.$emit('close');
},
},
});
{
"component": true,
"usingComponents": {
"van-popup": "../popup/index",
"options": "./options"
}
}
<wxs src="./index.wxs" module="computed" />
<van-popup
round
class="van-share-sheet"
show="{{ show }}"
position="bottom"
overlay="{{ overlay }}"
duration="{{ duration }}"
z-index="{{ zIndex }}"
overlay-style="{{ overlayStyle }}"
close-on-click-overlay="{{ closeOnClickOverlay }}"
safe-area-inset-bottom="{{ safeAreaInsetBottom }}"
bind:close="onClose"
bind:click-overlay="onClickOverlay"
>
<view class="van-share-sheet__header">
<view class="van-share-sheet__title">
<slot name="title" />
</view>
<view wx:if="{{ title }}" class="van-share-sheet__title">{{ title }}</view>
<view class="van-share-sheet__description">
<slot name="description" />
</view>
<view wx:if="{{ description }}" class="van-share-sheet__description">
{{ description }}
</view>
</view>
<block wx:if="{{ computed.isMulti(options) }}">
<options
wx:for="{{ options }}"
show-border="{{ index !== 0 }}"
wx:key="index"
options="{{ item }}"
bind:select="onSelect"
/>
</block>
<options wx:else options="{{ options }}" bind:select="onSelect" />
<button type="button" class="van-share-sheet__cancel" bindtap="onCancel">
{{ cancelText }}
</button>
</van-popup>
/* eslint-disable */
function isMulti(options) {
if (options == null || options[0] == null) {
return false;
}
return "Array" === options.constructor && "Array" === options[0].constructor;
}
module.exports = {
isMulti: isMulti
};
@import '../common/index.wxss';.van-share-sheet__header{padding:12px 16px 4px;text-align:center}.van-share-sheet__title{margin-top:8px;color:#323233;font-weight:400;font-size:14px;line-height:20px}.van-share-sheet__title:empty,.van-share-sheet__title:not(:empty)+.van-share-sheet__title{display:none}.van-share-sheet__description{display:block;margin-top:8px;color:#969799;font-size:12px;line-height:16px}.van-share-sheet__description:empty,.van-share-sheet__description:not(:empty)+.van-share-sheet__description{display:none}.van-share-sheet__cancel{display:block;box-sizing:initial;width:100%;height:auto;padding:0;font-size:16px;line-height:48px;text-align:center;background:#fff;border:none}.van-share-sheet__cancel:before{display:block;height:8px;background-color:#f7f8fa;content:" "}.van-share-sheet__cancel:after{display:none}.van-share-sheet__cancel:active{background-color:#f2f3f5}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
props: {
options: Array,
showBorder: Boolean,
},
methods: {
onSelect(event) {
const { index } = event.currentTarget.dataset;
const option = this.data.options[index];
this.$emit('select', Object.assign(Object.assign({}, option), { index }));
},
},
});
<wxs src="../wxs/utils.wxs" module="utils" />
<wxs src="./options.wxs" module="computed" />
<view class="{{ utils.bem('share-sheet__options', { border: showBorder }) }}">
<view
wx:for="{{ options }}"
wx:key="index"
class="van-share-sheet__option"
data-index="{{ index }}"
bindtap="onSelect"
>
<button class="van-share-sheet__button" open-type="{{ item.openType }}">
<image src="{{ computed.getIconURL(item.icon) }}" class="van-share-sheet__icon" />
</button>
<view wx:if="{{ item.name }}" class="van-share-sheet__name">{{ item.name }}</view>
<view wx:if="{{ item.description }}" class="van-share-sheet__option-description">
{{ item.description }}
</view>
</view>
</view>
/* eslint-disable */
var PRESET_ICONS = ['qq', 'weibo', 'wechat', 'link', 'qrcode', 'poster'];
function getIconURL(icon) {
if (PRESET_ICONS.indexOf(icon) !== -1) {
return 'https://img.yzcdn.cn/vant/share-icon-' + icon + '.png';
}
return icon;
}
module.exports = {
getIconURL: getIconURL,
};
@import '../common/index.wxss';.van-share-sheet__options{position:relative;display:-webkit-flex;display:flex;padding:16px 0 16px 8px;overflow-x:auto;overflow-y:visible;-webkit-overflow-scrolling:touch}.van-share-sheet__options--border:before{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:0;right:0;left:16px;border-top:1px solid #ebedf0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.van-share-sheet__options::-webkit-scrollbar{height:0}.van-share-sheet__option{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-user-select:none;user-select:none}.van-share-sheet__option:active{opacity:.7}.van-share-sheet__button{height:auto;padding:0;line-height:inherit;background-color:initial;border:0}.van-share-sheet__button:after{border:0}.van-share-sheet__icon{width:48px;height:48px;margin:0 16px}.van-share-sheet__name{margin-top:8px;padding:0 4px;color:#646566;font-size:12px}.van-share-sheet__option-description{padding:0 4px;color:#c8c9cc;font-size:12px}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
classes: ['active-class', 'disabled-class'],
relation: {
type: 'ancestor',
name: 'sidebar',
current: 'sidebar-item',
},
props: {
dot: Boolean,
badge: null,
info: null,
title: String,
disabled: Boolean,
},
methods: {
onClick() {
const { parent } = this;
if (!parent || this.data.disabled) {
return;
}
const index = parent.children.indexOf(this);
parent.setActive(index).then(() => {
this.$emit('click', index);
parent.$emit('change', index);
});
},
setActive(selected) {
return this.setData({ selected });
},
},
});
{
"component": true,
"usingComponents": {
"van-info": "../info/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<view
class="{{ utils.bem('sidebar-item', { selected, disabled }) }} {{ selected ? 'active-class' : '' }} {{ disabled ? 'disabled-class' : '' }} custom-class"
hover-class="van-sidebar-item--hover"
hover-stay-time="70"
bind:tap="onClick"
>
<view class="van-sidebar-item__text">
<van-info
wx:if="{{ badge != null || info !== null || dot }}"
dot="{{ dot }}"
info="{{ badge != null ? badge : info }}"
/>
<view wx:if="{{ title }}">{{ title }}</view>
<slot wx:else name="title" />
</view>
</view>
@import '../common/index.wxss';.van-sidebar-item{display:block;box-sizing:border-box;overflow:hidden;border-left:3px solid transparent;-webkit-user-select:none;user-select:none;padding:20px 12px 20px 8px;padding:var(--sidebar-padding,20px 12px 20px 8px);font-size:14px;font-size:var(--sidebar-font-size,14px);line-height:20px;line-height:var(--sidebar-line-height,20px);color:#323233;color:var(--sidebar-text-color,#323233);background-color:#f7f8fa;background-color:var(--sidebar-background-color,#f7f8fa)}.van-sidebar-item__text{position:relative;display:inline-block;word-break:break-all}.van-sidebar-item--hover:not(.van-sidebar-item--disabled){background-color:#f2f3f5;background-color:var(--sidebar-active-color,#f2f3f5)}.van-sidebar-item:after{border-bottom-width:1px}.van-sidebar-item--selected{color:#323233;color:var(--sidebar-selected-text-color,#323233);font-weight:500;font-weight:var(--sidebar-selected-font-weight,500);border-color:#ee0a24;border-color:var(--sidebar-selected-border-color,#ee0a24)}.van-sidebar-item--selected:after{border-right-width:1px}.van-sidebar-item--selected,.van-sidebar-item--selected.van-sidebar-item--hover{background-color:#fff;background-color:var(--sidebar-selected-background-color,#fff)}.van-sidebar-item--disabled{color:#c8c9cc;color:var(--sidebar-disabled-text-color,#c8c9cc)}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'sidebar-item',
type: 'descendant',
current: 'sidebar',
linked() {
this.setActive(this.data.activeKey);
},
unlinked() {
this.setActive(this.data.activeKey);
},
},
props: {
activeKey: {
type: Number,
value: 0,
observer: 'setActive',
},
},
beforeCreate() {
this.currentActive = -1;
},
methods: {
setActive(activeKey) {
const { children, currentActive } = this;
if (!children.length) {
return Promise.resolve();
}
this.currentActive = activeKey;
const stack = [];
if (currentActive !== activeKey && children[currentActive]) {
stack.push(children[currentActive].setActive(false));
}
if (children[activeKey]) {
stack.push(children[activeKey].setActive(true));
}
return Promise.all(stack);
},
},
});
<view class="van-sidebar custom-class">
<slot />
</view>
@import '../common/index.wxss';.van-sidebar{width:80px;width:var(--sidebar-width,80px)}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
classes: ['avatar-class', 'title-class', 'row-class'],
props: {
row: {
type: Number,
value: 0,
observer(value) {
this.setData({ rowArray: Array.from({ length: value }) });
},
},
title: Boolean,
avatar: Boolean,
loading: {
type: Boolean,
value: true,
},
animate: {
type: Boolean,
value: true,
},
avatarSize: {
type: String,
value: '32px',
},
avatarShape: {
type: String,
value: 'round',
},
titleWidth: {
type: String,
value: '40%',
},
rowWidth: {
type: null,
value: '100%',
observer(val) {
this.setData({ isArray: val instanceof Array });
},
},
},
data: {
isArray: false,
rowArray: [],
},
});
{
"component": true,
"usingComponents": {}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<view
wx:if="{{ loading }}"
class="custom-class {{ utils.bem('skeleton', [{animate}]) }}"
>
<view
wx:if="{{ avatar }}"
class="avatar-class {{ utils.bem('skeleton__avatar', [avatarShape])}}"
style="{{ 'width:' + avatarSize + ';height:' + avatarSize }}"
/>
<view class="{{ utils.bem('skeleton__content')}}">
<view
wx:if="{{ title }}"
class="title-class {{ utils.bem('skeleton__title') }}"
style="{{ 'width:' + titleWidth }}"
/>
<view
wx:for="{{ rowArray }}"
wx:key="index"
wx:for-index="index"
class="row-class {{ utils.bem('skeleton__row') }}"
style="{{ 'width:' + (isArray ? rowWidth[index] : rowWidth) }}"
/>
</view>
</view>
<view wx:else class="{{ utils.bem('skeleton__content')}}">
<slot />
</view>
@import '../common/index.wxss';.van-skeleton{display:-webkit-flex;display:flex;box-sizing:border-box;width:100%;padding:0 16px;padding:var(--skeleton-padding,0 16px)}.van-skeleton__avatar{-webkit-flex-shrink:0;flex-shrink:0;margin-right:16px;margin-right:var(--padding-md,16px);background-color:#f2f3f5;background-color:var(--skeleton-avatar-background-color,#f2f3f5)}.van-skeleton__avatar--round{border-radius:100%}.van-skeleton__content{-webkit-flex:1;flex:1}.van-skeleton__avatar+.van-skeleton__content{padding-top:8px;padding-top:var(--padding-xs,8px)}.van-skeleton__row,.van-skeleton__title{height:16px;height:var(--skeleton-row-height,16px);background-color:#f2f3f5;background-color:var(--skeleton-row-background-color,#f2f3f5)}.van-skeleton__title{margin:0}.van-skeleton__row:not(:first-child){margin-top:12px;margin-top:var(--skeleton-row-margin-top,12px)}.van-skeleton__title+.van-skeleton__row{margin-top:20px}.van-skeleton--animate{-webkit-animation:van-skeleton-blink 1.2s ease-in-out infinite;animation:van-skeleton-blink 1.2s ease-in-out infinite}@-webkit-keyframes van-skeleton-blink{50%{opacity:.6}}@keyframes van-skeleton-blink{50%{opacity:.6}}
\ No newline at end of file
import { VantComponent } from '../common/component';
import { touch } from '../mixins/touch';
import { canIUseModel } from '../common/version';
import { getRect } from '../common/utils';
VantComponent({
mixins: [touch],
props: {
disabled: Boolean,
useButtonSlot: Boolean,
activeColor: String,
inactiveColor: String,
max: {
type: Number,
value: 100,
},
min: {
type: Number,
value: 0,
},
step: {
type: Number,
value: 1,
},
value: {
type: Number,
value: 0,
observer(val) {
if (val !== this.value) {
this.updateValue(val);
}
},
},
barHeight: {
type: null,
value: 2,
},
},
created() {
this.updateValue(this.data.value);
},
methods: {
onTouchStart(event) {
if (this.data.disabled) return;
this.touchStart(event);
this.startValue = this.format(this.value);
this.dragStatus = 'start';
},
onTouchMove(event) {
if (this.data.disabled) return;
if (this.dragStatus === 'start') {
this.$emit('drag-start');
}
this.touchMove(event);
this.dragStatus = 'draging';
getRect(this, '.van-slider').then((rect) => {
const diff = (this.deltaX / rect.width) * this.getRange();
this.newValue = this.startValue + diff;
this.updateValue(this.newValue, false, true);
});
},
onTouchEnd() {
if (this.data.disabled) return;
if (this.dragStatus === 'draging') {
this.updateValue(this.newValue, true);
this.$emit('drag-end');
}
},
onClick(event) {
if (this.data.disabled) return;
const { min } = this.data;
getRect(this, '.van-slider').then((rect) => {
const value =
((event.detail.x - rect.left) / rect.width) * this.getRange() + min;
this.updateValue(value, true);
});
},
updateValue(value, end, drag) {
value = this.format(value);
const { min } = this.data;
const width = `${((value - min) * 100) / this.getRange()}%`;
this.value = value;
this.setData({
barStyle: `
width: ${width};
${drag ? 'transition: none;' : ''}
`,
});
if (drag) {
this.$emit('drag', { value });
}
if (end) {
this.$emit('change', value);
}
if ((drag || end) && canIUseModel()) {
this.setData({ value });
}
},
getRange() {
const { max, min } = this.data;
return max - min;
},
format(value) {
const { max, min, step } = this.data;
return Math.round(Math.max(min, Math.min(value, max)) / step) * step;
},
},
});
<wxs src="../wxs/utils.wxs" module="utils" />
<wxs src="./index.wxs" module="computed" />
<view
class="custom-class {{ utils.bem('slider', { disabled }) }}"
style="{{ inactiveColor ? 'background:' + inactiveColor : '' }}"
bind:tap="onClick"
>
<view
class="van-slider__bar"
style="{{ barStyle }};{{ computed.barStyle(barHeight, activeColor) }}"
>
<view
class="van-slider__button-wrapper"
bind:touchstart="onTouchStart"
catch:touchmove="onTouchMove"
bind:touchend="onTouchEnd"
bind:touchcancel="onTouchEnd"
>
<slot
wx:if="{{ useButtonSlot }}"
name="button"
/>
<view
wx:else
class="van-slider__button"
/>
</view>
</view>
</view>
/* eslint-disable */
var style = require('../wxs/style.wxs');
var addUnit = require('../wxs/add-unit.wxs');
function barStyle(barHeight, activeColor) {
return style({
height: addUnit(barHeight),
background: activeColor,
});
}
module.exports = {
barStyle: barStyle,
};
@import '../common/index.wxss';.van-slider{position:relative;border-radius:999px;border-radius:var(--border-radius-max,999px);background-color:#ebedf0;background-color:var(--slider-inactive-background-color,#ebedf0)}.van-slider:before{position:absolute;right:0;left:0;content:"";top:-8px;top:-var(--padding-xs,8px);bottom:-8px;bottom:-var(--padding-xs,8px)}.van-slider__bar{position:relative;border-radius:inherit;transition:width .2s;transition:width var(--animation-duration-fast,.2s);background-color:#1989fa;background-color:var(--slider-active-background-color,#1989fa)}.van-slider__button{width:24px;height:24px;border-radius:50%;box-shadow:0 1px 2px rgba(0,0,0,.5);background-color:#fff;background-color:var(--slider-button-background-color,#fff)}.van-slider__button-wrapper{position:absolute;top:50%;right:0;-webkit-transform:translate3d(50%,-50%,0);transform:translate3d(50%,-50%,0)}.van-slider--disabled{opacity:.5}
\ No newline at end of file
import { VantComponent } from '../common/component';
import { GREEN, GRAY_DARK } from '../common/color';
VantComponent({
classes: ['desc-class'],
props: {
icon: String,
steps: Array,
active: Number,
direction: {
type: String,
value: 'horizontal',
},
activeColor: {
type: String,
value: GREEN,
},
inactiveColor: {
type: String,
value: GRAY_DARK,
},
activeIcon: {
type: String,
value: 'checked',
},
inactiveIcon: String,
},
methods: {
onClick(event) {
const { index } = event.currentTarget.dataset;
this.$emit('click-step', index);
},
},
});
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="custom-class {{ utils.bem('steps', [direction]) }}">
<view class="van-step__wrapper">
<view
wx:for="{{ steps }}"
wx:key="index"
bindtap="onClick"
data-index="{{ index }}"
class="{{ utils.bem('step', [direction, status(index, active)]) }} van-hairline"
style="{{ status(index, active) === 'inactive' ? 'color: ' + inactiveColor: '' }}"
>
<view class="van-step__title" style="{{ index === active ? 'color: ' + activeColor : '' }}">
<view>{{ item.text }}</view>
<view class="desc-class">{{ item.desc }}</view>
</view>
<view class="van-step__circle-container">
<block wx:if="{{ index !== active }}">
<van-icon
wx:if="{{ item.inactiveIcon || inactiveIcon }}"
color="{{ status(index, active) === 'inactive' ? inactiveColor: activeColor }}"
name="{{ item.inactiveIcon || inactiveIcon }}"
custom-class="van-step__icon"
/>
<view
wx:else
class="van-step__circle"
style="{{ 'background-color: ' + (index < active ? activeColor : inactiveColor) }}"
/>
</block>
<van-icon wx:else name="{{ item.activeIcon || activeIcon }}" color="{{ activeColor }}" custom-class="van-step__icon" />
</view>
<view
wx:if="{{ index !== steps.length - 1 }}"
class="van-step__line" style="{{ 'background-color: ' + (index < active ? activeColor : inactiveColor) }}"
/>
</view>
</view>
</view>
<wxs module="status">
function get(index, active) {
if (index < active) {
return 'finish';
} else if (index === active) {
return 'process';
}
return 'inactive';
}
module.exports = get;
</wxs>
@import '../common/index.wxss';.van-steps{overflow:hidden;background-color:#fff;background-color:var(--steps-background-color,#fff)}.van-steps--horizontal{padding:10px}.van-steps--horizontal .van-step__wrapper{position:relative;display:-webkit-flex;display:flex;overflow:hidden}.van-steps--vertical{padding-left:10px}.van-steps--vertical .van-step__wrapper{padding:0 0 0 20px}.van-step{position:relative;-webkit-flex:1;flex:1;font-size:14px;font-size:var(--step-font-size,14px);color:#969799;color:var(--step-text-color,#969799)}.van-step--finish{color:#323233;color:var(--step-finish-text-color,#323233)}.van-step__circle{border-radius:50%;width:5px;width:var(--step-circle-size,5px);height:5px;height:var(--step-circle-size,5px);background-color:#969799;background-color:var(--step-circle-color,#969799)}.van-step--horizontal{padding-bottom:14px}.van-step--horizontal:first-child .van-step__title{-webkit-transform:none;transform:none}.van-step--horizontal:first-child .van-step__circle-container{padding:0 8px 0 0;-webkit-transform:translate3d(0,50%,0);transform:translate3d(0,50%,0)}.van-step--horizontal:last-child{position:absolute;right:0;width:auto}.van-step--horizontal:last-child .van-step__title{text-align:right;-webkit-transform:none;transform:none}.van-step--horizontal:last-child .van-step__circle-container{right:0;padding:0 0 0 8px;-webkit-transform:translate3d(0,50%,0);transform:translate3d(0,50%,0)}.van-step--horizontal .van-step__circle-container{position:absolute;bottom:6px;z-index:1;-webkit-transform:translate3d(-50%,50%,0);transform:translate3d(-50%,50%,0);background-color:#fff;background-color:var(--white,#fff);padding:0 8px;padding:0 var(--padding-xs,8px)}.van-step--horizontal .van-step__title{display:inline-block;-webkit-transform:translate3d(-50%,0,0);transform:translate3d(-50%,0,0);font-size:12px;font-size:var(--step-horizontal-title-font-size,12px)}.van-step--horizontal .van-step__line{position:absolute;right:0;bottom:6px;left:0;height:1px;-webkit-transform:translate3d(0,50%,0);transform:translate3d(0,50%,0);background-color:#ebedf0;background-color:var(--step-line-color,#ebedf0)}.van-step--horizontal.van-step--process{color:#323233;color:var(--step-process-text-color,#323233)}.van-step--horizontal.van-step--process .van-step__icon{display:block;line-height:1;font-size:12px;font-size:var(--step-icon-size,12px)}.van-step--vertical{padding:10px 10px 10px 0;line-height:18px}.van-step--vertical:after{border-bottom-width:1px}.van-step--vertical:last-child:after{border-bottom-width:none}.van-step--vertical:first-child:before{position:absolute;top:0;left:-15px;z-index:1;width:1px;height:20px;content:"";background-color:#fff;background-color:var(--white,#fff)}.van-step--vertical .van-step__circle,.van-step--vertical .van-step__icon,.van-step--vertical .van-step__line{position:absolute;top:19px;left:-14px;z-index:2;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0)}.van-step--vertical .van-step__icon{line-height:1;font-size:12px;font-size:var(--step-icon-size,12px)}.van-step--vertical .van-step__line{z-index:1;width:1px;height:100%;-webkit-transform:translate3d(-50%,0,0);transform:translate3d(-50%,0,0);background-color:#ebedf0;background-color:var(--step-line-color,#ebedf0)}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
props: {
info: null,
name: null,
icon: String,
dot: Boolean,
iconPrefix: {
type: String,
value: 'van-icon',
},
},
relation: {
name: 'tabbar',
type: 'ancestor',
current: 'tabbar-item',
},
data: {
active: false,
},
methods: {
onClick() {
const { parent } = this;
if (parent) {
const index = parent.children.indexOf(this);
const active = this.data.name || index;
if (active !== this.data.active) {
parent.$emit('change', active);
}
}
this.$emit('click');
},
updateFromParent() {
const { parent } = this;
if (!parent) {
return;
}
const index = parent.children.indexOf(this);
const parentData = parent.data;
const { data } = this;
const active = (data.name || index) === parentData.active;
const patch = {};
if (active !== data.active) {
patch.active = active;
}
if (parentData.activeColor !== data.activeColor) {
patch.activeColor = parentData.activeColor;
}
if (parentData.inactiveColor !== data.inactiveColor) {
patch.inactiveColor = parentData.inactiveColor;
}
if (Object.keys(patch).length > 0) {
this.setData(patch);
}
},
},
});
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-info": "../info/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<view
class="{{ utils.bem('tabbar-item', { active }) }} custom-class"
style="color: {{ active ? activeColor : inactiveColor }}"
bindtap="onClick"
>
<view class="van-tabbar-item__icon">
<van-icon
wx:if="{{ icon }}"
name="{{ icon }}"
class-prefix="{{ iconPrefix }}"
custom-class="van-tabbar-item__icon__inner"
/>
<block wx:else>
<slot wx:if="{{ active }}" name="icon-active" />
<slot wx:else name="icon" />
</block>
<van-info
dot="{{ dot }}"
info="{{ info }}"
custom-class="van-tabbar-item__info"
/>
</view>
<view class="van-tabbar-item__text">
<slot />
</view>
</view>
@import '../common/index.wxss';:host{-webkit-flex:1;flex:1}.van-tabbar-item{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;height:100%;color:#646566;color:var(--tabbar-item-text-color,#646566);font-size:12px;font-size:var(--tabbar-item-font-size,12px);line-height:1;line-height:var(--tabbar-item-line-height,1)}.van-tabbar-item__icon{position:relative;margin-bottom:4px;margin-bottom:var(--tabbar-item-margin-bottom,4px);font-size:22px;font-size:var(--tabbar-item-icon-size,22px)}.van-tabbar-item__icon__inner{display:block;min-width:1em}.van-tabbar-item--active{color:#1989fa;color:var(--tabbar-item-active-color,#1989fa)}.van-tabbar-item__info{margin-top:2px}
\ No newline at end of file
import { getRect } from '../common/utils';
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'tabbar-item',
type: 'descendant',
current: 'tabbar',
linked(target) {
target.parent = this;
target.updateFromParent();
},
unlinked() {
this.updateChildren();
},
},
props: {
active: {
type: null,
observer: 'updateChildren',
},
activeColor: {
type: String,
observer: 'updateChildren',
},
inactiveColor: {
type: String,
observer: 'updateChildren',
},
fixed: {
type: Boolean,
value: true,
observer: 'setHeight',
},
placeholder: {
type: Boolean,
observer: 'setHeight',
},
border: {
type: Boolean,
value: true,
},
zIndex: {
type: Number,
value: 1,
},
safeAreaInsetBottom: {
type: Boolean,
value: true,
},
},
data: {
height: 50,
},
methods: {
updateChildren() {
const { children } = this;
if (!Array.isArray(children) || !children.length) {
return;
}
children.forEach((child) => child.updateFromParent());
},
setHeight() {
if (!this.data.fixed || !this.data.placeholder) {
return;
}
wx.nextTick(() => {
getRect(this, '.van-tabbar').then((res) => {
this.setData({ height: res.height });
});
});
},
},
});
<wxs src="../wxs/utils.wxs" module="utils" />
<view
class="{{ border ? 'van-hairline--top-bottom' : '' }} {{ utils.bem('tabbar', { fixed, safe: safeAreaInsetBottom }) }} custom-class"
style="{{ zIndex ? 'z-index: ' + zIndex : '' }}"
>
<slot />
</view>
<view wx:if="{{ fixed && placeholder }}" style="height: {{ height }}px;"></view>
@import '../common/index.wxss';.van-tabbar{display:-webkit-flex;display:flex;box-sizing:initial;width:100%;height:50px;height:var(--tabbar-height,50px);background-color:#fff;background-color:var(--tabbar-background-color,#fff)}.van-tabbar--fixed{position:fixed;bottom:0;left:0}.van-tabbar--safe{padding-bottom:env(safe-area-inset-bottom)}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
props: {
show: Boolean,
mask: Boolean,
message: String,
forbidClick: Boolean,
zIndex: {
type: Number,
value: 1000,
},
type: {
type: String,
value: 'text',
},
loadingType: {
type: String,
value: 'circular',
},
position: {
type: String,
value: 'middle',
},
},
methods: {
// for prevent touchmove
noop() {},
},
});
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-loading": "../loading/index",
"van-overlay": "../overlay/index",
"van-transition": "../transition/index"
}
}
<van-overlay
wx:if="{{ mask || forbidClick }}"
show="{{ show }}"
z-index="{{ zIndex }}"
custom-style="{{ mask ? '' : 'background-color: transparent;' }}"
/>
<van-transition
show="{{ show }}"
custom-style="z-index: {{ zIndex }}"
custom-class="van-toast__container"
>
<view
class="van-toast van-toast--{{ type === 'text' ? 'text' : 'icon' }} van-toast--{{ position }}"
catch:touchmove="noop"
>
<!-- text only -->
<text wx:if="{{ type === 'text' }}">{{ message }}</text>
<!-- with icon -->
<block wx:else>
<van-loading
wx:if="{{ type === 'loading' }}"
color="white"
type="{{ loadingType }}"
custom-class="van-toast__loading"
/>
<van-icon wx:else class="van-toast__icon" name="{{ type }}" />
<text wx:if="{{ message }}" class="van-toast__text">{{ message }}</text>
</block>
<slot />
</view>
</van-transition>
@import '../common/index.wxss';.van-toast{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:initial;color:#fff;color:var(--toast-text-color,#fff);font-size:14px;font-size:var(--toast-font-size,14px);line-height:20px;line-height:var(--toast-line-height,20px);white-space:pre-wrap;word-wrap:break-word;background-color:rgba(0,0,0,.7);background-color:var(--toast-background-color,rgba(0,0,0,.7));border-radius:8px;border-radius:var(--toast-border-radius,8px)}.van-toast__container{position:fixed;top:50%;left:50%;width:-webkit-fit-content;width:fit-content;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);max-width:70%;max-width:var(--toast-max-width,70%)}.van-toast--text{min-width:96px;min-width:var(--toast-text-min-width,96px);padding:8px 12px;padding:var(--toast-text-padding,8px 12px)}.van-toast--icon{width:88px;width:var(--toast-default-width,88px);min-height:88px;min-height:var(--toast-default-min-height,88px);padding:16px;padding:var(--toast-default-padding,16px)}.van-toast--icon .van-toast__icon{font-size:36px;font-size:var(--toast-icon-size,36px)}.van-toast--icon .van-toast__text{padding-top:8px}.van-toast__loading{margin:10px 0}.van-toast--top{-webkit-transform:translateY(-30vh);transform:translateY(-30vh)}.van-toast--bottom{-webkit-transform:translateY(30vh);transform:translateY(30vh)}
\ No newline at end of file
/// <reference types="miniprogram-api-typings" />
declare type ToastMessage = string | number;
interface ToastOptions {
show?: boolean;
type?: string;
mask?: boolean;
zIndex?: number;
context?:
| WechatMiniprogram.Component.TrivialInstance
| WechatMiniprogram.Page.TrivialInstance;
position?: string;
duration?: number;
selector?: string;
forbidClick?: boolean;
loadingType?: string;
message?: ToastMessage;
onClose?: () => void;
}
declare function Toast(
toastOptions: ToastOptions | ToastMessage
):
| WechatMiniprogram.Component.Instance<
Record<string, any>,
Record<string, any>,
Record<string, any>,
Record<string, any>,
false
>
| undefined;
declare namespace Toast {
var loading: (
options: string | number | ToastOptions
) =>
| WechatMiniprogram.Component.Instance<
Record<string, any>,
Record<string, any>,
Record<string, any>,
Record<string, any>,
false
>
| undefined;
var success: (
options: string | number | ToastOptions
) =>
| WechatMiniprogram.Component.Instance<
Record<string, any>,
Record<string, any>,
Record<string, any>,
Record<string, any>,
false
>
| undefined;
var fail: (
options: string | number | ToastOptions
) =>
| WechatMiniprogram.Component.Instance<
Record<string, any>,
Record<string, any>,
Record<string, any>,
Record<string, any>,
false
>
| undefined;
var clear: () => void;
var setDefaultOptions: (options: ToastOptions) => void;
var resetDefaultOptions: () => void;
}
export default Toast;
import { isObj } from '../common/validator';
const defaultOptions = {
type: 'text',
mask: false,
message: '',
show: true,
zIndex: 1000,
duration: 2000,
position: 'middle',
forbidClick: false,
loadingType: 'circular',
selector: '#van-toast',
};
let queue = [];
let currentOptions = Object.assign({}, defaultOptions);
function parseOptions(message) {
return isObj(message) ? message : { message };
}
function getContext() {
const pages = getCurrentPages();
return pages[pages.length - 1];
}
function Toast(toastOptions) {
const options = Object.assign(
Object.assign({}, currentOptions),
parseOptions(toastOptions)
);
const context = options.context || getContext();
const toast = context.selectComponent(options.selector);
if (!toast) {
console.warn('未找到 van-toast 节点,请确认 selector 及 context 是否正确');
return;
}
delete options.context;
delete options.selector;
toast.clear = () => {
toast.setData({ show: false });
if (options.onClose) {
options.onClose();
}
};
queue.push(toast);
toast.setData(options);
clearTimeout(toast.timer);
if (options.duration != null && options.duration > 0) {
toast.timer = setTimeout(() => {
toast.clear();
queue = queue.filter((item) => item !== toast);
}, options.duration);
}
return toast;
}
const createMethod = (type) => (options) =>
Toast(Object.assign({ type }, parseOptions(options)));
Toast.loading = createMethod('loading');
Toast.success = createMethod('success');
Toast.fail = createMethod('fail');
Toast.clear = () => {
queue.forEach((toast) => {
toast.clear();
});
queue = [];
};
Toast.setDefaultOptions = (options) => {
Object.assign(currentOptions, options);
};
Toast.resetDefaultOptions = () => {
currentOptions = Object.assign({}, defaultOptions);
};
export default Toast;
import { VantComponent } from '../common/component';
VantComponent({
classes: [
'main-item-class',
'content-item-class',
'main-active-class',
'content-active-class',
'main-disabled-class',
'content-disabled-class',
],
props: {
items: {
type: Array,
observer: 'updateSubItems',
},
activeId: null,
mainActiveIndex: {
type: Number,
value: 0,
observer: 'updateSubItems',
},
height: {
type: [Number, String],
value: 300,
},
max: {
type: Number,
value: Infinity,
},
selectedIcon: {
type: String,
value: 'success',
},
},
data: {
subItems: [],
},
methods: {
// 当一个子项被选择时
onSelectItem(event) {
const { item } = event.currentTarget.dataset;
const isArray = Array.isArray(this.data.activeId);
// 判断有没有超出右侧选择的最大数
const isOverMax = isArray && this.data.activeId.length >= this.data.max;
// 判断该项有没有被选中, 如果有被选中,则忽视是否超出的条件
const isSelected = isArray
? this.data.activeId.indexOf(item.id) > -1
: this.data.activeId === item.id;
if (!item.disabled && (!isOverMax || isSelected)) {
this.$emit('click-item', item);
}
},
// 当一个导航被点击时
onClickNav(event) {
const index = event.detail;
const item = this.data.items[index];
if (!item.disabled) {
this.$emit('click-nav', { index });
}
},
// 更新子项列表
updateSubItems() {
const { items, mainActiveIndex } = this.data;
const { children = [] } = items[mainActiveIndex] || {};
this.setData({ subItems: children });
},
},
});
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-sidebar": "../sidebar/index",
"van-sidebar-item": "../sidebar-item/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<wxs src="./index.wxs" module="wxs" />
<view
class="van-tree-select"
style="height: {{ utils.addUnit(height) }}"
>
<scroll-view scroll-y class="van-tree-select__nav">
<van-sidebar active-key="{{ mainActiveIndex }}" bind:change="onClickNav" custom-class="van-tree-select__nav__inner">
<van-sidebar-item
wx:for="{{ items }}"
wx:key="index"
custom-class="main-item-class"
active-class="main-active-class"
disabled-class="main-disabled-class"
badge="{{ item.badge }}"
dot="{{ item.dot }}"
title="{{ item.text }}"
disabled="{{ item.disabled }}"
/>
</van-sidebar>
</scroll-view>
<scroll-view scroll-y class="van-tree-select__content">
<slot name="content" />
<view
wx:for="{{ subItems }}"
wx:key="id"
class="van-ellipsis content-item-class {{ utils.bem('tree-select__item', { active: wxs.isActive(activeId, item.id), disabled: item.disabled }) }} {{ wxs.isActive(activeId, item.id) ? 'content-active-class' : '' }} {{ item.disabled ? 'content-disabled-class' : '' }}"
data-item="{{ item }}"
bind:tap="onSelectItem"
>
{{ item.text }}
<van-icon
wx:if="{{ wxs.isActive(activeId, item.id) }}"
name="{{ selectedIcon }}"
size="16px"
class="van-tree-select__selected"
/>
</view>
</scroll-view>
</view>
/* eslint-disable */
var array = require('../wxs/array.wxs');
function isActive (activeList, itemId) {
if (array.isArray(activeList)) {
return activeList.indexOf(itemId) > -1;
}
return activeList === itemId;
}
module.exports.isActive = isActive;
@import '../common/index.wxss';.van-tree-select{position:relative;display:-webkit-flex;display:flex;-webkit-user-select:none;user-select:none;font-size:14px;font-size:var(--tree-select-font-size,14px)}.van-tree-select__nav{-webkit-flex:1;flex:1;background-color:#f7f8fa;background-color:var(--tree-select-nav-background-color,#f7f8fa);--sidebar-padding:12px 8px 12px 12px}.van-tree-select__nav__inner{width:100%!important;height:100%}.van-tree-select__content{-webkit-flex:2;flex:2;background-color:#fff;background-color:var(--tree-select-content-background-color,#fff)}.van-tree-select__item{position:relative;font-weight:700;padding:0 32px 0 16px;padding:0 32px 0 var(--padding-md,16px);line-height:44px;line-height:var(--tree-select-item-height,44px)}.van-tree-select__item--active{color:#ee0a24;color:var(--tree-select-item-active-color,#ee0a24)}.van-tree-select__item--disabled{color:#c8c9cc;color:var(--tree-select-item-disabled-color,#c8c9cc)}.van-tree-select__selected{position:absolute;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);right:16px;right:var(--padding-md,16px)}
\ No newline at end of file
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