Commit 6f0b28ff by pangchong

feat: 筛选页开发

parent 6ce64588
{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/ {
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数 // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
"version": "0.0", // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
"configurations": [{ "version" : "0.0",
"app-plus" : "configurations" : [
{ {
"launchtype" : "local" "app-plus" : {
}, "launchtype" : "local"
"default" : },
{ "default" : {
"launchtype" : "local" "launchtype" : "local"
}, },
"mp-weixin" : "mp-weixin" : {
{ "launchtype" : "local"
"launchtype" : "local" },
}, "type" : "uniCloud"
"type" : "uniCloud" },
} {
"playground" : "standard",
"type" : "uni-app:app-android"
}
] ]
} }
...@@ -10,6 +10,7 @@ declare module 'vue' { ...@@ -10,6 +10,7 @@ declare module 'vue' {
// 全局组件 // 全局组件
GlobalAlbum: typeof import('./src/mocp/components/global-album/global-album.vue')['default'] GlobalAlbum: typeof import('./src/mocp/components/global-album/global-album.vue')['default']
GlobalButton: typeof import('./src/mocp/components/global-button/global-button.vue')['default'] GlobalButton: typeof import('./src/mocp/components/global-button/global-button.vue')['default']
GlobalCalendar: typeof import('./src/mocp/components/global-calendar/global-calendar.vue')['default']
GlobalCheckbox: typeof import('./src/mocp/components/global-checkbox/global-checkbox.vue')['default'] GlobalCheckbox: typeof import('./src/mocp/components/global-checkbox/global-checkbox.vue')['default']
GlobalDate: typeof import('./src/mocp/components/global-date/global-date.vue')['default'] GlobalDate: typeof import('./src/mocp/components/global-date/global-date.vue')['default']
GlobalEmpty: typeof import('./src/mocp/components/global-empty/global-empty.vue')['default'] GlobalEmpty: typeof import('./src/mocp/components/global-empty/global-empty.vue')['default']
......
...@@ -9,6 +9,15 @@ export const getArrangeWorkListApi = (data, config) => { ...@@ -9,6 +9,15 @@ export const getArrangeWorkListApi = (data, config) => {
}) })
} }
export const getSeatUnitApi = (data, config) => {
return http({
method: 'POST',
url: '/workbench/getSeatUnit',
data,
config
})
}
export const getArrangeWorkDetailApi = (data, config) => { export const getArrangeWorkDetailApi = (data, config) => {
return http({ return http({
method: 'POST', method: 'POST',
......
@mixin global-button-light {
color: $mocp-primary-6;
background-color: $mocp-primary-1;
}
@mixin global-button-light-active {
color: darken($mocp-primary-6, 10%);
background-color: darken($mocp-primary-1, 5%);
border-color: darken($mocp-primary-1, 5%);
}
@mixin global-button-primary { @mixin global-button-primary {
color: #fff; color: #fff;
background-color: $mocp-primary-6; background-color: $mocp-primary-6;
...@@ -38,7 +47,12 @@ ...@@ -38,7 +47,12 @@
padding: 0 20rpx; padding: 0 20rpx;
margin: 0; margin: 0;
font-size: 28rpx; font-size: 28rpx;
border-radius: 52rpx; &.light {
@include global-button-light;
&:active {
@include global-button-light-active;
}
}
&.primary { &.primary {
@include global-button-primary; @include global-button-primary;
&:active { &:active {
......
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
<script setup> <script setup>
import { computed } from 'vue' import { computed } from 'vue'
const ps = defineProps({ const ps = defineProps({
radius: {
type: [String, Number],
default: 52
},
class: { class: {
type: String, type: String,
default: '' default: ''
...@@ -18,7 +22,7 @@ const ps = defineProps({ ...@@ -18,7 +22,7 @@ const ps = defineProps({
return {} return {}
} }
}, },
//default,primary,success,warning,danger,text //default,light,primary,success,warning,danger,text
type: { type: {
type: String, type: String,
default: 'default' default: 'default'
...@@ -61,10 +65,14 @@ const getSize = computed(() => { ...@@ -61,10 +65,14 @@ const getSize = computed(() => {
return 88 + 'rpx' return 88 + 'rpx'
} }
}) })
const getRadius = computed(() => {
return ps.radius + 'rpx'
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import './global-button.scss'; @import './global-button.scss';
.global-button { .global-button {
border-radius: v-bind(getRadius);
height: v-bind(getSize); height: v-bind(getSize);
line-height: v-bind(getSize); line-height: v-bind(getSize);
} }
......
<template>
<!-- 全局日期控件 -->
<view class="date">
<wu-calendar
ref="calendar"
:mode="mode"
:insert="false"
:color="color"
:confirmColor="confirmColor"
@confirm="confirm"
maskClick
lunar
slideSwitchMode="vertical"
rangeSameDay
:startText="startText"
:endText="endText"
operationPosition="bottom"
confirmFullDate
:date="defaultValue"
></wu-calendar>
<view class="date-content" :class="getPickerClass" @tap="open" :style="getStyle">
<text class="date-value">{{ getLabelValue }}</text>
<view class="date-icon">
<view class="date-icon-close" v-if="clearable && !showPlaceholder && !disabled" @tap.stop="clear">
<up-icon name="close-circle-fill" color="#c0c4cc" size="36rpx"></up-icon>
</view>
<global-icon icon="calendar" color="#86909C"></global-icon>
</view>
</view>
</view>
</template>
<script setup>
import { computed, ref, watchEffect } from 'vue'
import Day from 'mocp/utils/dayjs'
const es = defineEmits(['update:startTime', 'update:endTime', 'change'])
const ps = defineProps({
//日历模式single,range,multiple
mode: {
type: String,
default: 'range'
},
//显示为空的value值
emptyValue: {
type: [String, Number],
default: ''
},
startTime: {
type: [String, Number],
default: ''
},
endTime: {
type: [String, Number],
default: ''
},
modelValue: {
type: [String, Number],
default: ''
},
clearable: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: '请选择日期范围'
},
disabled: {
type: Boolean,
default: false
},
pickAlign: {
type: String,
default: 'left'
},
rangeSeparator: {
type: String,
default: '至'
},
format: {
type: String,
default: 'YYYY/MM/DD'
},
startText: {
type: String,
default: '开始'
},
endText: {
type: String,
default: '结束'
},
confirmText: {
type: String,
default: '确认'
},
color: {
type: String,
default: '#165dff'
},
confirmColor: {
type: String,
default: '#165dff'
}
})
//获取下拉框样式
const getStyle = computed(() => {
let pickAlign = 'flex-start'
if (ps.pickAlign == 'center') {
pickAlign = 'center'
} else if (ps.pickAlign == 'right') {
pickAlign = 'flex-end'
}
return {
justifyContent: pickAlign
}
})
//下拉框显示的内容
const labelValue = ref('')
const getLabelValue = computed(() => {
if (labelValue.value) {
return labelValue.value
} else {
return ps.placeholder
}
})
//获取下拉框class
const showPlaceholder = computed(() => {
return !labelValue.value || labelValue.value == ps.emptyValue
})
const getPickerClass = computed(() => {
return {
disabled: ps.disabled,
placeholder: showPlaceholder.value
}
})
const calendar = ref()
const open = () => {
calendar.value?.open()
}
//设置初始值
const defaultValue = ref([Day().format('YYYY-MM-DD'), ''])
watchEffect(() => {
if (ps.modelValue && ps.modelValue != ps.emptyValue) {
if (ps.mode == 'range') {
const range = ps.modelValue.split(ps.rangeSeparator)
labelValue.value = ps.modelValue.join(ps.rangeSeparator)
defaultValue.value = [Day(range[0]).format('YYYY-MM-DD'), Day(range[1]).format('YYYY-MM-DD')]
}
} else if (ps.startTime && ps.endTime) {
labelValue.value = Day(ps.startTime).format('YYYY-MM-DD') + ps.rangeSeparator + Day(ps.endTime).format('YYYY-MM-DD')
defaultValue.value = [Day(ps.startTime).format('YYYY-MM-DD'), Day(ps.endTime).format('YYYY-MM-DD')]
}
})
//点击确定按钮
const confirm = (e) => {
if (ps.mode == 'range') {
const { after, before } = e.range
labelValue.value = Day(before).format(ps.format) + ps.rangeSeparator + Day(after).format(ps.format)
es('update:startTime', Day(before).valueOf())
es('update:endTime', Day(after).valueOf())
es('change', [Day(before).valueOf(), Day(after).valueOf()])
}
}
//点击清空按钮
const clear = () => {
labelValue.value = ''
defaultValue.value = ''
es('update:startTime', ps.emptyValue)
es('update:endTime', ps.emptyValue)
es('change', [ps.emptyValue, ps.emptyValue])
}
</script>
<style lang="scss" scoped>
.date {
flex: auto;
&-content {
display: flex;
align-items: center;
line-height: 48rpx;
&.placeholder {
.date-value {
color: $mocp-text-3;
}
}
&.disabled {
background: #f5f7fa;
}
}
&-value {
color: $mocp-text-4;
margin-right: 8rpx;
}
&-icon {
display: flex;
align-items: center;
&-close {
margin-left: 4rpx;
}
}
}
</style>
...@@ -51,6 +51,7 @@ const getTextStyle = computed(() => { ...@@ -51,6 +51,7 @@ const getTextStyle = computed(() => {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 100%; width: 100%;
height: 100%;
flex: none; flex: none;
image { image {
margin-bottom: 40rpx; margin-bottom: 40rpx;
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
:back-to-top-bottom="backToTopBottom" :back-to-top-bottom="backToTopBottom"
show-refresher-update-time show-refresher-update-time
:hide-empty-view="!isDataList" :hide-empty-view="!isDataList"
@query="query" @query="queryList"
@scroll="scroll" @scroll="scroll"
:paging-style="getPagingStyle" :paging-style="getPagingStyle"
> >
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
</z-paging> </z-paging>
</template> </template>
<script setup> <script setup>
import { filterEmptyValues } from 'mocp/utils/tool'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
const dataList = ref([]) const dataList = ref([])
...@@ -152,6 +153,18 @@ const ps = defineProps({ ...@@ -152,6 +153,18 @@ const ps = defineProps({
type: Boolean, type: Boolean,
default: false default: false
}, },
//查询参数
params: {
type: Object,
default: () => {
return {}
}
},
//查询接口
api: {
type: Function,
default: null
},
//是否开启下拉刷新 //是否开启下拉刷新
refresherEnabled: { refresherEnabled: {
type: Boolean, type: Boolean,
...@@ -204,23 +217,33 @@ const scroll = () => { ...@@ -204,23 +217,33 @@ const scroll = () => {
}, 500) }, 500)
// #endif // #endif
} }
const complete = (data) => {
paging.value?.complete(data || true)
}
// 获取屏幕边界到安全区域距离 // 获取屏幕边界到安全区域距离
const { safeAreaInsets } = uni.getSystemInfoSync() const { safeAreaInsets } = uni.getSystemInfoSync()
//列表加载 //列表加载
const query = (pageIndex, pageSize) => { const queryList = (pageIndex, pageSize) => {
es('query', { pageIndex, pageSize })
if (ps.isDataList) { if (ps.isDataList) {
if (!dataList.value.length) { const params = {
complete(dataList.value) pageIndex,
pageSize,
...filterEmptyValues(ps.params)
}
if (Object.prototype.toString.call(ps.api) == '[object Function]') {
ps.api(params, { loading: true })
.then((res) => {
if (res.code == 200) {
paging.value?.complete(res.list || res.data?.list || [])
} else {
uni.$mocpMessage.showToast(res.message)
}
})
.catch(() => {
paging.value?.complete(false)
})
} else {
paging.value?.complete(false)
} }
setTimeout(() => {
complete([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
}, 500)
} else { } else {
complete() es('query', { pageIndex, pageSize })
} }
} }
//点击左边插槽 //点击左边插槽
...@@ -231,7 +254,7 @@ const handleLeftClick = () => { ...@@ -231,7 +254,7 @@ const handleLeftClick = () => {
es('handleLeftClick') es('handleLeftClick')
} }
} }
//保存 //点击右边插槽
const handleRightClick = () => { const handleRightClick = () => {
es('handleRightClick') es('handleRightClick')
} }
...@@ -241,6 +264,14 @@ const handleFooterClick = () => { ...@@ -241,6 +264,14 @@ const handleFooterClick = () => {
} }
// 获取页面栈 // 获取页面栈
const pages = getCurrentPages() const pages = getCurrentPages()
defineExpose({
reload: () => {
paging.value?.reload()
},
updateCache: () => {
paging.value?.updateCache()
}
})
</script> </script>
<script> <script>
export default { export default {
......
<template> <template>
<!-- 全局下拉框控件 --> <!-- 全局下拉框控件 -->
<view class="picker" :style="style"> <view class="picker" :style="style">
<global-popup v-model="show" @close="show = false" :height="592" :customStyle="{ padding: '28rpx 32rpx' }" v-if="filter" :distance="distance">
<template #top>
<view>
<up-search :placeholder="placeholder" :showAction="false" v-model="searchKey"></up-search>
</view>
</template>
<view class="popup-content-list" v-if="getFilterColumns.length">
<view
class="popup-content-item"
:class="{ 'mocp-color-primary-6': modelValue == item[valueField] }"
v-for="(item, index) in getFilterColumns"
:key="index"
@tap="handleChoose(item[valueField])"
>
{{ item[labelField] }}
</view>
</view>
<view style="width: 100%; height: 100%" v-else>
<global-empty></global-empty>
</view>
</global-popup>
<up-picker <up-picker
v-else
:show="show" :show="show"
:columns="[getColumns]" :columns="[getColumns]"
:keyName="labelField" :keyName="labelField"
...@@ -15,7 +37,7 @@ ...@@ -15,7 +37,7 @@
:cancelColor="cancelColor" :cancelColor="cancelColor"
:confirmColor="confirmColor" :confirmColor="confirmColor"
></up-picker> ></up-picker>
<view class="picker-content" :class="getPickerClass" @tap="show = true" :style="getContentStyle"> <view class="picker-content" :class="getPickerClass" @tap="open" :style="getContentStyle">
<text class="picker-value">{{ getLabelValue }}</text> <text class="picker-value">{{ getLabelValue }}</text>
<view class="picker-icon"> <view class="picker-icon">
<view class="picker-icon-close" v-if="clearable && !showPlaceholder && !disabled" @tap.stop="clear"> <view class="picker-icon-close" v-if="clearable && !showPlaceholder && !disabled" @tap.stop="clear">
...@@ -32,8 +54,12 @@ import { computed, ref, watch } from 'vue' ...@@ -32,8 +54,12 @@ import { computed, ref, watch } from 'vue'
import * as dictData from 'mocp/hooks/use-dict/dict-data' import * as dictData from 'mocp/hooks/use-dict/dict-data'
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
const es = defineEmits(['update:modelValue', 'change']) const es = defineEmits(['update:modelValue', 'change', 'getScrollTop'])
const ps = defineProps({ const ps = defineProps({
filter: {
type: Boolean,
default: false
},
style: { style: {
type: Object, type: Object,
default: () => { default: () => {
...@@ -131,6 +157,11 @@ const getPickerClass = computed(() => { ...@@ -131,6 +157,11 @@ const getPickerClass = computed(() => {
} }
}) })
const show = ref(false) const show = ref(false)
//打开
const open = () => {
searchKey.value = ''
show.value = true
}
//设置下拉框打开的默认值 //设置下拉框打开的默认值
const defaultIndex = ref(0) const defaultIndex = ref(0)
//获取下拉框的内容Columns //获取下拉框的内容Columns
...@@ -181,6 +212,26 @@ const clear = () => { ...@@ -181,6 +212,26 @@ const clear = () => {
es('update:modelValue', ps.emptyValue) es('update:modelValue', ps.emptyValue)
es('change', ps.emptyValue) es('change', ps.emptyValue)
} }
//弹出层输入框搜索
const searchKey = ref('')
const getFilterColumns = computed(() => {
return getColumns.value.filter((item) => item[ps.labelField].toLowerCase().includes(searchKey.value.toLowerCase()))
})
//弹出层列表点击
const distance = ref(0)
const handleChoose = (value) => {
es('update:modelValue', value)
es('change', value)
show.value = false
}
//打开默认滑动到选中的位置
watch(
defaultIndex,
(value) => {
distance.value = value * 39
},
{ immediate: true }
)
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.picker { .picker {
...@@ -209,5 +260,17 @@ const clear = () => { ...@@ -209,5 +260,17 @@ const clear = () => {
margin-left: 4rpx; margin-left: 4rpx;
} }
} }
.popup-content {
&-list {
padding-top: 20rpx;
color: $mocp-text-4;
}
&-item {
margin-bottom: 40rpx;
&:last-child {
margin-bottom: 0;
}
}
}
} }
</style> </style>
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
<slot name="title" v-if="title"> <slot name="title" v-if="title">
<view class="title">{{ title }}</view> <view class="title">{{ title }}</view>
</slot> </slot>
<slot name="top"></slot>
<scroll-view scroll-y class="content" :scroll-top="scrollTop" @scroll="scroll"> <scroll-view scroll-y class="content" :scroll-top="scrollTop" @scroll="scroll">
<slot></slot> <slot></slot>
</scroll-view> </scroll-view>
...@@ -34,6 +35,10 @@ const ps = defineProps({ ...@@ -34,6 +35,10 @@ const ps = defineProps({
type: [String, Number], type: [String, Number],
default: '' default: ''
}, },
height: {
type: [String, Number],
default: ''
},
title: { title: {
type: String, type: String,
default: '' default: ''
...@@ -64,6 +69,10 @@ const ps = defineProps({ ...@@ -64,6 +69,10 @@ const ps = defineProps({
type: [String, Number], type: [String, Number],
default: 0 default: 0
}, },
distance: {
type: Number,
default: 0
},
customStyle: { customStyle: {
type: Object, type: Object,
default: () => { default: () => {
...@@ -77,6 +86,7 @@ const getCustomStyle = computed(() => { ...@@ -77,6 +86,7 @@ const getCustomStyle = computed(() => {
const style = { const style = {
...ps.customStyle, ...ps.customStyle,
width: ps.width ? ps.width + 'rpx' : 'auto', width: ps.width ? ps.width + 'rpx' : 'auto',
height: ps.height ? ps.height + 'rpx' : 'auto',
background: ps.background background: ps.background
} }
if (ps.mode == 'right') { if (ps.mode == 'right') {
...@@ -101,7 +111,7 @@ watch( ...@@ -101,7 +111,7 @@ watch(
if (value) { if (value) {
scrollTop.value = 0 scrollTop.value = 0
nextTick(() => { nextTick(() => {
scrollTop.value = oldScrollTop.value scrollTop.value = ps.distance > 0 ? ps.distance : oldScrollTop.value
}) })
} }
} }
......
import { getArrangeWorkDetailApi } from 'mocp/api/assign-work' import { getArrangeWorkDetailApi, getSeatUnitApi } from 'mocp/api/assign-work'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import useUserStore from 'mocp/store/user' import useUserStore from 'mocp/store/user'
...@@ -16,10 +16,19 @@ const useAssignWorkStore = defineStore('assignWork', { ...@@ -16,10 +16,19 @@ const useAssignWorkStore = defineStore('assignWork', {
id: '', id: '',
details: undefined, details: undefined,
arrangeWorkExtendList: [], //责任单位列表 arrangeWorkExtendList: [], //责任单位列表
arrangeWorkExtend: undefined //当前选中的责任单位 arrangeWorkExtend: undefined, //当前选中的责任单位
selectList: {
seatList: [] //管理席位
}
} }
}, },
getters: { getters: {
getSeatUnitSelect(state) {
return state.selectList.seatList.map((q) => ({
label: q.adminSeat,
value: q.adminSeat
}))
},
//获取当前选中的责任单位的index //获取当前选中的责任单位的index
getArrangeWorkExtendIndex(state) { getArrangeWorkExtendIndex(state) {
return state.arrangeWorkExtendList.findIndex((item) => item.id == state.arrangeWorkExtend.id) return state.arrangeWorkExtendList.findIndex((item) => item.id == state.arrangeWorkExtend.id)
...@@ -86,6 +95,12 @@ const useAssignWorkStore = defineStore('assignWork', { ...@@ -86,6 +95,12 @@ const useAssignWorkStore = defineStore('assignWork', {
} }
}, },
actions: { actions: {
async getSeatUnit() {
const res = await getSeatUnitApi({ pageIndex: 1, pageSize: 999 })
if (res.code == 200) {
this.selectList.seatList = res.data.list || []
}
},
async getArrangeWorkDetail() { async getArrangeWorkDetail() {
const res = await getArrangeWorkDetailApi({ id: this.id }, { loading: true }) const res = await getArrangeWorkDetailApi({ id: this.id }, { loading: true })
if (res.code == 200) { if (res.code == 200) {
......
...@@ -13,3 +13,15 @@ export const timeStampFormat = (timeStamp, opt) => { ...@@ -13,3 +13,15 @@ export const timeStampFormat = (timeStamp, opt) => {
const format = opt?.format || 'YYYY/MM/DD HH:mm:ss' const format = opt?.format || 'YYYY/MM/DD HH:mm:ss'
return Day(timeStamp).format(format) return Day(timeStamp).format(format)
} }
/**
*接受一个对象并返回一个只包含非空和非 null 值的新对象
*/
export const filterEmptyValues = (obj) => {
return Object.entries(obj)
.filter(([_, value]) => value !== null && value !== undefined && value !== '')
.reduce((acc, [key, value]) => {
acc[key] = value
return acc
}, {})
}
...@@ -48,12 +48,27 @@ ...@@ -48,12 +48,27 @@
} }
}, },
{ {
"path": "pages/modules/mocp/tab/index",
"style": {
"navigationBarTitleText": "tab页面",
"app-plus": {
"bounce": "none" //关闭窗口回弹效果
}
}
},
{
"path": "pages/modules/mocp/panel/appraisal-record/list", "path": "pages/modules/mocp/panel/appraisal-record/list",
"style": { "style": {
"navigationBarTitleText": "考核记录" "navigationBarTitleText": "考核记录"
} }
}, },
{ {
"path": "pages/modules/mocp/panel/appraisal-record/search",
"style": {
"navigationBarTitleText": "筛选"
}
},
{
"path": "pages/modules/mocp/panel/appraisal-record/details", "path": "pages/modules/mocp/panel/appraisal-record/details",
"style": { "style": {
"navigationBarTitleText": "考核记录详情" "navigationBarTitleText": "考核记录详情"
...@@ -78,6 +93,12 @@ ...@@ -78,6 +93,12 @@
} }
}, },
{ {
"path": "pages/modules/mocp/panel/assign-work/search",
"style": {
"navigationBarTitleText": "筛选"
}
},
{
"path": "pages/modules/mocp/panel/assign-work/details", "path": "pages/modules/mocp/panel/assign-work/details",
"style": { "style": {
"navigationBarTitleText": "早会工作详情" "navigationBarTitleText": "早会工作详情"
...@@ -126,18 +147,15 @@ ...@@ -126,18 +147,15 @@
} }
}, },
{ {
"path": "pages/modules/mocp/tab/index", "path": "pages/modules/mocp/panel/move-decision/list",
"style": { "style": {
"navigationBarTitleText": "tab页面", "navigationBarTitleText": "运行决策"
"app-plus": {
"bounce": "none" //关闭窗口回弹效果
}
} }
}, },
{ {
"path": "pages/modules/mocp/panel/move-decision/list", "path": "pages/modules/mocp/panel/move-decision/search",
"style": { "style": {
"navigationBarTitleText": "运行决策" "navigationBarTitleText": "筛选"
} }
}, },
{ {
...@@ -165,7 +183,7 @@ ...@@ -165,7 +183,7 @@
}, },
"condition": { "condition": {
//模式配置,仅开发期间生效 //模式配置,仅开发期间生效
"current": 0, //当前激活的模式(list 的索引项) "current": 1, //当前激活的模式(list 的索引项)
"list": [ "list": [
{ {
"name": "test", //模式名称 "name": "test", //模式名称
......
import { ref } from 'vue'
export const formRef = ref()
// 表单数据
export const formData = ref({
status: null,
valid: null,
department: '',
appraisee: '',
ac: null,
acOwn: '',
acType: '',
startTime: null,
stopTime: null,
eventType: null,
examineType: '',
appealInfo: null
})
export const status = ref([])
import { toRaw } from 'vue'
import { formData, formRef } from './search.compositions'
export const handleReset = () => {
formData.value = {
status: null,
valid: null,
department: '',
appraisee: '',
ac: null,
acOwn: '',
acType: '',
startTime: null,
stopTime: null,
eventType: null,
examineType: '',
appealInfo: null
}
formRef.value?.resetFields()
handleConfirm()
}
export const handleConfirm = () => {
uni.$mocpJump.navigateBack()
uni.$emit('appraisalRecordReload', { params: toRaw(formData.value) })
}
<template> <template>
<global-page-swiper title="考核记录" refresherEnabled loadingMoreEnabled :tabList="tabList" :api="getRqmListApi" ref="paging" :padding="24"> <global-page
title="考核记录"
isDataList
refresherEnabled
loadingMoreEnabled
:params="searchParams"
:api="getRqmListApi"
auto
ref="paging"
:padding="24"
showNavRight
navRightType="icon"
navRightIcon="saixuan-01"
@handleRightClick="handleRightClick"
>
<template #="{ dataList }"> <template #="{ dataList }">
<view class="item" v-for="item in dataList" :key="item.id" @tap="goDetails(item)"> <view class="item" v-for="item in dataList" :key="item.id" @tap="goDetails(item)">
<view class="item-title"> <view class="item-title">
...@@ -15,7 +29,7 @@ ...@@ -15,7 +29,7 @@
</view> </view>
</view> </view>
</template> </template>
</global-page-swiper> </global-page>
</template> </template>
<script setup> <script setup>
...@@ -24,11 +38,6 @@ import { getRqmListApi } from 'mocp/api/appraisal-record' ...@@ -24,11 +38,6 @@ import { getRqmListApi } from 'mocp/api/appraisal-record'
import { onLoad, onUnload } from '@dcloudio/uni-app' import { onLoad, onUnload } from '@dcloudio/uni-app'
import useAppraisalRecordStore from 'mocp/store/appraisal-record' import useAppraisalRecordStore from 'mocp/store/appraisal-record'
const tabList = ref([
{ name: 'OPEN', value: 1 },
{ name: 'CLOSE', value: 0 },
{ name: '全部', value: -1 }
])
//跳转 //跳转
const goDetails = (data) => { const goDetails = (data) => {
uni.$mocpJump.navigateTo('/panel/appraisal-record/details', { uni.$mocpJump.navigateTo('/panel/appraisal-record/details', {
...@@ -40,9 +49,17 @@ const appraisalRecordStore = useAppraisalRecordStore() ...@@ -40,9 +49,17 @@ const appraisalRecordStore = useAppraisalRecordStore()
onLoad(() => { onLoad(() => {
appraisalRecordStore.getRqmOptions() appraisalRecordStore.getRqmOptions()
}) })
//筛选
const handleRightClick = () => {
uni.$mocpJump.navigateTo('/panel/appraisal-record/search')
}
//刷新 //刷新
const searchParams = ref()
const paging = ref() const paging = ref()
uni.$on('appraisalRecordReload', () => { uni.$on('appraisalRecordReload', ({ params }) => {
if (params) {
searchParams.value = params
}
paging.value?.reload() paging.value?.reload()
}) })
onUnload(() => { onUnload(() => {
......
<template>
<global-page :padding="24" title="筛选">
<up-form labelPosition="left" labelWidth="auto" :model="formData" ref="formRef">
<up-form-item label="状态" prop="status" :borderBottom="true">
<global-picker
v-model="formData.status"
pickAlign="right"
clearable
:options="[
{ label: 'OPEN', value: '1' },
{ label: 'CLOSE', value: '0' }
]"
></global-picker>
</up-form-item>
<up-form-item label="是否有效" prop="valid" :borderBottom="true">
<global-picker
v-model="formData.valid"
pickAlign="right"
:options="[
{ label: '有效', value: '1' },
{ label: '无效', value: '0' }
]"
clearable
></global-picker>
</up-form-item>
<up-form-item label="基地/职能部门" prop="department" :borderBottom="true">
<global-picker v-model="formData.department" pickAlign="right" :options="department" clearable filter></global-picker>
</up-form-item>
<up-form-item label="考核对象" prop="appraisee" :borderBottom="true">
<global-picker v-model="formData.appraisee" pickAlign="right" :options="appraisee" clearable filter></global-picker>
</up-form-item>
<up-form-item label="事件类别" prop="eventType" :borderBottom="true">
<global-picker v-model="formData.eventType" pickAlign="right" clearable dictkey="ar_eventType"></global-picker>
</up-form-item>
<up-form-item label="机号" prop="ac" :borderBottom="true">
<global-picker v-model="formData.ac" pickAlign="right" clearable :options="deviceNumList" filter></global-picker>
</up-form-item>
<up-form-item label="日期" :borderBottom="true">
<global-calendar
pickAlign="right"
v-model:startTime="formData.startTime"
v-model:endTime="formData.stopTime"
clearable
></global-calendar>
</up-form-item>
</up-form>
<template #bottom>
<view class="footer-btn">
<up-row gutter="10">
<up-col span="6">
<global-button type="light" size="large" :radius="5" @tap="handleReset">重置</global-button>
</up-col>
<up-col span="6"><global-button type="primary" size="large" :radius="5" @tap="handleConfirm">确定</global-button></up-col>
</up-row>
</view>
</template>
</global-page>
</template>
<script setup>
import { formData, formRef } from './constants/search.compositions'
import useBaseStore from 'mocp/store/base'
import useAppraisalRecordStore from 'mocp/store/appraisal-record'
import { handleConfirm, handleReset } from './constants/search.functionals'
//获取下拉框选项
const {
selectList: { deviceNumList }
} = useBaseStore()
const {
selectList: { appraisee, department }
} = useAppraisalRecordStore()
</script>
<style lang="scss" scoped>
.footer-btn {
padding: 24rpx 32rpx;
background-color: #fff;
}
</style>
import { ref } from 'vue'
export const formRef = ref()
// 表单数据
export const formData = ref({
state: null,
terminal: '',
valid: null,
decisionState: null,
aviation: '',
machineNumber: '',
startTimeS: null,
startTimeE: null
})
export const status = ref([])
import { toRaw } from 'vue'
import { formData, formRef } from './search.compositions'
export const handleReset = () => {
formData.value = {
state: null,
presenter: '',
seat: '',
workType: null,
startTime: null,
stopTime: null
}
formRef.value?.resetFields()
handleConfirm()
}
export const handleConfirm = () => {
uni.$mocpJump.navigateBack()
uni.$emit('assignWorkReload', { params: toRaw(formData.value) })
}
<template> <template>
<global-page-swiper <global-page
title="布置工作" title="布置工作"
isDataList
refresherEnabled refresherEnabled
loadingMoreEnabled loadingMoreEnabled
:tabList="tabList" auto
ref="paging"
:params="searchParams"
:api="getArrangeWorkListApi" :api="getArrangeWorkListApi"
:padding="24" :padding="24"
tabValueField="state" showNavRight
navRightType="icon"
navRightIcon="saixuan-01"
@handleRightClick="handleRightClick"
> >
<template #="{ dataList }"> <template #="{ dataList }">
<view class="item" v-for="item in dataList" :key="item.id" @tap="goDetails(item)"> <view class="item" v-for="item in dataList" :key="item.id" @tap="goDetails(item)">
...@@ -36,25 +42,43 @@ ...@@ -36,25 +42,43 @@
</view> </view>
</view> </view>
</template> </template>
</global-page-swiper> </global-page>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue'
import useBaseStore from 'mocp/store/base' import useBaseStore from 'mocp/store/base'
import { timeStampFormat } from 'mocp/utils/tool' import { timeStampFormat } from 'mocp/utils/tool'
import { getArrangeWorkListApi } from 'mocp/api/assign-work' import { getArrangeWorkListApi } from 'mocp/api/assign-work'
import useAssignWorkStore from 'mocp/store/assign-work'
import { onLoad, onUnload } from '@dcloudio/uni-app'
import { ref } from 'vue'
const tabList = ref([
{ name: 'OPEN', value: 1 },
{ name: 'CLOSE', value: 2 },
{ name: '全部', value: null }
])
const baseStore = useBaseStore() const baseStore = useBaseStore()
//加载下拉框数据
const assignWorkStore = useAssignWorkStore()
onLoad(() => {
assignWorkStore.getSeatUnit()
})
//跳转 //跳转
const goDetails = (data) => { const goDetails = (data) => {
uni.$mocpJump.navigateTo('/panel/assign-work/details', { id: data.id }) uni.$mocpJump.navigateTo('/panel/assign-work/details', { id: data.id })
} }
//筛选
const handleRightClick = () => {
uni.$mocpJump.navigateTo('/panel/assign-work/search')
}
//刷新
const searchParams = ref()
const paging = ref()
uni.$on('assignWorkReload', ({ params }) => {
if (params) {
searchParams.value = params
}
paging.value?.reload()
})
onUnload(() => {
uni.$off('assignWorkReload')
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import './constants/list.scss'; @import './constants/list.scss';
......
<template>
<global-page :padding="24" title="筛选">
<up-form labelPosition="left" labelWidth="auto" :model="formData" ref="formRef">
<up-form-item label="任务状态" prop="state" :borderBottom="true">
<global-picker
v-model="formData.state"
pickAlign="right"
clearable
:options="[
{ label: 'OPEN', value: '1' },
{ label: 'CLOSE', value: '2' }
]"
></global-picker>
</up-form-item>
<up-form-item label="提出人" prop="presenter" :borderBottom="true">
<up-input v-model="formData.presenter" inputAlign="right" border="none" placeholder="请输入" clearable></up-input>
</up-form-item>
<up-form-item label="管理席位" prop="seat" :borderBottom="true">
<global-picker
v-model="formData.seat"
pickAlign="right"
:options="assignWorkStore.getSeatUnitSelect"
clearable
filter
></global-picker>
</up-form-item>
<up-form-item label="工作类型" prop="workType" :borderBottom="true">
<global-picker
v-model="formData.workType"
pickAlign="right"
:options="baseStore.getParamsByType('LayoutWorkType')"
clearable
filter
></global-picker>
</up-form-item>
<up-form-item label="开始日期" :borderBottom="true">
<global-calendar
pickAlign="right"
v-model:startTime="formData.startTimeS"
v-model:endTime="formData.startTimeE"
clearable
></global-calendar>
</up-form-item>
</up-form>
<template #bottom>
<view class="footer-btn">
<up-row gutter="10">
<up-col span="6">
<global-button type="light" size="large" :radius="5" @tap="handleReset">重置</global-button>
</up-col>
<up-col span="6"><global-button type="primary" size="large" :radius="5" @tap="handleConfirm">确定</global-button></up-col>
</up-row>
</view>
</template>
</global-page>
</template>
<script setup>
import { formData, formRef } from './constants/search.compositions'
import useBaseStore from 'mocp/store/base'
import useAssignWorkStore from 'mocp/store/assign-work'
import { handleConfirm, handleReset } from './constants/search.functionals'
//获取下拉框选项
const assignWorkStore = useAssignWorkStore()
const baseStore = useBaseStore()
</script>
<style lang="scss" scoped>
.footer-btn {
padding: 24rpx 32rpx;
background-color: #fff;
}
</style>
import { ref } from 'vue'
export const formRef = ref()
// 表单数据
export const formData = ref({
state: null,
presenter: '',
seat: '',
workType: null,
startDateTime: null,
endDateTime: null
})
export const status = ref([])
import { toRaw } from 'vue'
import { formData, formRef } from './search.compositions'
export const handleReset = () => {
formData.value = {
state: null,
presenter: '',
seat: '',
workType: null,
startTime: null,
stopTime: null
}
formRef.value?.resetFields()
handleConfirm()
}
export const handleConfirm = () => {
uni.$mocpJump.navigateBack()
uni.$emit('moveDecisionReload', { params: toRaw(formData.value) })
}
<template> <template>
<global-page-swiper <global-page
title="运行决策" title="运行决策"
isDataList
refresherEnabled refresherEnabled
loadingMoreEnabled loadingMoreEnabled
:tabList="tabList" auto
ref="paging"
:params="searchParams"
showNavRight
navRightType="icon"
navRightIcon="saixuan-01"
@handleRightClick="handleRightClick"
:api="getDecisionApi" :api="getDecisionApi"
:padding="24" :padding="24"
tabValueField="state"
> >
<template #="{ dataList }"> <template #="{ dataList }">
<view class="item" v-for="item in dataList" :key="item.id" @tap="goDetails(item)"> <view class="item" v-for="item in dataList" :key="item.id" @tap="goDetails(item)">
...@@ -33,7 +39,7 @@ ...@@ -33,7 +39,7 @@
</view> </view>
</view> </view>
</template> </template>
</global-page-swiper> </global-page>
</template> </template>
<script setup> <script setup>
...@@ -42,13 +48,8 @@ import { timeStampFormat } from 'mocp/utils/tool' ...@@ -42,13 +48,8 @@ import { timeStampFormat } from 'mocp/utils/tool'
import { getDecisionApi } from 'mocp/api/move-decision' import { getDecisionApi } from 'mocp/api/move-decision'
import { useGetDictByValue } from 'mocp/hooks/use-dict/useDict' import { useGetDictByValue } from 'mocp/hooks/use-dict/useDict'
import useMoveDecisionStore from 'mocp/store/move-decision' import useMoveDecisionStore from 'mocp/store/move-decision'
import { onUnload } from '@dcloudio/uni-app'
const tabList = ref([
{ name: 'OPEN', value: 1 },
{ name: 'CLOSE', value: 3 },
{ name: '跟踪', value: 2 },
{ name: '全部', value: null }
])
//跳转 //跳转
const moveDecisionStore = useMoveDecisionStore() const moveDecisionStore = useMoveDecisionStore()
const goDetails = (data) => { const goDetails = (data) => {
...@@ -56,6 +57,22 @@ const goDetails = (data) => { ...@@ -56,6 +57,22 @@ const goDetails = (data) => {
moveDecisionStore.setState('details', data) moveDecisionStore.setState('details', data)
}) })
} }
//筛选
const handleRightClick = () => {
uni.$mocpJump.navigateTo('/panel/move-decision/search')
}
//刷新
const searchParams = ref()
const paging = ref()
uni.$on('moveDecisionReload', ({ params }) => {
if (params) {
searchParams.value = params
}
paging.value?.reload()
})
onUnload(() => {
uni.$off('moveDecisionReload')
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import './constants/list.scss'; @import './constants/list.scss';
......
<template>
<global-page :padding="24" title="筛选">
<up-form labelPosition="left" labelWidth="auto" :model="formData" ref="formRef">
<up-form-item label="状态" prop="state" :borderBottom="true">
<global-picker
v-model="formData.state"
pickAlign="right"
clearable
:options="[
{ label: 'OPEN', value: 1 },
{ label: '跟踪', value: 2 },
{ label: 'CLOSE', value: 3 }
]"
></global-picker>
</up-form-item>
<up-form-item label="航站" prop="terminal" :borderBottom="true">
<global-picker pickAlign="right" v-model="formData.terminal" clearable :options="baseStore.getTerminalSelect" filter></global-picker>
</up-form-item>
<up-form-item label="是否有效" prop="valid" :borderBottom="true">
<global-picker
v-model="formData.valid"
pickAlign="right"
:options="[
{ label: '有效', value: '1' },
{ label: '无效', value: '0' }
]"
clearable
></global-picker>
</up-form-item>
<up-form-item label="决策结果" prop="decisionState" :borderBottom="true">
<global-picker
v-model="formData.decisionState"
pickAlign="right"
:options="[
{ label: '同意', value: '1' },
{ label: '不同意', value: '0' }
]"
clearable
></global-picker>
</up-form-item>
<up-form-item label="航司" prop="aviation" :borderBottom="true">
<global-picker v-model="formData.aviation" pickAlign="right" :options="baseStore.getAirlineSelect" clearable filter></global-picker>
</up-form-item>
<up-form-item label="机号" prop="machineNumber" :borderBottom="true">
<global-picker pickAlign="right" v-model="formData.machineNumber" :options="deviceNumList" clearable filter></global-picker>
</up-form-item>
<up-form-item label="日期" :borderBottom="true">
<global-calendar
pickAlign="right"
v-model:startTime="formData.startDateTime"
v-model:endTime="formData.endDateTime"
clearable
></global-calendar>
</up-form-item>
</up-form>
<template #bottom>
<view class="footer-btn">
<up-row gutter="10">
<up-col span="6">
<global-button type="light" size="large" :radius="5" @tap="handleReset">重置</global-button>
</up-col>
<up-col span="6"><global-button type="primary" size="large" :radius="5" @tap="handleConfirm">确定</global-button></up-col>
</up-row>
</view>
</template>
</global-page>
</template>
<script setup>
import { formData, formRef } from './constants/search.compositions'
import useBaseStore from 'mocp/store/base'
import { handleConfirm, handleReset } from './constants/search.functionals'
//获取下拉框选项
const baseStore = useBaseStore()
const {
selectList: { deviceNumList }
} = useBaseStore()
</script>
<style lang="scss" scoped>
.footer-btn {
padding: 24rpx 32rpx;
background-color: #fff;
}
</style>
...@@ -55,6 +55,12 @@ ...@@ -55,6 +55,12 @@
<ul class="icon_lists dib-box"> <ul class="icon_lists dib-box">
<li class="dib"> <li class="dib">
<span class="icon iconfont">&#xe6e2;</span>
<div class="name">saixuan</div>
<div class="code-name">&amp;#xe6e2;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6df;</span> <span class="icon iconfont">&#xe6df;</span>
<div class="name">jpg</div> <div class="name">jpg</div>
<div class="code-name">&amp;#xe6df;</div> <div class="code-name">&amp;#xe6df;</div>
...@@ -156,9 +162,9 @@ ...@@ -156,9 +162,9 @@
<pre><code class="language-css" <pre><code class="language-css"
>@font-face { >@font-face {
font-family: 'iconfont'; font-family: 'iconfont';
src: url('iconfont.woff2?t=1717745202331') format('woff2'), src: url('iconfont.woff2?t=1720423308442') format('woff2'),
url('iconfont.woff?t=1717745202331') format('woff'), url('iconfont.woff?t=1720423308442') format('woff'),
url('iconfont.ttf?t=1717745202331') format('truetype'); url('iconfont.ttf?t=1720423308442') format('truetype');
} }
</code></pre> </code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3> <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
...@@ -185,6 +191,15 @@ ...@@ -185,6 +191,15 @@
<ul class="icon_lists dib-box"> <ul class="icon_lists dib-box">
<li class="dib"> <li class="dib">
<span class="icon iconfont icon-saixuan-01"></span>
<div class="name">
saixuan
</div>
<div class="code-name">.icon-saixuan-01
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-jpg"></span> <span class="icon iconfont icon-jpg"></span>
<div class="name"> <div class="name">
jpg jpg
...@@ -339,6 +354,14 @@ ...@@ -339,6 +354,14 @@
<li class="dib"> <li class="dib">
<svg class="icon svg-icon" aria-hidden="true"> <svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-saixuan-01"></use>
</svg>
<div class="name">saixuan</div>
<div class="code-name">#icon-saixuan-01</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-jpg"></use> <use xlink:href="#icon-jpg"></use>
</svg> </svg>
<div class="name">jpg</div> <div class="name">jpg</div>
......
@font-face { @font-face {
font-family: "iconfont"; /* Project id 4550048 */ font-family: "iconfont"; /* Project id 4550048 */
src: url('iconfont.woff2?t=1717745202331') format('woff2'), src: url('iconfont.woff2?t=1720423308442') format('woff2'),
url('iconfont.woff?t=1717745202331') format('woff'), url('iconfont.woff?t=1720423308442') format('woff'),
url('iconfont.ttf?t=1717745202331') format('truetype'); url('iconfont.ttf?t=1720423308442') format('truetype');
} }
.iconfont { .iconfont {
...@@ -13,6 +13,10 @@ ...@@ -13,6 +13,10 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-saixuan-01:before {
content: "\e6e2";
}
.icon-jpg:before { .icon-jpg:before {
content: "\e6df"; content: "\e6df";
} }
......
...@@ -6,6 +6,13 @@ ...@@ -6,6 +6,13 @@
"description": "", "description": "",
"glyphs": [ "glyphs": [
{ {
"icon_id": "40993233",
"name": "saixuan",
"font_class": "saixuan-01",
"unicode": "e6e2",
"unicode_decimal": 59106
},
{
"icon_id": "40650590", "icon_id": "40650590",
"name": "jpg", "name": "jpg",
"font_class": "jpg", "font_class": "jpg",
......
## 1.5.2(2024-06-14)
修复错误style语法
## 1.5.1(2024-06-11)
修复弹窗确认与取消设置颜色不生效
## 1.5.0(2024-06-03)
1. 修复monthSwitch事件初始化时被触发的问题
2. monthSwitch事件新增fullDate属性(用来方便直接获取字符串形式的完整日期)
3. 日历新增confirmFullDate属性,用来指定在弹窗模式下的日期点击确认按钮时是否需要选择完整日期
## 1.4.9(2024-05-08)
更新域名
## 1.4.8(2024-04-22)
修复日历内外高度不一致的问题
## 1.4.7(2024-04-16)
增加 operationPosition 属性 用来控制弹窗日历取消和确认按钮的显示位置
## 1.4.6(2024-04-16)
新增属性 actBadgeColor, 当通过 `selected` 属性设置某个日期 `badgeColor`后,如果该日期被选择且主题色与 `badgeColor` 一致时,徽标会显示本颜色
## 1.4.5(2024-04-15)
1. 新增reset方法来重置日历数据
2. 新增插槽-operation 用来自定义弹窗日历确认和取消按钮
3. selected 属性新增 badgeColor 用来指定 badge 颜色
4. close 事件改为弹窗日历点击mask关闭时触发,新增cancel事件,弹窗日历点击取消时触发。
## 1.4.4(2024-01-19)
修复vue2初始化时使用同一引用类型造成的bug
## 1.4.3(2024-01-17)
优化切换折叠状态时的记录方式
## 1.4.2(2024-01-12)
优化 monthShowCurrentMonth 属性, 如果仅显示当月直接不展示该元素。
## 1.4.1(2024-01-12)
优化 monthShowCurrentMonth 属性, 如果仅显示当月直接不展示该元素。
## 1.4.0(2024-01-11)
修复type="week"时找不到
## 1.3.9(2024-01-10)
优化: 将日历日期宽度固定改为跟随父级来决定宽度,避免出现父元素宽度变化带来的对不齐
## 1.3.8(2024-01-04)
1. 增加节日
2. 日历增加自定义高度
3. vue页面日历折叠时增加动效
4. 增加头部插槽
5. 仅显示当月时自动扩大间距,不会再出现下面一排空白的尴尬情况了
## 1.3.7(2023-12-19)
修复回到今日时没有正确记录折叠日期
修复selected变化时无法正常更新打点信息
## 1.3.6(2023-12-13)
修复单选模式下选中时展示的错误的weeks
## 1.3.5(2023-12-13)
修复动态修改date以及其他会触发更新init的函数, swiper不对及只会更新一个下一个数据的bug
## 1.3.4(2023-12-08)
修复selectd没有启用深度监听,导致直接添加数组带来的异常
## 1.3.3(2023-11-23)
1. 修复weeks错误类型提示
2. 修复calendarChange返回month类型不对
## 1.3.2(2023-11-22)
修复将今日日期打点禁用后造成的bug
## 1.3.1(2023-11-21)
1. 修复wu-icon依赖缺失
2. 新增rangeHaveDisableTruncation属性, 用来指定范围选择遇到打点禁用日期是否进行截断
## 1.3.0(2023-11-19)
1. 日历新增类型(周、月日历)
2. 日历新增折叠功能
3. 日历新增以周几开始的属性(周日、周一)
## 1.2.9(2023-11-08)
1. 修复mode变化时,不会正确重置的问题
2. 优化月份大文字显示方式
## 1.2.8(2023-10-22)
新增maskClick用来控制是否点击遮罩层关闭
新增disabledChoice用来控制是否禁止点击日历
## 1.2.7(2023-09-22)
修复传date值情况下不会默认选中的bug
## 1.2.6(2023-09-22)
修改useToday描述
## 1.2.5(2023-09-22)
新增useToday属性用来指定是否使用今天作为默认时间
## 1.2.4(2023-09-21)
修复插入模式下顶部会显示弹窗关闭的内容
## 1.2.3(2023-09-20)
修复恢复默认数据错误的bug
## 1.2.2(2023-09-19)
新增rangeSameDay属性用来指定选日期范围选择时起始日期是否可以为同一天
## 1.2.1(2023-09-18)
1.修复wu-calendar回到今日错误
2.优化wu-calendar picker日期与当前日历日期同步
3.wu-calendar新增mode属性,用来控制单日期、多日期、日期选择范围模式
4.优化wu-calendar date属性来更好的指定多日期、范围日期的默认值
## 1.2.0(2023-09-17)
修复date变化时未成功重置
## 1.1.9(2023-09-17)
1. 新增mode属性用来指定日期选择模式
2. 增加多选
3. 增加范围选择模式、多选模式默认值
## 1.1.8(2023-09-12)
修复回到今日错误
新增日历picker日期与日历同步
## 1.1.7(2023-09-11)
自定义事件声明
## 1.1.6(2023-09-09)
增加 `rangeEndRepick` 属性,用来指定选择完成后点击选择范围内的日期是否可以重选结束日期
## 1.1.5(2023-09-09)
修复每月仅显示当月数据时上方星期错乱的问题
## 1.1.4(2023-09-05)
1. 优化动态计算算法
2. 优化弹窗模式打开缓慢的问题
3. 优化Color方法
## 1.1.3(2023-09-03)
新增插件预览图片
## 1.1.2(2023-09-02)
1. 新增monthShowCurrentMonth 用来设置是否每月仅展示当月数据
2. 修复动态加载时下一月数据更新错误问题
3. 修复confirm和change事件选中的列表中有被禁止的日期的问题
## 1.1.1(2023-08-31)
修复在插入模式中无法滑动的bug
## 1.1.0(2023-08-29)
修复回到今日bug(来自群里464与A毛毛大佬的测试)
## 1.0.9(2023-08-29)
修复依赖缺失
## 1.0.8(2023-08-22)
修复v2初始化时使用不存在的属性导致不可使用的bug(来自wu-ui群内攸宁大佬的反馈)
## 1.0.7(2023-08-21)
阻止默认滑动事件执行
## 1.0.6(2023-08-21)
修复支付宝高度消失的问题
## 1.0.5(2023-08-21)
修改说明
## 1.0.4(2023-08-20)
去除误加打印
## 1.0.3(2023-08-20)
1. 修复初始化时下个月份日期计算不对的问题
2. 增加打点禁用、设置打点徽标位置
## 1.0.2(2023-08-20)
更新展示截图
## 1.0.1(2023-08-20)
修改展示截图及说明
## 1.0.0(2023-08-20)
动态滑动计算的日历插件,还可以设置滑动切换模式、自定义主题颜色、自定义文案、农历显示等功能,可以让您纵享丝滑的使用日历。
{
"wu-calender.ok": "ok",
"wu-calender.cancel": "cancel",
"wu-calender.year": "year",
"wu-calender.month": "month",
"wu-calender.today": "today",
"wu-calender.MON": "MON",
"wu-calender.TUE": "TUE",
"wu-calender.WED": "WED",
"wu-calender.THU": "THU",
"wu-calender.FRI": "FRI",
"wu-calender.SAT": "SAT",
"wu-calender.SUN": "SUN"
}
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
en,
'zh-Hans': zhHans,
'zh-Hant': zhHant
}
{
"wu-calender.ok": "确定",
"wu-calender.cancel": "取消",
"wu-calender.year": "年",
"wu-calender.month": "月",
"wu-calender.today": "今日",
"wu-calender.SUN": "日",
"wu-calender.MON": "一",
"wu-calender.TUE": "二",
"wu-calender.WED": "三",
"wu-calender.THU": "四",
"wu-calender.FRI": "五",
"wu-calender.SAT": "六"
}
{
"wu-calender.ok": "確定",
"wu-calender.cancel": "取消",
"wu-calender.year": "年",
"wu-calender.month": "月",
"wu-calender.today": "今日",
"wu-calender.SUN": "日",
"wu-calender.MON": "一",
"wu-calender.TUE": "二",
"wu-calender.WED": "三",
"wu-calender.THU": "四",
"wu-calender.FRI": "五",
"wu-calender.SAT": "六"
}
export default {
props: {
showMonth: {
type: Boolean,
default: false
},
// 折叠状态
FoldStatus: {
type: String,
default: null
},
month: {
type: [Number, String],
default: null
},
color: {
type: String,
default: '#3c9cff'
},
startText: {
type: String,
default: '开始'
},
endText: {
type: String,
default: '结束'
},
weeks: {
type: [Object, Array],
default: ()=> {
return []
}
},
calendar: {
type: Object,
default: () => {
return {}
}
},
selected: {
type: Array,
default: () => {
return []
}
},
lunar: {
type: Boolean,
default: false
},
itemHeight: {
type: Number,
default: 64
},
monthShowCurrentMonth: {
type: Boolean,
default: false
},
actBadgeColor: {
type: String,
default: '#fff'
},
}
}
\ No newline at end of file
<template>
<view class="wu-calendar-block">
<view v-if="showMonth && FoldShowMonth" class="wu-calendar__box-bg">
<text class="wu-calendar__box-bg-text">{{month}}</text>
</view>
<!-- 月或周日历 -->
<view class="wu-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
<view class="wu-calendar__weeks-item" v-for="(weeks, weeksIndex) in item" :key="weeksIndex" :style="[weekItemStyle]">
<wu-calendar-item v-if="!monthShowCurrentMonth || !weeks.empty" class="wu-calendar-item--hook" :weeks="weeks" :calendar="calendar"
:selected="selected" :lunar="lunar" @change="choiceDate" :color="color" :actBadgeColor="actBadgeColor"
:startText="startText" :endText="endText" :itemHeight="itemHeight - defaultMargin"></wu-calendar-item>
</view>
</view>
</view>
</template>
<script>
import mpMixin from '@/uni_modules/wu-ui-tools/libs/mixin/mpMixin.js';
import mixin from '@/uni_modules/wu-ui-tools/libs/mixin/mixin.js';
import props from './props.js';
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import i18nMessages from '../i18n/index.js'
const {
t
} = initVueI18n(i18nMessages)
export default {
emits: ['change'],
mixins: [mpMixin, mixin, props],
data() {
return {
FoldShowMonth: false,
// 默认边距
defaultMargin: 8
}
},
mounted() {
this.FoldShowMonth = this.FoldStatus == 'open';
},
computed: {
weekItemStyle() {
let weeksLength = Object.keys(this.weeks).length;
let calendarHeight = this.FoldStatus === 'open' ? this.itemHeight * 6 : this.itemHeight;
let margin = weeksLength && this.weeks[weeksLength - 1][0].empty ? this.itemHeight / (weeksLength - 1) + this.defaultMargin : this.defaultMargin
return {
marginTop: margin / 2 + 'px',
marginBottom: margin / 2 + 'px',
}
}
},
watch: {
FoldStatus(newVal) {
this.$nextTick(()=>{
this.FoldShowMonth = this.FoldStatus == 'open';
})
}
},
methods: {
choiceDate(weeks) {
this.$emit('change', weeks)
}
}
}
</script>
<style lang="scss" scoped>
$wu-text-color-grey: #999;
.wu-calendar-block {
.wu-calendar__weeks {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
padding: 0 8rpx;
}
.wu-calendar__weeks-item {
flex: 1;
}
.wu-calendar__box-bg {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.wu-calendar__box-bg-text {
font-size: 100rpx;
transform: scale(4);
font-weight: bold;
color: $wu-text-color-grey;
opacity: 0.1;
text-align: center;
/* #ifndef APP-NVUE */
line-height: 1;
/* #endif */
}
}
</style>
\ No newline at end of file
export default {
props: {
color: {
type: String,
default: '#3c9cff'
},
startText: {
type: String,
default: '开始'
},
endText: {
type: String,
default: '结束'
},
weeks: {
type: Object,
default () {
return {}
}
},
calendar: {
type: Object,
default: () => {
return {}
}
},
selected: {
type: Array,
default: () => {
return []
}
},
lunar: {
type: Boolean,
default: false
},
itemHeight: {
type: Number,
default: 64
},
actBadgeColor: {
type: String,
default: '#fff',
}
}
}
\ No newline at end of file
<template>
<view class="wu-calendar-item__weeks-box" ref="$weeksbox" :style="[calendarItemStyle, {
borderTopLeftRadius: weeks.beforeRange ? '12rpx' : '',
borderBottomLeftRadius: weeks.beforeRange ? '12rpx' : '',
borderTopRightRadius: weeks.afterRange ? '12rpx' : '',
borderBottomRightRadius: weeks.afterRange ? '12rpx' : '',
}]" @click="choiceDate(weeks)">
<view class="wu-calendar-item__weeks-box-item" :style="[actMultipleStyle, {height: itemHeight + 'px'}]">
<!-- 自定义打点上方信息 -->
<text v-if="weeks.extraInfo && weeks.extraInfo.topInfo" class="wu-calendar-item__weeks-lunar-text" :style="[{color: weeks.extraInfo.topInfoColor || '#e43d33'}, calendarItemStyle, actMultipleStyle]">{{weeks.extraInfo.topInfo}}</text>
<!-- 徽标 -->
<text v-if="selected && weeks.extraInfo && weeks.extraInfo.badge" class="wu-calendar-item__weeks-box-circle" :style="[badgeStyle]"></text>
<!-- 日期文字 -->
<text class="wu-calendar-item__weeks-box-text" :style="[calendarItemStyle, actMultipleStyle]">{{weeks.date}}</text>
<!-- 今日的文字 -->
<text v-if="!lunar && !weeks.extraInfo && weeks.isDay && !weeks.beforeRange && !weeks.afterRange" class="wu-calendar-item__weeks-lunar-text" :style="[calendarItemStyle, actMultipleStyle]">{{todayText}}</text>
<!-- 农历文字 -->
<text v-if="lunar && !weeks.extraInfo && !weeks.beforeRange && !weeks.afterRange" class="wu-calendar-item__weeks-lunar-text" :style="[calendarItemStyle, actMultipleStyle]">{{dayText}}</text>
<!-- 选中的文字展示 -->
<text v-if="!weeks.extraInfo && (weeks.beforeRange || weeks.afterRange)" class="wu-calendar-item__weeks-lunar-text" :style="[calendarItemStyle, actMultipleStyle]">{{multipleText}}</text>
<!-- 自定义打点下方信息 -->
<text v-if="weeks.extraInfo && weeks.extraInfo.info" class="wu-calendar-item__weeks-lunar-text" :style="[{color: weeks.extraInfo.infoColor || '#e43d33'}, calendarItemStyle, actMultipleStyle]">{{weeks.extraInfo.info}}</text>
</view>
</view>
</template>
<script>
import mpMixin from '@/uni_modules/wu-ui-tools/libs/mixin/mpMixin.js';
import mixin from '@/uni_modules/wu-ui-tools/libs/mixin/mixin.js';
import props from './props.js';
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import i18nMessages from '../i18n/index.js'
const {
t
} = initVueI18n(i18nMessages)
export default {
emits: ['change'],
mixins: [mpMixin, mixin, props],
computed: {
todayText() {
return t("wu-calender.today")
},
// 每项日历样式
calendarItemStyle() {
let style = {};
let color = this.$w.Color.gradient(this.color, this.$w.Color.isLight(this.color) ? '#000' : '#fff', 100)[6]
// 有顺序别乱动
// 选中的日期范围内的样式
if (this.weeks.rangeMultiple) {
style = {
backgroundColor: this.$w.Color.gradient(this.color, '#fff', 100)[80],
color
}
};
// 今天的日期样式
if (this.weeks.isDay) {
style.color = color;
}
// 禁用的日期样式
if(this.weeks.disable) {
style = {
backgroundColor: 'rgba(249, 249, 249, 0.3)',
color: '#c0c0c0'
}
}
return style;
},
// 选中的日期样式
actMultipleStyle() {
if ((this.weeks.beforeRange || this.weeks.afterRange || this.weeks.multiples || (this.calendar.fullDate === this.weeks
.fullDate && this.weeks.mode === 'single')) && !this.weeks.disable) {
return {
backgroundColor: this.color,
color: '#fff',
borderRadius: '12rpx'
}
}
},
// 徽标样式
badgeStyle() {
let style = {
backgroundColor: this.weeks.disable ? '#c0c0c0' : '#e43d33',
width: '16rpx',
height: '16rpx'
};
if(this.weeks.extraInfo) {
if(this.weeks.extraInfo.badgeColor) {
// 如果当前是选中日期的徽标且徽标颜色与主题色一致 为了保证 徽标颜色可以被看见 再选中时将其设置为 #fff
if ((this.weeks.beforeRange || this.weeks.afterRange || this.weeks.multiples || (this.calendar.fullDate === this.weeks
.fullDate && this.weeks.mode === 'single')) && !this.weeks.disable && this.$w.Color.convertFormat(this.weeks.extraInfo.badgeColor) == this.$w.Color.convertFormat(this.color)) {
style.backgroundColor = this.actBadgeColor;
} else {
style.backgroundColor = this.weeks.extraInfo.badgeColor
}
}
if(this.weeks.extraInfo.badgeSize) {
style.width = this.weeks.extraInfo.badgeSize
style.height = this.weeks.extraInfo.badgeSize
}
if(!this.weeks.extraInfo.badgePosition) {
style.right = '10rpx';
style.top = '10rpx';
} else if(this.weeks.extraInfo.badgePosition == 'top-left'){
style.top = '10rpx';
style.left = '10rpx';
} else if(this.weeks.extraInfo.badgePosition == 'top-center'){
style.top = '10rpx';
style.left = 'center';
} else if(this.weeks.extraInfo.badgePosition == 'top-right'){
style.top = '10rpx';
style.right = '10rpx';
} else if(this.weeks.extraInfo.badgePosition == 'bottom-left'){
style.bottom = '10rpx';
style.left = '10rpx';
} else if(this.weeks.extraInfo.badgePosition == 'bottom-center'){
style.bottom = '10rpx';
style.left = 'center';
} else if(this.weeks.extraInfo.badgePosition == 'bottom-right'){
style.bottom = '10rpx';
style.right = '10rpx';
}
}
return style
},
// 日期文字
dayText() {
let text = '';
if (this.weeks.isDay) {
text = this.todayText
} else if(this.weeks.lunar.festival) {
text = this.weeks.lunar.festival
} else if(this.weeks.lunar.isTerm) {
text = this.weeks.lunar.Term
} else if (this.weeks.lunar.IDayCn === '初一') {
text = this.weeks.lunar.IMonthCn
} else {
text = this.weeks.lunar.IDayCn
}
return text
},
// 选中的文字
multipleText() {
let text = '';
if (this.weeks.afterRange) {
text = this.endText
} else if (this.weeks.beforeRange) {
text = this.startText
}
return text;
}
},
methods: {
choiceDate(weeks) {
this.$emit('change', weeks)
}
}
}
</script>
<style lang="scss" scoped>
@import '@/uni_modules/wu-ui-tools/theme.scss';
$wu-font-size-base: 28rpx;
$wu-text-color: #333;
$wu-font-size-sm: 24rpx;
$wu-color-error: #e43d33;
$wu-opacity-disabled: 0.3;
$wu-text-color-disable: #c0c0c0;
.wu-calendar-item__weeks-box {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
padding: 0 0.5px;
}
.wu-calendar-item__weeks-box-text {
font-size: $wu-font-size-base;
color: $wu-text-color;
}
.wu-calendar-item__weeks-lunar-text {
font-size: $wu-font-size-sm;
color: $wu-text-color;
}
.wu-calendar-item__weeks-box-item {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
}
.wu-calendar-item__weeks-box-circle {
position: absolute;
border-radius: 16rpx;
background-color: $wu-color-error;
}
.wu-calendar-item--disable {
background-color: rgba(249, 249, 249, $wu-opacity-disabled);
color: $wu-text-color-disable;
}
.wu-calendar-item--extra {
color: $wu-color-error;
opacity: 0.8;
}
.wu-calendar-item--checked {
color: #fff;
}
</style>
\ No newline at end of file
export default {
props: {
// 自定义当前时间
date: {
type: [String, Array],
default: ''
},
// 日历类型(默认为month)
type: {
type: String,
default: 'month',
validator(value) {
return ['month', 'week'].includes(value)
}
},
// 日期选择模式
mode: {
type: String,
default: 'single'
},
// 是否使用默认日期(今天,默认为true)
useToday: {
type: Boolean,
default: true
},
// 是否使用折叠功能
fold: {
type: Boolean,
default: null
},
// 主题色
color: {
type: String,
default: '#3c9cff'
},
// 日历中每一项日期的高度(默认70),单位px
itemHeight: {
type: Number,
default: 70
},
// 取消文字的颜色
cancelColor: {
type: String,
default: '#333'
},
// 确定文字的颜色
confirmColor: {
type: String,
default: '#333'
},
// mode=range时,第一个日期底部的提示文字
startText: {
type: String,
default: '开始'
},
// mode=range时,最后一个日期底部的提示文字
endText: {
type: String,
default: '结束'
},
// 日历以周几开始
startWeek: {
type: String,
default: 'sun',
validator(value) {
return ['sun', 'mon'].includes(value)
}
},
// 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]
selected: {
type: Array,
default () {
return []
}
},
// 是否显示农历
lunar: {
type: Boolean,
default: false
},
// 日期选择范围-开始日期
startDate: {
type: String,
default: ''
},
// 日期选择范围-结束日期
endDate: {
type: String,
default: ''
},
// 允许日期选择范围内重选结束日期
rangeEndRepick: {
type: Boolean,
default: false
},
// 允许日期选择范围起始日期为同一天
rangeSameDay: {
type: Boolean,
default: false
},
// 允许日期选择范围内遇到打点禁用日期进行截断
rangeHaveDisableTruncation: {
type: Boolean,
default: false
},
// 每月仅显示当月日期
monthShowCurrentMonth: {
type: Boolean,
default: false
},
// 插入模式,可选值,ture:插入模式;false:弹窗模式; 默认为插入模式
insert: {
type: Boolean,
default: true
},
// 滑动切换模式,可选值 horizontal: 横向 vertical:纵向 none: 不使用滑动切换
slideSwitchMode: {
type: String,
default: 'horizontal'
},
// 是否显示月份为背景
showMonth: {
type: Boolean,
default: true
},
// 弹窗模式是否清空上次选择内容
clearDate: {
type: Boolean,
default: true
},
// 是否点击遮罩层关闭
maskClick: {
type: Boolean,
default: false
},
// 是否禁止点击日历
disabledChoice: {
type: Boolean,
default: false
},
// 弹窗日历取消和确认按钮的显示位置
operationPosition: {
type: String,
default: 'top',
validator(value) {
return ['top', 'bottom'].includes(value)
}
},
// 弹窗日历点击确认时是否需要选择完整日期
confirmFullDate: {
type: Boolean,
default: false
},
// 当通过 `selected` 属性设置某个日期 `badgeColor`后,如果该日期被选择且主题色与 `badgeColor` 一致时,徽标会显示本颜色
actBadgeColor: {
type: String,
default: '#fff'
},
...uni.$w?.props?.calendar
}
}
\ No newline at end of file
{
"id": "wu-calendar",
"displayName": "wu-calendar 最全日历,动态滑动切换、多滑动模式、多日历类型、多日期选择模式等,全端兼容,无论平台,一致体验。",
"version": "1.5.2",
"description": "唯一支持动态滑动计算的日历插件,多滑动切换模式(纵、横、不滑动)、多日历类型(周、月)、多日期选择模式(单选、多选、范围)、日历周几(周日、周一)、自定义主题、农历显示等,可以让您纵享丝滑的使用日历",
"keywords": [
"wu-calendar",
"日历",
"多日历类型",
"动态滑动计算",
"wu-ui"
],
"repository": "",
"engines": {
"HBuilderX": "^3.5.5"
},
"dcloudext": {
"type": "component-vue",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [
"wu-ui-tools",
"wu-icon",
"wu-safe-bottom"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "y"
},
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"钉钉": "n",
"快手": "n",
"飞书": "n",
"京东": "n"
},
"快应用": {
"华为": "n",
"联盟": "n"
}
}
}
}
}
\ No newline at end of file
## wu-calendar 最全日历
> **组件名:wu-calendar**
目前插件市场上唯一可以动态滑动计算的日历插件,多滑动切换模式(纵、横向滑动,不滑动)、多日历类型(周、月日历)、多日历选择模式(日期单选、多选、范围选择)、多日历起始周几设置(周日、周一)、自定义主题颜色(副色自动生成)、自定义文案、农历显示等功能,可以让您纵享丝滑的使用日历。
## [查看文档](https://wuui.cn/zh-CN/components/calendar.html)
## [更多组件, 请查看 `wu-ui` 组件库](https://ext.dcloud.net.cn/plugin?name=wu--ui)
(请勿下载插件zip)
<a href="https://ext.dcloud.net.cn/plugin?name=wu--ui">
<img src="https://wuui.cn/intr.png">
</a>
**如使用过程中有任何问题,或者您对wu-ui有一些好的建议。<br>欢迎加入 [wu-ui 交流群](https://wuui.cn/zh-CN/components/qqFeedBack.html)**
\ No newline at end of file
## 1.0.4(2024-05-08)
更新域名
## 1.0.3(2023-08-08)
修复链接引入错误
## 1.0.2(2023-08-07)
修复引入错误
## 1.0.1(2023-08-07)
支持自定义(包括nvue)文字与图片图标
## 1.0.0(2023-08-03)
基于字体的图标集,包含了大多数常见场景的图标,支持自定义,支持自定义图片图标等。可自定义颜色、大小。
export default {
'wuicon-level': 'e68f',
'wuicon-download': 'e670',
'wuicon-search': 'e632',
'wuicon-reload': 'e627',
'wuicon-scan': 'e631',
'wuicon-calendar': 'e65c',
'wuicon-bag': 'e647',
'wuicon-checkbox-mark': 'e659',
'wuicon-attach': 'e640',
'wuicon-wifi-off': 'e6cc',
'wuicon-woman': 'e626',
'wuicon-man': 'e675',
'wuicon-chat': 'e656',
'wuicon-chat-fill': 'e63f',
'wuicon-red-packet': 'e6c3',
'wuicon-folder': 'e694',
'wuicon-order': 'e695',
'wuicon-arrow-up-fill': 'e636',
'wuicon-arrow-down-fill': 'e638',
'wuicon-backspace': 'e64d',
'wuicon-photo': 'e60d',
'wuicon-photo-fill': 'e6b4',
'wuicon-lock': 'e69d',
'wuicon-lock-fill': 'e6a6',
'wuicon-lock-open': 'e68d',
'wuicon-lock-opened-fill': 'e6a1',
'wuicon-home': 'e67b',
'wuicon-home-fill': 'e68e',
'wuicon-star': 'e618',
'wuicon-star-fill': 'e61e',
'wuicon-share': 'e629',
'wuicon-share-fill': 'e6bb',
'wuicon-share-square': 'e6c4',
'wuicon-volume': 'e605',
'wuicon-volume-fill': 'e624',
'wuicon-volume-off': 'e6bd',
'wuicon-volume-off-fill': 'e6c8',
'wuicon-trash': 'e623',
'wuicon-trash-fill': 'e6ce',
'wuicon-shopping-cart': 'e6cb',
'wuicon-shopping-cart-fill': 'e630',
'wuicon-question-circle': 'e622',
'wuicon-question-circle-fill': 'e6bc',
'wuicon-plus': 'e625',
'wuicon-plus-circle': 'e603',
'wuicon-plus-circle-fill': 'e611',
'wuicon-tags': 'e621',
'wuicon-tags-fill': 'e613',
'wuicon-pause': 'e61c',
'wuicon-pause-circle': 'e696',
'wuicon-pause-circle-fill': 'e60c',
'wuicon-play-circle': 'e6af',
'wuicon-play-circle-fill': 'e62a',
'wuicon-map': 'e665',
'wuicon-map-fill': 'e6a8',
'wuicon-phone': 'e6ba',
'wuicon-phone-fill': 'e6ac',
'wuicon-list': 'e690',
'wuicon-list-dot': 'e6a9',
'wuicon-info-circle': 'e69f',
'wuicon-info-circle-fill': 'e6a7',
'wuicon-minus': 'e614',
'wuicon-minus-circle': 'e6a5',
'wuicon-mic': 'e66d',
'wuicon-mic-off': 'e691',
'wuicon-grid': 'e68c',
'wuicon-grid-fill': 'e698',
'wuicon-eye': 'e664',
'wuicon-eye-fill': 'e697',
'wuicon-eye-off': 'e69c',
'wuicon-eye-off-outline': 'e688',
'wuicon-file-text': 'e687',
'wuicon-file-text-fill': 'e67f',
'wuicon-edit-pen': 'e65d',
'wuicon-edit-pen-fill': 'e679',
'wuicon-email': 'e673',
'wuicon-email-fill': 'e683',
'wuicon-checkmark': 'e64a',
'wuicon-checkmark-circle': 'e643',
'wuicon-checkmark-circle-fill': 'e668',
'wuicon-clock': 'e66c',
'wuicon-clock-fill': 'e64b',
'wuicon-close': 'e65a',
'wuicon-close-circle': 'e64e',
'wuicon-close-circle-fill': 'e666',
'wuicon-car': 'e64f',
'wuicon-car-fill': 'e648',
'wuicon-bell': 'e651',
'wuicon-bell-fill': 'e604',
'wuicon-play-left': 'e6bf',
'wuicon-play-right': 'e6b3',
'wuicon-play-left-fill': 'e6ae',
'wuicon-play-right-fill': 'e6ad',
'wuicon-skip-back-left': 'e6c5',
'wuicon-skip-forward-right': 'e61f',
'wuicon-setting': 'e602',
'wuicon-setting-fill': 'e6d0',
'wuicon-more-dot-fill': 'e66f',
'wuicon-more-circle': 'e69e',
'wuicon-more-circle-fill': 'e684',
'wuicon-arrow-upward': 'e641',
'wuicon-arrow-downward': 'e634',
'wuicon-arrow-leftward': 'e63b',
'wuicon-arrow-rightward': 'e644',
'wuicon-arrow-up': 'e633',
'wuicon-arrow-down': 'e63e',
'wuicon-arrow-left': 'e646',
'wuicon-arrow-right': 'e63c',
'wuicon-thumb-up': 'e612',
'wuicon-thumb-up-fill': 'e62c',
'wuicon-thumb-down': 'e60a',
'wuicon-thumb-down-fill': 'e628',
'wuicon-coupon': 'e65f',
'wuicon-coupon-fill': 'e64c',
'wuicon-kefu-ermai': 'e660',
'wuicon-server-fill': 'e610',
'wuicon-server-man': 'e601',
'wuicon-warning': 'e6c1',
'wuicon-warning-fill': 'e6c7',
'wuicon-camera': 'e642',
'wuicon-camera-fill': 'e650',
'wuicon-pushpin': 'e6d1',
'wuicon-pushpin-fill': 'e6b6',
'wuicon-heart': 'e6a2',
'wuicon-heart-fill': 'e68b',
'wuicon-account': 'e63a',
'wuicon-account-fill': 'e653',
'wuicon-integral': 'e693',
'wuicon-integral-fill': 'e6b1',
'wuicon-gift': 'e680',
'wuicon-gift-fill': 'e6b0',
'wuicon-empty-data': 'e671',
'wuicon-empty-address': 'e68a',
'wuicon-empty-favor': 'e662',
'wuicon-empty-car': 'e656',
'wuicon-empty-order': 'e66b',
'wuicon-empty-list': 'e671',
'wuicon-empty-search': 'e677',
'wuicon-empty-permission': 'e67c',
'wuicon-empty-news': 'e67d',
'wuicon-empty-history': 'e684',
'wuicon-empty-coupon': 'e69b',
'wuicon-empty-page': 'e60e',
'wuicon-apple-fill': 'e635',
'wuicon-zhifubao-circle-fill': 'e617',
'wuicon-weixin-circle-fill': 'e6cd',
'wuicon-weixin-fill': 'e620',
'wuicon-qq-fill': 'e608',
'wuicon-qq-circle-fill': 'e6b9',
'wuicon-moments': 'e6a0',
'wuicon-moments-circel-fill': 'e6c2',
'wuicon-twitter': 'e607',
'wuicon-twitter-circle-fill': 'e6cf',
}
\ No newline at end of file
export default {
props: {
// 图标类名
name: {
type: String,
default: ''
},
// 图标颜色,可接受主题色
color: {
type: String,
default: '#606266'
},
// 字体大小,单位px
size: {
type: [String, Number],
default: '16px'
},
// 是否显示粗体
bold: {
type: Boolean,
default: false
},
// 点击图标的时候传递事件出去的index(用于区分点击了哪一个)
index: {
type: [String, Number],
default: null
},
// 触摸图标时的类名
hoverClass: {
type: String,
default: ''
},
// 自定义扩展前缀,方便用户扩展自己的图标库
customPrefix: {
type: String,
default: 'wuicon'
},
// 图标右边或者下面的文字
label: {
type: [String, Number],
default: ''
},
// label的位置,只能右边或者下边
labelPos: {
type: String,
default: 'right'
},
// label的大小
labelSize: {
type: [String, Number],
default: '15px'
},
// label的颜色
labelColor: {
type: String,
default: '#606266'
},
// label与图标的距离
space: {
type: [String, Number],
default: '3px'
},
// 图片的mode
imgMode: {
type: String,
default: ''
},
// 用于显示图片小图标时,图片的宽度
width: {
type: [String, Number],
default: ''
},
// 用于显示图片小图标时,图片的高度
height: {
type: [String, Number],
default: ''
},
// 用于解决某些情况下,让图标垂直居中的用途
top: {
type: [String, Number],
default: 0
},
// 是否阻止事件传播
stop: {
type: Boolean,
default: false
},
...uni.$w?.props?.icon
}
}
\ No newline at end of file
<template>
<view class="wu-icon" @tap="clickHandler" :class="['wu-icon--' + labelPos]">
<!-- 这里进行空字符串判断,如果仅仅是v-if="label",可能会出现传递0的时候,结果也无法显示 -->
<text v-if="label !== '' && (labelPos == 'left' || labelPos == 'top')" class="wu-icon__label" :style="labelStyle">{{ label }}</text>
<image class="wu-icon__img" v-if="isImg" :src="name" :mode="imgMode"
:style="[imgStyle, $w.addStyle(customStyle)]"></image>
<text v-else class="wu-icon__icon" :class="uClasses" :style="[iconStyle, $w.addStyle(customStyle)]"
:hover-class="hoverClass">{{icon}}</text>
<!-- 这里进行空字符串判断,如果仅仅是v-if="label",可能会出现传递0的时候,结果也无法显示 -->
<text v-if="label !== '' && (labelPos == 'right' || labelPos == 'bottom')" class="wu-icon__label" :style="labelStyle">{{ label }}</text>
</view>
</template>
<script>
import mpMixin from '@/uni_modules/wu-ui-tools/libs/mixin/mpMixin.js'
import mixin from '@/uni_modules/wu-ui-tools/libs/mixin/mixin.js'
// #ifdef APP-NVUE
// nvue通过weex的dom模块引入字体,相关文档地址如下:
// https://weex.apache.org/zh/docs/modules/dom.html#addrule
import iconUrl from './wuicons.ttf';
const domModule = weex.requireModule('dom');
domModule.addRule('fontFace', {
'fontFamily': "wuicon-iconfont",
'src': "url('" + iconUrl + "')"
})
// #endif
// 引入图标名称,已经对应的unicode
import icons from './icons';
import props from './props.js';
/**
* icon 图标
* @description 基于字体的图标集,包含了大多数常见场景的图标。
* @tutorial https://wuui.cn/zh-CN/components/icon.html
* @property {String} name 图标名称,若带有 `/` 或遵循 `base64` 图片格式,会被认为是图片图标,则文字图标相关属性会失效。
* @property {String} color 图标颜色,可接受主题色 (默认 color: #606266 )
* @property {String | Number} size 图标字体大小,单位px/rpx (默认 '16px' )
* @property {Boolean} bold 是否显示粗体 (默认 false )
* @property {String | Number} index 点击图标的时候传递事件出去的index(用于区分点击了哪一个)
* @property {String} hoverClass 图标按下去的样式类,用法同uni的view组件的hoverClass参数,详情见官网
* @property {String} customPrefix 自定义扩展前缀,方便用户扩展自己的图标库 (默认 'wuicon' )
* @property {String | Number} label 图标右侧的label文字
* @property {String} labelPos label相对于图标的位置(默认 'right' )
* @value top 上方
* @value bottom 下方
* @value left 左侧
* @value right 右侧
* @property {String | Number} labelSize label字体大小,单位px (默认 '15px' )
* @property {String} labelColor 图标右侧的label文字颜色 ( 默认 color['wu-content-color'] )
* @property {String | Number} space label与图标的距离,单位px (默认 '3px' )
* @property {String} imgMode image组件的mode,详见:[image](https://uniapp.dcloud.net.cn/component/image.html#image)
* @property {String | Number} width 显示图片小图标时的宽度
* @property {String | Number} height 显示图片小图标时的高度
* @property {String | Number} top 图标在垂直方向上的定位 用于解决某些情况下,让图标垂直居中的用途 (默认 0 )
* @property {Boolean} stop 是否阻止事件传播 (默认 false )
* @property {Object} customStyle icon的样式,对象形式
* @event {Function} click 点击图标时触发
* @event {Function} touchstart 事件触摸时触发
* @example <wu-icon name="photo" color="#2979ff" size="28"></wu-icon>
*/
export default {
name: 'wu-icon',
emits: ['click'],
mixins: [mpMixin, mixin, props],
data() {
return {
colorType: [
'primary',
'success',
'info',
'error',
'warning'
]
}
},
computed: {
uClasses() {
let classes = []
classes.push(this.customPrefix)
classes.push(this.customPrefix + '-' + this.name)
// 主题色,通过类配置
if (this.color && this.colorType.includes(this.color)) classes.push('wu-icon__icon--' + this.color)
// 阿里,头条,百度小程序通过数组绑定类名时,无法直接使用[a, b, c]的形式,否则无法识别
// 故需将其拆成一个字符串的形式,通过空格隔开各个类名
//#ifdef MP-ALIPAY || MP-TOUTIAO || MP-BAIDU
classes = classes.join(' ')
//#endif
return classes
},
iconStyle() {
let style = {}
style = {
fontSize: this.$w.addUnit(this.size),
lineHeight: this.$w.addUnit(this.size),
fontWeight: this.bold ? 'bold' : 'normal',
// 某些特殊情况需要设置一个到顶部的距离,才能更好的垂直居中
top: this.$w.addUnit(this.top)
}
// 非主题色值时,才当作颜色值
if (this.color && !this.colorType.includes(this.color)) style.color = this.color
return style
},
// 判断传入的name属性,是否图片路径,只要带有"/"均认为是图片形式
isImg() {
const isBase64 = this.name.indexOf('data:') > -1 && this.name.indexOf('base64') > -1;
return this.name.indexOf('/') !== -1 || isBase64;
},
imgStyle() {
let style = {}
// 如果设置width和height属性,则优先使用,否则使用size属性
style.width = this.width ? this.$w.addUnit(this.width) : this.$w.addUnit(this.size)
style.height = this.height ? this.$w.addUnit(this.height) : this.$w.addUnit(this.size)
return style
},
// 通过图标名,查找对应的图标
icon() {
// 如果内置的图标中找不到对应的图标,就直接返回name值,因为用户可能传入的是unicode代码
const code = icons['wuicon-' + this.name];
if (['wuicon'].indexOf(this.customPrefix) > -1) {
return code ? unescape(`%u${code}`) : this.name;
} else {
// #ifndef APP-NVUE
return ''
// #endif
// #ifdef APP-NVUE
return unescape(`%u${this.name}`)
// #endif
}
},
// label样式
labelStyle() {
let style = {
color: this.labelColor,
fontSize: this.$w.addUnit(this.labelSize),
marginLeft: this.labelPos == 'right' ? this.$w.addUnit(this.space) : 0,
marginTop: this.labelPos == 'bottom' ? this.$w.addUnit(this.space) : 0,
marginRight: this.labelPos == 'left' ? this.$w.addUnit(this.space) : 0,
marginBottom: this.labelPos == 'top' ? this.$w.addUnit(this.space) : 0
};
return style
}
},
methods: {
clickHandler(e) {
this.$emit('click', this.index)
// 是否阻止事件冒泡
this.stop && this.preventEvent(e)
}
}
}
</script>
<style lang="scss" scoped>
@import '@/uni_modules/wu-ui-tools/libs/css/components.scss';
@import '@/uni_modules/wu-ui-tools/libs/css/color.scss';
// 变量定义
$wu-icon-primary: $wu-primary !default;
$wu-icon-success: $wu-success !default;
$wu-icon-info: $wu-info !default;
$wu-icon-warning: $wu-warning !default;
$wu-icon-error: $wu-error !default;
$wu-icon-label-line-height: 1 !default;
/* #ifndef APP-NVUE */
// nvue下加载字体
@font-face {
font-family: 'wuicon-iconfont';
src: url('./wuicons.ttf') format('truetype');
}
/* #endif */
.wu-icon {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
align-items: center;
&--left, &--right {
flex-direction: row;
}
&--top, &--bottom {
flex-direction: column;
}
&__icon {
font-family: wuicon-iconfont;
position: relative;
@include flex;
align-items: center;
&--primary {
color: $wu-icon-primary;
}
&--success {
color: $wu-icon-success;
}
&--error {
color: $wu-icon-error;
}
&--warning {
color: $wu-icon-warning;
}
&--info {
color: $wu-icon-info;
}
}
&__img {
/* #ifndef APP-NVUE */
height: auto;
will-change: transform;
/* #endif */
}
&__label {
/* #ifndef APP-NVUE */
line-height: $wu-icon-label-line-height;
/* #endif */
}
}
</style>
\ No newline at end of file
{
"id": "wu-icon",
"displayName": "wu-icon 图标 全面兼容小程序、nvue、vue2、vue3等多端",
"version": "1.0.4",
"description": "基于字体的图标集,包含了大多数常见场景的图标,支持自定义,支持自定义图片图标等。可自定义颜色、大小。",
"keywords": [
"wu-ui",
"图标",
"wu-icon",
"文字图标"
],
"repository": "",
"engines": {
"HBuilderX": "^3.4.15"
},
"dcloudext": {
"type": "component-vue",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [
"wu-ui-tools"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "y"
},
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}
\ No newline at end of file
## wu-icon 图标库
> **组件名:wu-icon**
基于字体的图标集,包含了大多数常见场景的图标,支持自定义(包括nvue)文字与图片图标等。
## <a href="https://wuui.cn/zh-CN/components/icon" target="_blank">查看文档</a>
## [更多插件,请关注wu-ui组件库](https://ext.dcloud.net.cn/plugin?name=wuui) <small>(请不要 下载插件ZIP)</small>
**如使用过程中有任何问题,或者您对wu-ui有一些好的建议。<br>欢迎加入 [wu-ui 交流群](https://wuui.cn/zh-CN/components/qqFeedBack.html)**
\ No newline at end of file
## 1.0.2(2024-05-08)
更新域名
## 1.0.1(2023-09-11)
优化底部安全距离计算方法
## 1.0.0(2023-09-01)
主要是针对IPhone X等一些底部带指示条的机型,指示条的操作区域与页面底部存在重合,容易导致用户误操作,因此我们需要针对这些机型进行底部安全区适配。
export default {
props: {
...uni.$w?.props?.safeBottom
}
}
<template>
<view
class="wu-safe-bottom"
:style="[style]"
>
</view>
</template>
<script>
import mpMixin from '@/uni_modules/wu-ui-tools/libs/mixin/mpMixin.js';
import mixin from '@/uni_modules/wu-ui-tools/libs/mixin/mixin.js';
import props from './props.js';
/**
* SafeBottom 底部安全区
* @description 这个适配,主要是针对IPhone X等一些底部带指示条的机型,指示条的操作区域与页面底部存在重合,容易导致用户误操作,因此我们需要针对这些机型进行底部安全区适配。
* @tutorial https://wuui.cn/zh-CN/components/safeAreaInset.html
* @property {type} prop_name
* @property {Object} customStyle 定义需要用到的外部样式
*
* @event {Function()}
* @example <wu-status-bar></wu-status-bar>
*/
export default {
name: "wu-safe-bottom",
mixins: [mpMixin, mixin, props],
data() {
return {
safeAreaBottomHeight: 0,
isNvue: false,
};
},
computed: {
style() {
const {
windowWidth,
windowHeight,
windowTop,
safeArea,
screenHeight,
safeAreaInsets
} = this.$w.sys();
const style = {};
// #ifdef MP-WEIXIN
style.height = this.$w.addUnit(screenHeight - safeArea.bottom, 'px');
// #endif
// #ifndef MP-WEIXIN
style.height = this.$w.addUnit(safeAreaInsets.bottom, 'px');
// #endif
return this.$w.deepMerge(style, this.$w.addStyle(this.customStyle));
},
},
};
</script>
<style lang="scss" scoped>
.wu-safe-bottom {
/* #ifndef APP-NVUE */
width: 100%;
/* #endif */
}
</style>
{
"id": "wu-safe-bottom",
"displayName": "wu-safe-bottom底部安全区 全端兼容 无论平台 一致体验",
"version": "1.0.2",
"description": "针对一些底部带指示条的机型,操作区域与页面底部重合,容易误操作,因此本插件对这些机型进行底部安全区适配",
"keywords": [
"wu-ui",
"wuui",
"wu-safe-bottom",
"safe-bottom",
"底部安全区"
],
"repository": "",
"engines": {
"HBuilderX": "^3.4.15"
},
"dcloudext": {
"type": "component-vue",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [
"wu-ui-tools"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "y"
},
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"钉钉": "n",
"快手": "n",
"飞书": "n",
"京东": "n"
},
"快应用": {
"华为": "n",
"联盟": "n"
}
}
}
}
}
\ No newline at end of file
## wu-safe-bottom 底部安全区
> **组件名:wu-safe-bottom**
这个适配,主要是针对IPhone X等一些底部带指示条的机型,指示条的操作区域与页面底部存在重合,容易导致用户误操作,因此我们需要针对这些机型进行底部安全区适配。
## [查看文档](https://wuui.cn/zh-CN/components/safeAreaInset.html)
## [更多组件, 请查看 `wu-ui` 组件库](https://ext.dcloud.net.cn/plugin?name=wu--ui)
(请勿下载插件zip)
<a href="https://ext.dcloud.net.cn/plugin?name=wu--ui">
<img src="https://wuui.cn/intr.png">
</a>
**如使用过程中有任何问题,或者您对wu-ui有一些好的建议。<br>欢迎加入 [wu-ui 交流群](https://wuui.cn/zh-CN/components/qqFeedBack.html)**
\ No newline at end of file
## 1.1.0(2023-09-13)
更新版本
## 1.0.9(2023-09-08)
修复Color方法引入路径错误
## 1.0.8(2023-09-05)
Color不在使用npm包,改为本地方法
## 1.0.7(2023-09-03)
修复引入错误
## 1.0.6(2023-09-03)
发布1.0.6版本
## 1.0.5(2023-08-30)
修复api部分未导入
## 1.0.4(2023-08-21)
修复Color API引入错误
## 1.0.3(2023-08-18)
新增颜色API,支持任意颜色格式转换,颜色亮度调节、颜色饱和度调节、亮度获取、颜色是否深/亮等
## 1.0.2(2023-08-16)
mixin交互节点信息根边距设置
## 1.0.1(2023-08-16)
mixin更新节点交互信息查询
## 1.0.0(2023-08-01)
wu-ui-tools 工具库 全面兼容小程序、nvue、vue2、vue3等多端
<template>
</template>
<script>
</script>
<style>
</style>
// 全局挂载引入http相关请求拦截插件
import Request from './libs/luch-request'
// 引入全局mixin
import mixin from './libs/mixin/mixin.js'
// 小程序特有的mixin
import mpMixin from './libs/mixin/mpMixin.js'
// #ifdef MP
import mpShare from './libs/mixin/mpShare.js'
// #endif
// 路由封装
import route from './libs/util/route.js'
// 公共工具函数
import * as index from './libs/function/index.js'
// 防抖方法
import debounce from './libs/function/debounce.js'
// 节流方法
import throttle from './libs/function/throttle.js'
// 规则检验
import * as test from './libs/function/test.js'
// 配置信息
import config from './libs/config/config.js'
// 平台
import platform from './libs/function/platform'
import Color from './libs/function/color/index.js'
const $w = {
...index,
route,
config,
test,
throttle,
date: index.timeFormat, // 另名date
Color,
http: new Request(),
debounce,
throttle,
platform,
mixin,
mpMixin
}
uni.$w = $w;
const install = (Vue,options={}) => {
// #ifndef APP-NVUE
Vue.mixin(mixin);
// #ifdef MP
if(options.mpShare){
Vue.mixin(mpShare);
}
// #endif
// #endif
// #ifdef VUE2
// 时间格式化,同时两个名称,date和timeFormat
Vue.filter('timeFormat', (timestamp, format) => uni.$w.timeFormat(timestamp, format));
Vue.filter('date', (timestamp, format) => uni.$w.timeFormat(timestamp, format));
// 将多久以前的方法,注入到全局过滤器
Vue.filter('timeFrom', (timestamp, format) => uni.$w.timeFrom(timestamp, format));
// 同时挂载到uni和Vue.prototype中
// #ifndef APP-NVUE
// 只有vue,挂载到Vue.prototype才有意义,因为nvue中全局Vue.prototype和Vue.mixin是无效的
Vue.prototype.$w = $w;
// #endif
// #endif
// #ifdef VUE3
Vue.config.globalProperties.$w = $w;
// #endif
}
export default {
install
}
\ No newline at end of file
// 引入公共基础类
@import "./libs/css/common.scss";
// 非nvue的样式
/* #ifndef APP-NVUE */
@import "./libs/css/vue.scss";
/* #endif */
\ No newline at end of file
// 此版本发布于2023-09-13
const version = '1.0.9'
// 开发环境才提示,生产环境不会提示
if (process.env.NODE_ENV === 'development') {
console.log(`\n %c wuui V${version} https://wuui.geeks.ink/ \n\n`, 'color: #ffffff; background: #3c9cff; padding:5px 0; border-radius: 5px;');
}
export default {
v: version,
version,
// 主题名称
type: [
'primary',
'success',
'info',
'error',
'warning'
],
// 颜色部分,本来可以通过scss的:export导出供js使用,但是奈何nvue不支持
color: {
'wu-primary': '#2979ff',
'wu-warning': '#ff9900',
'wu-success': '#19be6b',
'wu-error': '#fa3534',
'wu-info': '#909399',
'wu-main-color': '#303133',
'wu-content-color': '#606266',
'wu-tips-color': '#909399',
'wu-light-color': '#c0c4cc'
},
// 默认单位,可以通过配置为rpx,那么在用于传入组件大小参数为数值时,就默认为rpx
unit: 'px'
}
$wu-main-color: #303133 !default;
$wu-content-color: #606266 !default;
$wu-tips-color: #909193 !default;
$wu-light-color: #c0c4cc !default;
$wu-border-color: #dadbde !default;
$wu-bg-color: #f3f4f6 !default;
$wu-disabled-color: #c8c9cc !default;
$wu-primary: #3c9cff !default;
$wu-primary-dark: #398ade !default;
$wu-primary-disabled: #9acafc !default;
$wu-primary-light: #ecf5ff !default;
$wu-warning: #f9ae3d !default;
$wu-warning-dark: #f1a532 !default;
$wu-warning-disabled: #f9d39b !default;
$wu-warning-light: #fdf6ec !default;
$wu-success: #5ac725 !default;
$wu-success-dark: #53c21d !default;
$wu-success-disabled: #a9e08f !default;
$wu-success-light: #f5fff0;
$wu-error: #f56c6c !default;
$wu-error-dark: #e45656 !default;
$wu-error-disabled: #f7b2b2 !default;
$wu-error-light: #fef0f0 !default;
$wu-info: #909399 !default;
$wu-info-dark: #767a82 !default;
$wu-info-disabled: #c4c6c9 !default;
$wu-info-light: #f4f4f5 !default;
// 超出行数,自动显示行尾省略号,最多5行
// 来自wuui的温馨提示:当您在控制台看到此报错,说明需要在App.vue的style标签加上【lang="scss"】
@for $i from 1 through 5 {
.wu-line-#{$i} {
/* #ifdef APP-NVUE */
// nvue下,可以直接使用lines属性,这是weex特有样式
lines: $i;
text-overflow: ellipsis;
overflow: hidden;
flex: 1;
/* #endif */
/* #ifndef APP-NVUE */
// vue下,单行和多行显示省略号需要单独处理
@if $i == '1' {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
} @else {
display: -webkit-box!important;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
-webkit-line-clamp: $i;
-webkit-box-orient: vertical!important;
}
/* #endif */
}
}
$wu-bordercolor: #dadbde;
@if variable-exists(wu-border-color) {
$wu-bordercolor: $wu-border-color;
}
// 此处加上!important并非随意乱用,而是因为目前*.nvue页面编译到H5时,
// App.vue的样式会被uni-app的view元素的自带border属性覆盖,导致无效
// 综上,这是uni-app的缺陷导致我们为了多端兼容,而必须要加上!important
// 移动端兼容性较好,直接使用0.5px去实现细边框,不使用伪元素形式实现
.wu-border {
border-width: 0.5px!important;
border-color: $wu-bordercolor!important;
border-style: solid;
}
.wu-border-top {
border-top-width: 0.5px!important;
border-color: $wu-bordercolor!important;
border-top-style: solid;
}
.wu-border-left {
border-left-width: 0.5px!important;
border-color: $wu-bordercolor!important;
border-left-style: solid;
}
.wu-border-right {
border-right-width: 0.5px!important;
border-color: $wu-bordercolor!important;
border-right-style: solid;
}
.wu-border-bottom {
border-bottom-width: 0.5px!important;
border-color: $wu-bordercolor!important;
border-bottom-style: solid;
}
.wu-border-top-bottom {
border-top-width: 0.5px!important;
border-bottom-width: 0.5px!important;
border-color: $wu-bordercolor!important;
border-top-style: solid;
border-bottom-style: solid;
}
// 去除button的所有默认样式,让其表现跟普通的view、text元素一样
.wu-reset-button {
padding: 0;
background-color: transparent;
/* #ifndef APP-PLUS */
font-size: inherit;
line-height: inherit;
color: inherit;
/* #endif */
/* #ifdef APP-NVUE */
border-width: 0;
/* #endif */
}
/* #ifndef APP-NVUE */
.wu-reset-button::after {
border: none;
}
/* #endif */
.wu-hover-class {
opacity: 0.7;
}
@mixin flex($direction: row) {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: $direction;
}
/* #ifndef APP-NVUE */
// 由于wuui是基于nvue环境进行开发的,此环境中普通元素默认为flex-direction: column;
// 所以在非nvue中,需要对元素进行重置为flex-direction: column; 否则可能会表现异常
$wuui-nvue-style: true !default;
@if $wuui-nvue-style == true {
view, scroll-view, swiper-item {
display: flex;
flex-direction: column;
flex-shrink: 0;
flex-grow: 0;
flex-basis: auto;
align-items: stretch;
align-content: flex-start;
}
}
/* #endif */
// 超出行数,自动显示行尾省略号,最多5行
// 来自uvui的温馨提示:当您在控制台看到此报错,说明需要在App.vue的style标签加上【lang="scss"】
@if variable-exists(show-lines) {
@for $i from 1 through 5 {
.wu-line-#{$i} {
/* #ifdef APP-NVUE */
// nvue下,可以直接使用lines属性,这是weex特有样式
lines: $i;
text-overflow: ellipsis;
overflow: hidden;
flex: 1;
/* #endif */
/* #ifndef APP-NVUE */
// vue下,单行和多行显示省略号需要单独处理
@if $i == '1' {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
} @else {
display: -webkit-box!important;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
-webkit-line-clamp: $i;
-webkit-box-orient: vertical!important;
}
/* #endif */
}
}
}
@if variable-exists(show-border) {
$wu-bordercolor: #dadbde;
@if variable-exists(wu-border-color) {
$wu-bordercolor: $wu-border-color;
}
// 此处加上!important并非随意乱用,而是因为目前*.nvue页面编译到H5时,
// App.vue的样式会被uni-app的view元素的自带border属性覆盖,导致无效
// 综上,这是uni-app的缺陷导致我们为了多端兼容,而必须要加上!important
// 移动端兼容性较好,直接使用0.5px去实现细边框,不使用伪元素形式实现
@if variable-exists(show-border-surround) {
.wu-border {
border-width: 0.5px!important;
border-color: $wu-bordercolor!important;
border-style: solid;
}
}
@if variable-exists(show-border-top) {
.wu-border-top {
border-top-width: 0.5px!important;
border-color: $wu-bordercolor!important;
border-top-style: solid;
}
}
@if variable-exists(show-border-left) {
.wu-border-left {
border-left-width: 0.5px!important;
border-color: $wu-bordercolor!important;
border-left-style: solid;
}
}
@if variable-exists(show-border-right) {
.wu-border-right {
border-right-width: 0.5px!important;
border-color: $wu-bordercolor!important;
border-right-style: solid;
}
}
@if variable-exists(show-border-bottom) {
.wu-border-bottom {
border-bottom-width: 0.5px!important;
border-color: $wu-bordercolor!important;
border-bottom-style: solid;
}
}
@if variable-exists(show-border-top-bottom) {
.wu-border-top-bottom {
border-top-width: 0.5px!important;
border-bottom-width: 0.5px!important;
border-color: $wu-bordercolor!important;
border-top-style: solid;
border-bottom-style: solid;
}
}
}
@if variable-exists(show-reset-button) {
// 去除button的所有默认样式,让其表现跟普通的view、text元素一样
.wu-reset-button {
padding: 0;
background-color: transparent;
/* #ifndef APP-PLUS */
font-size: inherit;
line-height: inherit;
color: inherit;
/* #endif */
/* #ifdef APP-NVUE */
border-width: 0;
/* #endif */
}
/* #ifndef APP-NVUE */
.wu-reset-button::after {
border: none;
}
/* #endif */
}
@if variable-exists(show-hover) {
.wu-hover-class {
opacity: 0.7;
}
}
// 历遍生成4个方向的底部安全区
@each $d in top, right, bottom, left {
.wu-safe-area-inset-#{$d} {
padding-#{$d}: 0;
padding-#{$d}: constant(safe-area-inset-#{$d});
padding-#{$d}: env(safe-area-inset-#{$d});
}
}
//提升H5端uni.toast()的层级,避免被wuui的modal等遮盖
/* #ifdef H5 */
uni-toast {
z-index: 10090;
}
uni-toast .uni-toast {
z-index: 10090;
}
/* #endif */
// 隐藏scroll-view的滚动条
::-webkit-scrollbar {
display: none;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
$wuui-nvue-style: true !default;
@if $wuui-nvue-style == false {
view, scroll-view, swiper-item {
display: flex;
flex-direction: column;
flex-shrink: 0;
flex-grow: 0;
flex-basis: auto;
align-items: stretch;
align-content: flex-start;
}
}
# 1.0.0 - 2016-01-07
- Removed: unused speed test
- Added: Automatic routing between previously unsupported conversions
([#27](https://github.com/Qix-/color-convert/pull/27))
- Removed: `xxx2xxx()` and `xxx2xxxRaw()` functions
([#27](https://github.com/Qix-/color-convert/pull/27))
- Removed: `convert()` class
([#27](https://github.com/Qix-/color-convert/pull/27))
- Changed: all functions to lookup dictionary
([#27](https://github.com/Qix-/color-convert/pull/27))
- Changed: `ansi` to `ansi256`
([#27](https://github.com/Qix-/color-convert/pull/27))
- Fixed: argument grouping for functions requiring only one argument
([#27](https://github.com/Qix-/color-convert/pull/27))
# 0.6.0 - 2015-07-23
- Added: methods to handle
[ANSI](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) 16/256 colors:
- rgb2ansi16
- rgb2ansi
- hsl2ansi16
- hsl2ansi
- hsv2ansi16
- hsv2ansi
- hwb2ansi16
- hwb2ansi
- cmyk2ansi16
- cmyk2ansi
- keyword2ansi16
- keyword2ansi
- ansi162rgb
- ansi162hsl
- ansi162hsv
- ansi162hwb
- ansi162cmyk
- ansi162keyword
- ansi2rgb
- ansi2hsl
- ansi2hsv
- ansi2hwb
- ansi2cmyk
- ansi2keyword
([#18](https://github.com/harthur/color-convert/pull/18))
# 0.5.3 - 2015-06-02
- Fixed: hsl2hsv does not return `NaN` anymore when using `[0,0,0]`
([#15](https://github.com/harthur/color-convert/issues/15))
---
Check out commit logs for older releases
Copyright (c) 2011-2016 Heather Arthur <fayearthur@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# color-convert
[![Build Status](https://travis-ci.org/Qix-/color-convert.svg?branch=master)](https://travis-ci.org/Qix-/color-convert)
Color-convert is a color conversion library for JavaScript and node.
It converts all ways between `rgb`, `hsl`, `hsv`, `hwb`, `cmyk`, `ansi`, `ansi16`, `hex` strings, and CSS `keyword`s (will round to closest):
```js
var convert = require('color-convert');
convert.rgb.hsl(140, 200, 100); // [96, 48, 59]
convert.keyword.rgb('blue'); // [0, 0, 255]
var rgbChannels = convert.rgb.channels; // 3
var cmykChannels = convert.cmyk.channels; // 4
var ansiChannels = convert.ansi16.channels; // 1
```
# Install
```console
$ npm install color-convert
```
# API
Simply get the property of the _from_ and _to_ conversion that you're looking for.
All functions have a rounded and unrounded variant. By default, return values are rounded. To get the unrounded (raw) results, simply tack on `.raw` to the function.
All 'from' functions have a hidden property called `.channels` that indicates the number of channels the function expects (not including alpha).
```js
var convert = require('color-convert');
// Hex to LAB
convert.hex.lab('DEADBF'); // [ 76, 21, -2 ]
convert.hex.lab.raw('DEADBF'); // [ 75.56213190997677, 20.653827952644754, -2.290532499330533 ]
// RGB to CMYK
convert.rgb.cmyk(167, 255, 4); // [ 35, 0, 98, 0 ]
convert.rgb.cmyk.raw(167, 255, 4); // [ 34.509803921568626, 0, 98.43137254901961, 0 ]
```
### Arrays
All functions that accept multiple arguments also support passing an array.
Note that this does **not** apply to functions that convert from a color that only requires one value (e.g. `keyword`, `ansi256`, `hex`, etc.)
```js
var convert = require('color-convert');
convert.rgb.hex(123, 45, 67); // '7B2D43'
convert.rgb.hex([123, 45, 67]); // '7B2D43'
```
## Routing
Conversions that don't have an _explicitly_ defined conversion (in [conversions.js](conversions.js)), but can be converted by means of sub-conversions (e.g. XYZ -> **RGB** -> CMYK), are automatically routed together. This allows just about any color model supported by `color-convert` to be converted to any other model, so long as a sub-conversion path exists. This is also true for conversions requiring more than one step in between (e.g. LCH -> **LAB** -> **XYZ** -> **RGB** -> Hex).
Keep in mind that extensive conversions _may_ result in a loss of precision, and exist only to be complete. For a list of "direct" (single-step) conversions, see [conversions.js](conversions.js).
# Contribute
If there is a new model you would like to support, or want to add a direct conversion between two existing models, please send us a pull request.
# License
Copyright &copy; 2011-2016, Heather Arthur and Josh Junon. Licensed under the [MIT License](LICENSE).
import route from './route'
import conversions from './conversions'
const convert = {};
const models = Object.keys(conversions);
function wrapRaw(fn) {
const wrappedFn = function (...args) {
const arg0 = args[0];
if (arg0 === undefined || arg0 === null) {
return arg0;
}
if (arg0.length > 1) {
args = arg0;
}
return fn(args);
};
// Preserve .conversion property if there is one
if ('conversion' in fn) {
wrappedFn.conversion = fn.conversion;
}
return wrappedFn;
}
function wrapRounded(fn) {
const wrappedFn = function (...args) {
const arg0 = args[0];
if (arg0 === undefined || arg0 === null) {
return arg0;
}
if (arg0.length > 1) {
args = arg0;
}
const result = fn(args);
// We're assuming the result is an array here.
// see notice in conversions.js; don't use box types
// in conversion functions.
if (typeof result === 'object') {
for (let len = result.length, i = 0; i < len; i++) {
result[i] = Math.round(result[i]);
}
}
return result;
};
// Preserve .conversion property if there is one
if ('conversion' in fn) {
wrappedFn.conversion = fn.conversion;
}
return wrappedFn;
}
models.forEach(fromModel => {
convert[fromModel] = {};
Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels});
Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels});
const routes = route(fromModel);
const routeModels = Object.keys(routes);
routeModels.forEach(toModel => {
const fn = routes[toModel];
convert[fromModel][toModel] = wrapRounded(fn);
convert[fromModel][toModel].raw = wrapRaw(fn);
});
});
export default convert;
{
"name": "color-convert",
"description": "Plain color conversion functions",
"version": "2.0.1",
"author": "Heather Arthur <fayearthur@gmail.com>",
"license": "MIT",
"repository": "Qix-/color-convert",
"scripts": {
"pretest": "xo",
"test": "node test/basic.js"
},
"engines": {
"node": ">=7.0.0"
},
"keywords": [
"color",
"colour",
"convert",
"converter",
"conversion",
"rgb",
"hsl",
"hsv",
"hwb",
"cmyk",
"ansi",
"ansi16"
],
"files": [
"index.js",
"conversions.js",
"route.js"
],
"xo": {
"rules": {
"default-case": 0,
"no-inline-comments": 0,
"operator-linebreak": 0
}
},
"devDependencies": {
"chalk": "^2.4.2",
"xo": "^0.24.0"
},
"dependencies": {
"color-name": "~1.1.4"
}
}
import conversions from './conversions'
/*
This function routes a model to all other models.
all functions that are routed have a property `.conversion` attached
to the returned synthetic function. This property is an array
of strings, each with the steps in between the 'from' and 'to'
color models (inclusive).
conversions that are not possible simply are not included.
*/
function buildGraph() {
const graph = {};
// https://jsperf.com/object-keys-vs-for-in-with-closure/3
const models = Object.keys(conversions);
for (let len = models.length, i = 0; i < len; i++) {
graph[models[i]] = {
// http://jsperf.com/1-vs-infinity
// micro-opt, but this is simple.
distance: -1,
parent: null
};
}
return graph;
}
// https://en.wikipedia.org/wiki/Breadth-first_search
function deriveBFS(fromModel) {
const graph = buildGraph();
const queue = [fromModel]; // Unshift -> queue -> pop
graph[fromModel].distance = 0;
while (queue.length) {
const current = queue.pop();
const adjacents = Object.keys(conversions[current]);
for (let len = adjacents.length, i = 0; i < len; i++) {
const adjacent = adjacents[i];
const node = graph[adjacent];
if (node.distance === -1) {
node.distance = graph[current].distance + 1;
node.parent = current;
queue.unshift(adjacent);
}
}
}
return graph;
}
function link(from, to) {
return function (args) {
return to(from(args));
};
}
function wrapConversion(toModel, graph) {
const path = [graph[toModel].parent, toModel];
let fn = conversions[graph[toModel].parent][toModel];
let cur = graph[toModel].parent;
while (graph[cur].parent) {
path.unshift(graph[cur].parent);
fn = link(conversions[graph[cur].parent][cur], fn);
cur = graph[cur].parent;
}
fn.conversion = path;
return fn;
}
export default function (fromModel) {
const graph = deriveBFS(fromModel);
const conversion = {};
const models = Object.keys(graph);
for (let len = models.length, i = 0; i < len; i++) {
const toModel = models[i];
const node = graph[toModel];
if (node.parent === null) {
// No possible conversion, or this node is the source model.
continue;
}
conversion[toModel] = wrapConversion(toModel, graph);
}
return conversion;
};
The MIT License (MIT)
Copyright (c) 2015 Dmitry Ivanov
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
A JSON with color names and its values. Based on http://dev.w3.org/csswg/css-color/#named-colors.
[![NPM](https://nodei.co/npm/color-name.png?mini=true)](https://nodei.co/npm/color-name/)
```js
var colors = require('color-name');
colors.red //[255,0,0]
```
<a href="LICENSE"><img src="https://upload.wikimedia.org/wikipedia/commons/0/0c/MIT_logo.svg" width="120"/></a>
'use strict'
export default {
"aliceblue": [240, 248, 255],
"antiquewhite": [250, 235, 215],
"aqua": [0, 255, 255],
"aquamarine": [127, 255, 212],
"azure": [240, 255, 255],
"beige": [245, 245, 220],
"bisque": [255, 228, 196],
"black": [0, 0, 0],
"blanchedalmond": [255, 235, 205],
"blue": [0, 0, 255],
"blueviolet": [138, 43, 226],
"brown": [165, 42, 42],
"burlywood": [222, 184, 135],
"cadetblue": [95, 158, 160],
"chartreuse": [127, 255, 0],
"chocolate": [210, 105, 30],
"coral": [255, 127, 80],
"cornflowerblue": [100, 149, 237],
"cornsilk": [255, 248, 220],
"crimson": [220, 20, 60],
"cyan": [0, 255, 255],
"darkblue": [0, 0, 139],
"darkcyan": [0, 139, 139],
"darkgoldenrod": [184, 134, 11],
"darkgray": [169, 169, 169],
"darkgreen": [0, 100, 0],
"darkgrey": [169, 169, 169],
"darkkhaki": [189, 183, 107],
"darkmagenta": [139, 0, 139],
"darkolivegreen": [85, 107, 47],
"darkorange": [255, 140, 0],
"darkorchid": [153, 50, 204],
"darkred": [139, 0, 0],
"darksalmon": [233, 150, 122],
"darkseagreen": [143, 188, 143],
"darkslateblue": [72, 61, 139],
"darkslategray": [47, 79, 79],
"darkslategrey": [47, 79, 79],
"darkturquoise": [0, 206, 209],
"darkviolet": [148, 0, 211],
"deeppink": [255, 20, 147],
"deepskyblue": [0, 191, 255],
"dimgray": [105, 105, 105],
"dimgrey": [105, 105, 105],
"dodgerblue": [30, 144, 255],
"firebrick": [178, 34, 34],
"floralwhite": [255, 250, 240],
"forestgreen": [34, 139, 34],
"fuchsia": [255, 0, 255],
"gainsboro": [220, 220, 220],
"ghostwhite": [248, 248, 255],
"gold": [255, 215, 0],
"goldenrod": [218, 165, 32],
"gray": [128, 128, 128],
"green": [0, 128, 0],
"greenyellow": [173, 255, 47],
"grey": [128, 128, 128],
"honeydew": [240, 255, 240],
"hotpink": [255, 105, 180],
"indianred": [205, 92, 92],
"indigo": [75, 0, 130],
"ivory": [255, 255, 240],
"khaki": [240, 230, 140],
"lavender": [230, 230, 250],
"lavenderblush": [255, 240, 245],
"lawngreen": [124, 252, 0],
"lemonchiffon": [255, 250, 205],
"lightblue": [173, 216, 230],
"lightcoral": [240, 128, 128],
"lightcyan": [224, 255, 255],
"lightgoldenrodyellow": [250, 250, 210],
"lightgray": [211, 211, 211],
"lightgreen": [144, 238, 144],
"lightgrey": [211, 211, 211],
"lightpink": [255, 182, 193],
"lightsalmon": [255, 160, 122],
"lightseagreen": [32, 178, 170],
"lightskyblue": [135, 206, 250],
"lightslategray": [119, 136, 153],
"lightslategrey": [119, 136, 153],
"lightsteelblue": [176, 196, 222],
"lightyellow": [255, 255, 224],
"lime": [0, 255, 0],
"limegreen": [50, 205, 50],
"linen": [250, 240, 230],
"magenta": [255, 0, 255],
"maroon": [128, 0, 0],
"mediumaquamarine": [102, 205, 170],
"mediumblue": [0, 0, 205],
"mediumorchid": [186, 85, 211],
"mediumpurple": [147, 112, 219],
"mediumseagreen": [60, 179, 113],
"mediumslateblue": [123, 104, 238],
"mediumspringgreen": [0, 250, 154],
"mediumturquoise": [72, 209, 204],
"mediumvioletred": [199, 21, 133],
"midnightblue": [25, 25, 112],
"mintcream": [245, 255, 250],
"mistyrose": [255, 228, 225],
"moccasin": [255, 228, 181],
"navajowhite": [255, 222, 173],
"navy": [0, 0, 128],
"oldlace": [253, 245, 230],
"olive": [128, 128, 0],
"olivedrab": [107, 142, 35],
"orange": [255, 165, 0],
"orangered": [255, 69, 0],
"orchid": [218, 112, 214],
"palegoldenrod": [238, 232, 170],
"palegreen": [152, 251, 152],
"paleturquoise": [175, 238, 238],
"palevioletred": [219, 112, 147],
"papayawhip": [255, 239, 213],
"peachpuff": [255, 218, 185],
"peru": [205, 133, 63],
"pink": [255, 192, 203],
"plum": [221, 160, 221],
"powderblue": [176, 224, 230],
"purple": [128, 0, 128],
"rebeccapurple": [102, 51, 153],
"red": [255, 0, 0],
"rosybrown": [188, 143, 143],
"royalblue": [65, 105, 225],
"saddlebrown": [139, 69, 19],
"salmon": [250, 128, 114],
"sandybrown": [244, 164, 96],
"seagreen": [46, 139, 87],
"seashell": [255, 245, 238],
"sienna": [160, 82, 45],
"silver": [192, 192, 192],
"skyblue": [135, 206, 235],
"slateblue": [106, 90, 205],
"slategray": [112, 128, 144],
"slategrey": [112, 128, 144],
"snow": [255, 250, 250],
"springgreen": [0, 255, 127],
"steelblue": [70, 130, 180],
"tan": [210, 180, 140],
"teal": [0, 128, 128],
"thistle": [216, 191, 216],
"tomato": [255, 99, 71],
"turquoise": [64, 224, 208],
"violet": [238, 130, 238],
"wheat": [245, 222, 179],
"white": [255, 255, 255],
"whitesmoke": [245, 245, 245],
"yellow": [255, 255, 0],
"yellowgreen": [154, 205, 50]
};
{
"name": "color-name",
"version": "1.1.4",
"description": "A list of color names and its values",
"main": "index.js",
"files": [
"index.js"
],
"scripts": {
"test": "node test.js"
},
"repository": {
"type": "git",
"url": "git@github.com:colorjs/color-name.git"
},
"keywords": [
"color-name",
"color",
"color-keyword",
"keyword"
],
"author": "DY <dfcreative@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/colorjs/color-name/issues"
},
"homepage": "https://github.com/colorjs/color-name"
}
Copyright (c) 2011 Heather Arthur <fayearthur@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# color-string
> library for parsing and generating CSS color strings.
## Install
With [npm](http://npmjs.org/):
```console
$ npm install color-string
```
## Usage
### Parsing
```js
colorString.get('#FFF') // {model: 'rgb', value: [255, 255, 255, 1]}
colorString.get('#FFFA') // {model: 'rgb', value: [255, 255, 255, 0.67]}
colorString.get('#FFFFFFAA') // {model: 'rgb', value: [255, 255, 255, 0.67]}
colorString.get('hsl(360, 100%, 50%)') // {model: 'hsl', value: [0, 100, 50, 1]}
colorString.get('hsl(360 100% 50%)') // {model: 'hsl', value: [0, 100, 50, 1]}
colorString.get('hwb(60, 3%, 60%)') // {model: 'hwb', value: [60, 3, 60, 1]}
colorString.get.rgb('#FFF') // [255, 255, 255, 1]
colorString.get.rgb('blue') // [0, 0, 255, 1]
colorString.get.rgb('rgba(200, 60, 60, 0.3)') // [200, 60, 60, 0.3]
colorString.get.rgb('rgba(200 60 60 / 0.3)') // [200, 60, 60, 0.3]
colorString.get.rgb('rgba(200 60 60 / 30%)') // [200, 60, 60, 0.3]
colorString.get.rgb('rgb(200, 200, 200)') // [200, 200, 200, 1]
colorString.get.rgb('rgb(200 200 200)') // [200, 200, 200, 1]
colorString.get.hsl('hsl(360, 100%, 50%)') // [0, 100, 50, 1]
colorString.get.hsl('hsl(360 100% 50%)') // [0, 100, 50, 1]
colorString.get.hsl('hsla(360, 60%, 50%, 0.4)') // [0, 60, 50, 0.4]
colorString.get.hsl('hsl(360 60% 50% / 0.4)') // [0, 60, 50, 0.4]
colorString.get.hwb('hwb(60, 3%, 60%)') // [60, 3, 60, 1]
colorString.get.hwb('hwb(60, 3%, 60%, 0.6)') // [60, 3, 60, 0.6]
colorString.get.rgb('invalid color string') // null
```
### Generation
```js
colorString.to.hex([255, 255, 255]) // "#FFFFFF"
colorString.to.hex([0, 0, 255, 0.4]) // "#0000FF66"
colorString.to.hex([0, 0, 255], 0.4) // "#0000FF66"
colorString.to.rgb([255, 255, 255]) // "rgb(255, 255, 255)"
colorString.to.rgb([0, 0, 255, 0.4]) // "rgba(0, 0, 255, 0.4)"
colorString.to.rgb([0, 0, 255], 0.4) // "rgba(0, 0, 255, 0.4)"
colorString.to.rgb.percent([0, 0, 255]) // "rgb(0%, 0%, 100%)"
colorString.to.keyword([255, 255, 0]) // "yellow"
colorString.to.hsl([360, 100, 100]) // "hsl(360, 100%, 100%)"
colorString.to.hwb([50, 3, 15]) // "hwb(50, 3%, 15%)"
// all functions also support swizzling
colorString.to.rgb(0, [0, 255], 0.4) // "rgba(0, 0, 255, 0.4)"
colorString.to.rgb([0, 0], [255], 0.4) // "rgba(0, 0, 255, 0.4)"
colorString.to.rgb([0], 0, [255, 0.4]) // "rgba(0, 0, 255, 0.4)"
```
/* MIT license */
import colorNames from '../color-name'
import swizzle from '../simple-swizzle'
var hasOwnProperty = Object.hasOwnProperty;
var reverseNames = Object.create(null);
// create a list of reverse color names
for (var name in colorNames) {
if (hasOwnProperty.call(colorNames, name)) {
reverseNames[colorNames[name]] = name;
}
}
var cs = {
to: {},
get: {}
};
cs.get = function (string) {
var prefix = string.substring(0, 3).toLowerCase();
var val;
var model;
switch (prefix) {
case 'hsl':
val = cs.get.hsl(string);
model = 'hsl';
break;
case 'hwb':
val = cs.get.hwb(string);
model = 'hwb';
break;
default:
val = cs.get.rgb(string);
model = 'rgb';
break;
}
if (!val) {
return null;
}
return {model: model, value: val};
};
cs.get.rgb = function (string) {
if (!string) {
return null;
}
var abbr = /^#([a-f0-9]{3,4})$/i;
var hex = /^#([a-f0-9]{6})([a-f0-9]{2})?$/i;
var rgba = /^rgba?\(\s*([+-]?\d+)(?=[\s,])\s*(?:,\s*)?([+-]?\d+)(?=[\s,])\s*(?:,\s*)?([+-]?\d+)\s*(?:[,|\/]\s*([+-]?[\d\.]+)(%?)\s*)?\)$/;
var per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,?\s*([+-]?[\d\.]+)\%\s*,?\s*([+-]?[\d\.]+)\%\s*(?:[,|\/]\s*([+-]?[\d\.]+)(%?)\s*)?\)$/;
var keyword = /^(\w+)$/;
var rgb = [0, 0, 0, 1];
var match;
var i;
var hexAlpha;
if (match = string.match(hex)) {
hexAlpha = match[2];
match = match[1];
for (i = 0; i < 3; i++) {
// https://jsperf.com/slice-vs-substr-vs-substring-methods-long-string/19
var i2 = i * 2;
rgb[i] = parseInt(match.slice(i2, i2 + 2), 16);
}
if (hexAlpha) {
rgb[3] = parseInt(hexAlpha, 16) / 255;
}
} else if (match = string.match(abbr)) {
match = match[1];
hexAlpha = match[3];
for (i = 0; i < 3; i++) {
rgb[i] = parseInt(match[i] + match[i], 16);
}
if (hexAlpha) {
rgb[3] = parseInt(hexAlpha + hexAlpha, 16) / 255;
}
} else if (match = string.match(rgba)) {
for (i = 0; i < 3; i++) {
rgb[i] = parseInt(match[i + 1], 0);
}
if (match[4]) {
if (match[5]) {
rgb[3] = parseFloat(match[4]) * 0.01;
} else {
rgb[3] = parseFloat(match[4]);
}
}
} else if (match = string.match(per)) {
for (i = 0; i < 3; i++) {
rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55);
}
if (match[4]) {
if (match[5]) {
rgb[3] = parseFloat(match[4]) * 0.01;
} else {
rgb[3] = parseFloat(match[4]);
}
}
} else if (match = string.match(keyword)) {
if (match[1] === 'transparent') {
return [0, 0, 0, 0];
}
if (!hasOwnProperty.call(colorNames, match[1])) {
return null;
}
rgb = colorNames[match[1]];
rgb[3] = 1;
return rgb;
} else {
return null;
}
for (i = 0; i < 3; i++) {
rgb[i] = clamp(rgb[i], 0, 255);
}
rgb[3] = clamp(rgb[3], 0, 1);
return rgb;
};
cs.get.hsl = function (string) {
if (!string) {
return null;
}
var hsl = /^hsla?\(\s*([+-]?(?:\d{0,3}\.)?\d+)(?:deg)?\s*,?\s*([+-]?[\d\.]+)%\s*,?\s*([+-]?[\d\.]+)%\s*(?:[,|\/]\s*([+-]?(?=\.\d|\d)(?:0|[1-9]\d*)?(?:\.\d*)?(?:[eE][+-]?\d+)?)\s*)?\)$/;
var match = string.match(hsl);
if (match) {
var alpha = parseFloat(match[4]);
var h = ((parseFloat(match[1]) % 360) + 360) % 360;
var s = clamp(parseFloat(match[2]), 0, 100);
var l = clamp(parseFloat(match[3]), 0, 100);
var a = clamp(isNaN(alpha) ? 1 : alpha, 0, 1);
return [h, s, l, a];
}
return null;
};
cs.get.hwb = function (string) {
if (!string) {
return null;
}
var hwb = /^hwb\(\s*([+-]?\d{0,3}(?:\.\d+)?)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?(?=\.\d|\d)(?:0|[1-9]\d*)?(?:\.\d*)?(?:[eE][+-]?\d+)?)\s*)?\)$/;
var match = string.match(hwb);
if (match) {
var alpha = parseFloat(match[4]);
var h = ((parseFloat(match[1]) % 360) + 360) % 360;
var w = clamp(parseFloat(match[2]), 0, 100);
var b = clamp(parseFloat(match[3]), 0, 100);
var a = clamp(isNaN(alpha) ? 1 : alpha, 0, 1);
return [h, w, b, a];
}
return null;
};
cs.to.hex = function () {
var rgba = swizzle(arguments);
return (
'#' +
hexDouble(rgba[0]) +
hexDouble(rgba[1]) +
hexDouble(rgba[2]) +
(rgba[3] < 1
? (hexDouble(Math.round(rgba[3] * 255)))
: '')
);
};
cs.to.rgb = function () {
var rgba = swizzle(arguments);
return rgba.length < 4 || rgba[3] === 1
? 'rgb(' + Math.round(rgba[0]) + ', ' + Math.round(rgba[1]) + ', ' + Math.round(rgba[2]) + ')'
: 'rgba(' + Math.round(rgba[0]) + ', ' + Math.round(rgba[1]) + ', ' + Math.round(rgba[2]) + ', ' + rgba[3] + ')';
};
cs.to.rgb.percent = function () {
var rgba = swizzle(arguments);
var r = Math.round(rgba[0] / 255 * 100);
var g = Math.round(rgba[1] / 255 * 100);
var b = Math.round(rgba[2] / 255 * 100);
return rgba.length < 4 || rgba[3] === 1
? 'rgb(' + r + '%, ' + g + '%, ' + b + '%)'
: 'rgba(' + r + '%, ' + g + '%, ' + b + '%, ' + rgba[3] + ')';
};
cs.to.hsl = function () {
var hsla = swizzle(arguments);
return hsla.length < 4 || hsla[3] === 1
? 'hsl(' + hsla[0] + ', ' + hsla[1] + '%, ' + hsla[2] + '%)'
: 'hsla(' + hsla[0] + ', ' + hsla[1] + '%, ' + hsla[2] + '%, ' + hsla[3] + ')';
};
// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax
// (hwb have alpha optional & 1 is default value)
cs.to.hwb = function () {
var hwba = swizzle(arguments);
var a = '';
if (hwba.length >= 4 && hwba[3] !== 1) {
a = ', ' + hwba[3];
}
return 'hwb(' + hwba[0] + ', ' + hwba[1] + '%, ' + hwba[2] + '%' + a + ')';
};
cs.to.keyword = function (rgb) {
return reverseNames[rgb.slice(0, 3)];
};
// helpers
function clamp(num, min, max) {
return Math.min(Math.max(min, num), max);
}
function hexDouble(num) {
var str = Math.round(num).toString(16).toUpperCase();
return (str.length < 2) ? '0' + str : str;
}
export default cs;
\ No newline at end of file
{
"name": "color-string",
"description": "Parser and generator for CSS color strings",
"version": "1.9.1",
"author": "Heather Arthur <fayearthur@gmail.com>",
"contributors": [
"Maxime Thirouin",
"Dyma Ywanov <dfcreative@gmail.com>",
"Josh Junon"
],
"repository": "Qix-/color-string",
"scripts": {
"pretest": "xo",
"test": "node test/basic.js"
},
"license": "MIT",
"files": [
"index.js"
],
"xo": {
"rules": {
"no-cond-assign": 0,
"operator-linebreak": 0
}
},
"dependencies": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
},
"devDependencies": {
"xo": "^0.12.1"
},
"keywords": [
"color",
"colour",
"rgb",
"css"
]
}
import Color from './color';
/**
* 转换颜色格式。
* @param {Object} params - 参数对象。
* @param {string} color - 输入的颜色,默认为 '#fff'。
* @param {string} format - 需要转换的格式(支持 'rgb', 'hex', 'hsl', 'hsv', 'hwb')。
* @param {string} type - 转换后的类型(支持 'string', 'object', 'array', 'round')。
* @returns {string|Object|Array} 转换后的颜色表示。
*/
function convertFormat(color = '#fff', format = 'rgb', type = 'string') {
let colorObj = Color(color);
// 如果格式存在
if (colorObj[format]) {
// hex 无法直接转换为 除string类型外的任何类型
// 所以转为rgb 后 获取其他类型
if(format == 'hex' && type != 'string') format = 'rgb';
// 类型名称
let typeName = '';
switch (type) {
case 'string':
typeName = 'toString';
break;
case 'object':
typeName = 'object';
break;
case 'array':
typeName = 'array';
break;
case 'round':
typeName = 'round';
break;
default:
throw Error('Unsupported target type:' + type)
}
return colorObj[format]()[typeName]();
} else {
throw Error('Unsupported target format: ' + format);
}
}
/**
* 计算两个颜色之间的渐变值。
* @param {string} startColor - 开始的颜色,默认为黑色。
* @param {string} endColor - 结束的颜色,默认为白色。
* @param {number} step - 渐变的步数,默认为10。
* @returns {Array<string>} 两个颜色之间的渐变颜色数组。
*/
function gradient(startColor = 'rgb(0, 0, 0)', endColor = 'rgb(255, 255, 255)', step = 10) {
const startRGB = convertFormat(startColor, 'rgb', 'array') // 转换为rgb数组模式
const startR = startRGB[0]
const startG = startRGB[1]
const startB = startRGB[2]
const endRGB = convertFormat(endColor, 'rgb', 'array')
const endR = endRGB[0]
const endG = endRGB[1]
const endB = endRGB[2]
const sR = (endR - startR) / step // 总差值
const sG = (endG - startG) / step
const sB = (endB - startB) / step
const colorArr = []
for (let i = 0; i < step; i++) {
// 计算每一步的hex值
let hex = convertFormat(`rgb(${Math.round((sR * i + startR))},${Math.round((sG * i + startG))},${Math.round((sB
* i + startB))})`, 'hex')
// 确保第一个颜色值为startColor的值
if (i === 0) hex = convertFormat(startColor, 'hex')
// 确保最后一个颜色值为endColor的值
if (i === step - 1) hex = convertFormat(endColor, 'hex')
colorArr.push(hex)
}
return colorArr
}
export default {
/**
* 格式转换。
*/
convertFormat,
/**
* 计算两个颜色之间的渐变值。
*/
gradient,
/**
* 增加颜色的亮度。
* @param {string} color - 输入的颜色。
* @param {number} value - 增加的亮度值(0-1)。
* @returns {string} 调整后的颜色。
*/
lighten: (color, value, format = 'rgb', type = 'string') => convertFormat(Color(color).lighten(value), format, type),
/**
* 减少颜色的亮度。
* @param {string} color - 输入的颜色。
* @param {number} value - 减少的亮度值(0-1)。
* @returns {string} 调整后的颜色。
*/
darken: (color, value, format = 'rgb', type = 'string') => convertFormat(Color(color).darken(value), format, type),
/**
* 增加颜色的饱和度。
* @param {string} color - 输入的颜色。
* @param {number} value - 增加的饱和度值(0-1)。
* @returns {string} 调整后的颜色。
*/
saturate: (color, value, format = 'rgb', type = 'string') => convertFormat(Color(color).saturate(value), format, type),
/**
* 减少颜色的饱和度。
* @param {string} color - 输入的颜色。
* @param {number} value - 减少的饱和度值(0-1)。
* @returns {string} 调整后的颜色。
*/
desaturate: (color, value, format = 'rgb', type = 'string') => convertFormat(Color(color).desaturate(value), format, type),
/**
* 旋转颜色的色相。
* @param {string} color - 输入的颜色。
* @param {number} degrees - 旋转的度数。
* @returns {string} 调整后的颜色。
*/
rotate: (color, degrees, format = 'rgb', type = 'string') => convertFormat(Color(color).rotate(degrees), format, type),
/**
* 调整颜色的透明度。
* @param {string} color - 输入的颜色。
* @param {number} value - 透明度值(0-1,其中 1 是不透明)。
* @returns {string} 调整后的颜色。
*/
adjustAlpha: (color, value, format = 'rgb', type = 'string') => convertFormat(Color(color).alpha(value), format, type),
/**
* 获取颜色的亮度。
* @param {string} color - 输入的颜色。
* @returns {number} 颜色的亮度值(0-1)。
*/
luminosity: (color, format) => Color(color).luminosity(),
/**
* 判断颜色是否为暗色。
* @param {string} color - 输入的颜色。
* @returns {boolean} 如果是暗色则返回 true,否则返回 false。
*/
isDark: (color, format) => Color(color).isDark(),
/**
* 判断颜色是否为亮色。
* @param {string} color - 输入的颜色。
* @returns {boolean} 如果是亮色则返回 true,否则返回 false。
*/
isLight: (color, format) => Color(color).isLight()
};
\ No newline at end of file
The MIT License (MIT)
Copyright (c) 2015 JD Ballard
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# node-is-arrayish [![Travis-CI.org Build Status](https://img.shields.io/travis/Qix-/node-is-arrayish.svg?style=flat-square)](https://travis-ci.org/Qix-/node-is-arrayish) [![Coveralls.io Coverage Rating](https://img.shields.io/coveralls/Qix-/node-is-arrayish.svg?style=flat-square)](https://coveralls.io/r/Qix-/node-is-arrayish)
> Determines if an object can be used like an Array
## Example
```javascript
var isArrayish = require('is-arrayish');
isArrayish([]); // true
isArrayish({__proto__: []}); // true
isArrayish({}); // false
isArrayish({length:10}); // false
```
## License
Licensed under the [MIT License](http://opensource.org/licenses/MIT).
You can find a copy of it in [LICENSE](LICENSE).
export default function isArrayish(obj) {
if (!obj || typeof obj === 'string') {
return false;
}
return obj instanceof Array || Array.isArray(obj) ||
(obj.length >= 0 && (obj.splice instanceof Function ||
(Object.getOwnPropertyDescriptor(obj, (obj.length - 1)) && obj.constructor.name !== 'String')));
};
{
"name": "is-arrayish",
"description": "Determines if an object can be used as an array",
"version": "0.3.2",
"author": "Qix (http://github.com/qix-)",
"keywords": [
"is",
"array",
"duck",
"type",
"arrayish",
"similar",
"proto",
"prototype",
"type"
],
"license": "MIT",
"scripts": {
"test": "mocha --require coffeescript/register ./test/**/*.coffee",
"lint": "zeit-eslint --ext .jsx,.js .",
"lint-staged": "git diff --diff-filter=ACMRT --cached --name-only '*.js' '*.jsx' | xargs zeit-eslint"
},
"repository": {
"type": "git",
"url": "https://github.com/qix-/node-is-arrayish.git"
},
"devDependencies": {
"@zeit/eslint-config-node": "^0.3.0",
"@zeit/git-hooks": "^0.1.4",
"coffeescript": "^2.3.1",
"coveralls": "^3.0.1",
"eslint": "^4.19.1",
"istanbul": "^0.4.5",
"mocha": "^5.2.0",
"should": "^13.2.1"
},
"eslintConfig": {
"extends": [
"@zeit/eslint-config-node"
]
},
"git": {
"pre-commit": "lint-staged"
}
}
The MIT License (MIT)
Copyright (c) 2015 Josh Junon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# simple-swizzle [![Travis-CI.org Build Status](https://img.shields.io/travis/Qix-/node-simple-swizzle.svg?style=flat-square)](https://travis-ci.org/Qix-/node-simple-swizzle) [![Coveralls.io Coverage Rating](https://img.shields.io/coveralls/Qix-/node-simple-swizzle.svg?style=flat-square)](https://coveralls.io/r/Qix-/node-simple-swizzle)
> [Swizzle](https://en.wikipedia.org/wiki/Swizzling_(computer_graphics)) your function arguments; pass in mixed arrays/values and get a clean array
## Usage
```js
var swizzle = require('simple-swizzle');
function myFunc() {
var args = swizzle(arguments);
// ...
return args;
}
myFunc(1, [2, 3], 4); // [1, 2, 3, 4]
myFunc(1, 2, 3, 4); // [1, 2, 3, 4]
myFunc([1, 2, 3, 4]); // [1, 2, 3, 4]
```
Functions can also be wrapped to automatically swizzle arguments and be passed
the resulting array.
```js
var swizzle = require('simple-swizzle');
var swizzledFn = swizzle.wrap(function (args) {
// ...
return args;
});
swizzledFn(1, [2, 3], 4); // [1, 2, 3, 4]
swizzledFn(1, 2, 3, 4); // [1, 2, 3, 4]
swizzledFn([1, 2, 3, 4]); // [1, 2, 3, 4]
```
## License
Licensed under the [MIT License](http://opensource.org/licenses/MIT).
You can find a copy of it in [LICENSE](LICENSE).
'use strict';
import isArrayish from '../is-arrayish';
var concat = Array.prototype.concat;
var slice = Array.prototype.slice;
export default function swizzle(args) {
var results = [];
for (var i = 0, len = args.length; i < len; i++) {
var arg = args[i];
if (isArrayish(arg)) {
// http://jsperf.com/javascript-array-concat-vs-push/98
results = concat.call(results, slice.call(arg));
} else {
results.push(arg);
}
}
return results;
};
swizzle.wrap = function (fn) {
return function () {
return fn(swizzle(arguments));
};
};
{
"name": "simple-swizzle",
"description": "Simply swizzle your arguments",
"version": "0.2.2",
"author": "Qix (http://github.com/qix-)",
"keywords": [
"argument",
"arguments",
"swizzle",
"swizzling",
"parameter",
"parameters",
"mixed",
"array"
],
"license": "MIT",
"scripts": {
"pretest": "xo",
"test": "mocha --compilers coffee:coffee-script/register"
},
"files": [
"index.js"
],
"repository": "qix-/node-simple-swizzle",
"devDependencies": {
"coffee-script": "^1.9.3",
"coveralls": "^2.11.2",
"istanbul": "^0.3.17",
"mocha": "^2.2.5",
"should": "^7.0.1",
"xo": "^0.7.1"
},
"dependencies": {
"is-arrayish": "^0.3.1"
}
}
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