crm
This commit is contained in:
parent
61ab038c4e
commit
1b4278010e
26
App.vue
26
App.vue
@ -32,35 +32,9 @@
|
|||||||
main.SET_TOKEN(opt.accessToken);
|
main.SET_TOKEN(opt.accessToken);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onShow(() => {
|
|
||||||
// 检查用户登录情况
|
|
||||||
// #ifdef H5
|
|
||||||
if (isWeixin()) {
|
|
||||||
// H5编译的代码
|
|
||||||
// 判断是否是微信浏览器
|
|
||||||
//oAuth()
|
|
||||||
//return;
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
//wechatMiniLogin();
|
|
||||||
// #endif
|
|
||||||
})
|
|
||||||
|
|
||||||
onHide(() => {
|
|
||||||
console.log('App Hide')
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '~@/static/style/app.scss';
|
@import '~@/static/style/app.scss';
|
||||||
//@import 'static/iconfont/iconfont.scss';
|
|
||||||
//@import url('./static/style/style.less');
|
|
||||||
@import 'static/style/yshop.css';
|
@import 'static/style/yshop.css';
|
||||||
|
|
||||||
// /*每个页面公共css */
|
|
||||||
// page {
|
|
||||||
// background-color: #f5f5f5;
|
|
||||||
// }
|
|
||||||
</style>
|
</style>
|
13
pages.json
13
pages.json
@ -20,13 +20,6 @@
|
|||||||
"enablePullDownRefresh": true
|
"enablePullDownRefresh": true
|
||||||
}
|
}
|
||||||
|
|
||||||
}, {
|
|
||||||
"path": "pages/msg/index",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "消息",
|
|
||||||
"enablePullDownRefresh": false
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"subPackages": [{
|
"subPackages": [{
|
||||||
@ -363,12 +356,6 @@
|
|||||||
"iconPath": "static/images/tabBar/customer.png",
|
"iconPath": "static/images/tabBar/customer.png",
|
||||||
"selectedIconPath": "static/images/tabBar/customer-selected.png"
|
"selectedIconPath": "static/images/tabBar/customer-selected.png"
|
||||||
},
|
},
|
||||||
//{
|
|
||||||
// "pagePath": "pages/msg/index",
|
|
||||||
// "text": "消息",
|
|
||||||
// "iconPath": "static/images/tabBar/msg.png",
|
|
||||||
// "selectedIconPath": "static/images/tabBar/msg-select.png"
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
"pagePath": "pages/mine/mine",
|
"pagePath": "pages/mine/mine",
|
||||||
"text": "我的",
|
"text": "我的",
|
||||||
|
@ -17,15 +17,13 @@
|
|||||||
@scrolltolower="reachBottom">
|
@scrolltolower="reachBottom">
|
||||||
<view class="page-box">
|
<view class="page-box">
|
||||||
<block v-if="list.length > 0">
|
<block v-if="list.length > 0">
|
||||||
<uv-checkbox-group>
|
|
||||||
<view class="client" v-for="(item, index) in list" :key="index">
|
<view class="client" v-for="(item, index) in list" :key="index">
|
||||||
<view class="top">
|
<view class="top">
|
||||||
<view class="left">
|
<view>
|
||||||
<view class="store">
|
<radio activeBackgroundColor="#09b4f1" activeBorderColor="#09b4f1" color="#09b4f1" :disabled="true"
|
||||||
<uv-checkbox disabled activeColor="#09b4f1" :checked="item.checked"
|
:value="item.id" :checked="item.checked" />
|
||||||
:name="item.id">{{item.storeName}}</uv-checkbox>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
<view class="sku-name">{{item.storeName}}</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="item">
|
<view class="item">
|
||||||
@ -45,7 +43,6 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</uv-checkbox-group>
|
|
||||||
<uv-load-more :status="listStatus"></uv-load-more>
|
<uv-load-more :status="listStatus"></uv-load-more>
|
||||||
</block>
|
</block>
|
||||||
<uv-empty text="暂无数据" v-else margin-top="50" mode="list"></uv-empty>
|
<uv-empty text="暂无数据" v-else margin-top="50" mode="list"></uv-empty>
|
||||||
@ -150,6 +147,9 @@
|
|||||||
storeToRefs
|
storeToRefs
|
||||||
} from 'pinia'
|
} from 'pinia'
|
||||||
const main = useMainStore()
|
const main = useMainStore()
|
||||||
|
const {
|
||||||
|
selectProductList
|
||||||
|
} = storeToRefs(main)
|
||||||
const title = ref('选择产品')
|
const title = ref('选择产品')
|
||||||
const keyword = ref('')
|
const keyword = ref('')
|
||||||
const selected = ref(false)
|
const selected = ref(false)
|
||||||
@ -157,10 +157,6 @@
|
|||||||
const oldScrollTop = ref(0)
|
const oldScrollTop = ref(0)
|
||||||
const scrollTop = ref(-1)
|
const scrollTop = ref(-1)
|
||||||
const skuList = ref([])
|
const skuList = ref([])
|
||||||
|
|
||||||
// search: {
|
|
||||||
// fontSise: '18px'
|
|
||||||
// },
|
|
||||||
const list = ref([])
|
const list = ref([])
|
||||||
const selectList = ref([])
|
const selectList = ref([])
|
||||||
const consentShow = ref(false)
|
const consentShow = ref(false)
|
||||||
@ -178,7 +174,6 @@
|
|||||||
const thisIndex = ref(0)
|
const thisIndex = ref(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
onReady(() => {
|
onReady(() => {
|
||||||
uni.getSystemInfo({
|
uni.getSystemInfo({
|
||||||
success(res) {
|
success(res) {
|
||||||
@ -192,15 +187,11 @@
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
onLoad((e) => {
|
onLoad((opt) => {
|
||||||
//getBusinessList();
|
selectList.value = selectProductList.value || []
|
||||||
})
|
|
||||||
|
|
||||||
onShow(() => {
|
|
||||||
getProductList()
|
getProductList()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// 选中一个
|
// 选中一个
|
||||||
const selectShowRef = ref()
|
const selectShowRef = ref()
|
||||||
const onSelect = (val, i) => {
|
const onSelect = (val, i) => {
|
||||||
@ -210,7 +201,6 @@
|
|||||||
icon: 'error',
|
icon: 'error',
|
||||||
duration: 2000
|
duration: 2000
|
||||||
})
|
})
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
list.value.forEach((item, index) => {
|
list.value.forEach((item, index) => {
|
||||||
@ -230,7 +220,6 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectSku = async (val, index) => {
|
const selectSku = async (val, index) => {
|
||||||
@ -284,9 +273,9 @@
|
|||||||
})
|
})
|
||||||
selectList.value.splice(index, 1)
|
selectList.value.splice(index, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选好了
|
// 选好了
|
||||||
const chosen = () => {
|
const chosen = () => {
|
||||||
// 储存
|
|
||||||
main.SET_SELECT_PRODUCT(selectList.value)
|
main.SET_SELECT_PRODUCT(selectList.value)
|
||||||
uni.navigateBack();
|
uni.navigateBack();
|
||||||
}
|
}
|
||||||
@ -301,7 +290,6 @@
|
|||||||
}).then(res => {
|
}).then(res => {
|
||||||
if (res) {
|
if (res) {
|
||||||
res.list.forEach((item, index) => {
|
res.list.forEach((item, index) => {
|
||||||
//item.create_time = this.timeFormats(item.create_time)
|
|
||||||
item.checked = false
|
item.checked = false
|
||||||
// 设置默认数据
|
// 设置默认数据
|
||||||
item.nums = 1
|
item.nums = 1
|
||||||
@ -327,12 +315,11 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// scroll 滚动记录
|
|
||||||
const scroll = (e) => {
|
const scroll = (e) => {
|
||||||
oldScrollTop.value = e.detail.scrollTop
|
oldScrollTop.value = e.detail.scrollTop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 滚动到底部
|
// 滚动到底部
|
||||||
const reachBottom = () => {
|
const reachBottom = () => {
|
||||||
if (lastPage.value || listStatus.value == 'loading') return;
|
if (lastPage.value || listStatus.value == 'loading') return;
|
||||||
@ -374,17 +361,14 @@
|
|||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
|
|
||||||
.top {
|
.top {
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
.left {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
.store {
|
.sku-name {
|
||||||
font-size: 28rpx;
|
font-size: 30rpx;
|
||||||
font-weight: bold;
|
margin-left: 10rpx;
|
||||||
}
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.right {
|
.right {
|
||||||
|
@ -88,7 +88,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<!-- 底部按钮 -->
|
<!-- 底部按钮 -->
|
||||||
<view class="bottom-btn">
|
<view class="bottom-btn">
|
||||||
<uv-button :plain="true" @click="moreShow" customStyle="padding:0 80rpx;border:solid">更多</uv-button>
|
<view class="btn more-btn" @click="moreShow">更多</view>
|
||||||
<view class="btn entity ml-1" @click="onAdd">跟进</view>
|
<view class="btn entity ml-1" @click="onAdd">跟进</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -662,11 +662,21 @@
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.entity {
|
.entity {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #09b4f1;
|
background-color: #09b4f1;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.more-btn {
|
||||||
|
padding: 15rpx 60rpx;
|
||||||
|
background-color: #5ecc62;
|
||||||
|
color: #fff;
|
||||||
|
margin-right: 12rpx;
|
||||||
|
z-index: 999;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -686,6 +696,7 @@
|
|||||||
.grid-text {
|
.grid-text {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
margin-top: 4rpx;
|
margin-top: 4rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -70,12 +70,6 @@
|
|||||||
</template>
|
</template>
|
||||||
</uv-input>
|
</uv-input>
|
||||||
</uv-form-item>
|
</uv-form-item>
|
||||||
<!-- <uv-form-item label="审批人:">
|
|
||||||
<uv-input disabledColor="#ffffff" disabled v-model="form.flowAdminIdName" placeholder="请去审批流程里配置合同审批" />
|
|
||||||
</uv-form-item> -->
|
|
||||||
<!-- <uv-form-item label="备注:">
|
|
||||||
<uv-textarea v-model="form.remark" :disabled="isCheck" placeholder="请输入备注"></uv-textarea>
|
|
||||||
</uv-form-item> -->
|
|
||||||
</uv-form>
|
</uv-form>
|
||||||
<!-- 产品 -->
|
<!-- 产品 -->
|
||||||
<view class="flex cif-title" @click="type !== 'detail' ? selectProduct() : ''">
|
<view class="flex cif-title" @click="type !== 'detail' ? selectProduct() : ''">
|
||||||
@ -129,8 +123,8 @@
|
|||||||
<view class="item-photo-list-item" style="font-size: 0; position: relative;margin-bottom: 60rpx;"
|
<view class="item-photo-list-item" style="font-size: 0; position: relative;margin-bottom: 60rpx;"
|
||||||
:style="{marginRight:(index+1)%3==0?'0rpx':'20rpx'}" v-for="(item, index) in imgFiles" :key="item"
|
:style="{marginRight:(index+1)%3==0?'0rpx':'20rpx'}" v-for="(item, index) in imgFiles" :key="item"
|
||||||
@click="replaceImage(item, index)">
|
@click="replaceImage(item, index)">
|
||||||
<image v-if="!isCheck" src="@/static/greyguanbi.png" mode="aspectFit" class="item-photo-list-item-close"
|
<image v-if="!isCheck" src="https://sys.znkjfw.com/imgs/crmimages/close.png" mode="aspectFit"
|
||||||
@click.stop="deleteItem(item, index)"></image>
|
class="item-photo-list-item-close" @click.stop="deleteItem(item, index)"></image>
|
||||||
<image v-if="!isCheck" :src="item.url" mode="" style="width: 100%; height: 100%"></image>
|
<image v-if="!isCheck" :src="item.url" mode="" style="width: 100%; height: 100%"></image>
|
||||||
</view>
|
</view>
|
||||||
<image src="http://sys.znkjfw.com/imgs/process/uploadzp.png" mode="aspectFill" class="item-photo-list-item"
|
<image src="http://sys.znkjfw.com/imgs/process/uploadzp.png" mode="aspectFill" class="item-photo-list-item"
|
||||||
@ -144,8 +138,8 @@
|
|||||||
<view class="item-photo-list">
|
<view class="item-photo-list">
|
||||||
<view class="item-photo-list-item" style="font-size: 0; position: relative;margin-bottom: 60rpx;"
|
<view class="item-photo-list-item" style="font-size: 0; position: relative;margin-bottom: 60rpx;"
|
||||||
:style="{marginRight:(index+1)%3==0?'0rpx':'20rpx'}" v-for="(item, index) in pdfList" :key="item">
|
:style="{marginRight:(index+1)%3==0?'0rpx':'20rpx'}" v-for="(item, index) in pdfList" :key="item">
|
||||||
<image v-if="!isCheck" src="@/static/greyguanbi.png" mode="aspectFit" class="item-photo-list-item-close"
|
<image v-if="!isCheck" src="https://sys.znkjfw.com/imgs/crmimages/close.png" mode="aspectFit"
|
||||||
@click.stop="deleteFiles(item, index)"></image>
|
class="item-photo-list-item-close" @click.stop="deleteFiles(item, index)"></image>
|
||||||
<image v-if="!isCheck" src="http://sys.znkjfw.com/imgs/process/pdfIcon.png" mode=""
|
<image v-if="!isCheck" src="http://sys.znkjfw.com/imgs/process/pdfIcon.png" mode=""
|
||||||
style="width: 100%; height: 100%">
|
style="width: 100%; height: 100%">
|
||||||
</image>
|
</image>
|
||||||
@ -160,33 +154,8 @@
|
|||||||
<view class="mt-4" style="text-align: center;">
|
<view class="mt-4" style="text-align: center;">
|
||||||
<uv-button color="#09b4f1" @click="submit" :disabled="isCheck || submitBtn" :ripple="true">确定提交</uv-button>
|
<uv-button color="#09b4f1" @click="submit" :disabled="isCheck || submitBtn" :ripple="true">确定提交</uv-button>
|
||||||
</view>
|
</view>
|
||||||
<!-- <view class="mt-4 flex justify-end" style="text-align: center;" v-else>
|
|
||||||
<view style="width: 25%;margin-right: 10rpx;">
|
|
||||||
<uv-button color="#09b4f1" @click="submitCheck(1)">审核</uv-button>
|
|
||||||
</view>
|
</view>
|
||||||
<view style="width: 25%;">
|
|
||||||
<uv-button type="error" @click="selectShow5()">拒绝</uv-button>
|
|
||||||
</view>
|
|
||||||
</view> -->
|
|
||||||
</view>
|
|
||||||
<uv-popup mode="bottom" round="38" ref="selectShowRef5">
|
|
||||||
<view class="popup-content">
|
|
||||||
<view class="popup-title">
|
|
||||||
<view class="" style="width: 45px;">
|
|
||||||
</view>
|
|
||||||
<text class="">输入驳回理由</text>
|
|
||||||
<view class="" @click="selectShowClose5" style="width: 45px;">
|
|
||||||
<uv-icon name="close" color="#909399" size="24"></uv-icon>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view style="height: 500rpx;padding: 20rpx;">
|
|
||||||
<uv-textarea v-model="form2.remark" placeholder="输入驳回理由"></uv-textarea>
|
|
||||||
</view>
|
|
||||||
<view style="padding: 20rpx;">
|
|
||||||
<uv-button color="#09b4f1" @click="submitCheck(2)">确定</uv-button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</uv-popup>
|
|
||||||
<!-- 选择客户弹窗 -->
|
<!-- 选择客户弹窗 -->
|
||||||
<uv-popup mode="bottom" round="38" ref="selectShowRef">
|
<uv-popup mode="bottom" round="38" ref="selectShowRef">
|
||||||
<view class="popup-content">
|
<view class="popup-content">
|
||||||
@ -450,11 +419,6 @@
|
|||||||
const keyword3 = ref('')
|
const keyword3 = ref('')
|
||||||
const businessList = ref([])
|
const businessList = ref([])
|
||||||
const isCheck = ref(false)
|
const isCheck = ref(false)
|
||||||
const form2 = ref({
|
|
||||||
id: 0,
|
|
||||||
agreeType: 1,
|
|
||||||
remark: ''
|
|
||||||
})
|
|
||||||
|
|
||||||
onLoad((e) => {
|
onLoad((e) => {
|
||||||
type.value = e.type
|
type.value = e.type
|
||||||
@ -862,13 +826,6 @@
|
|||||||
selectShowClose4()
|
selectShowClose4()
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectShowRef5 = ref()
|
|
||||||
const selectShow5 = async () => {
|
|
||||||
unref(selectShowRef5).open()
|
|
||||||
}
|
|
||||||
const selectShowClose5 = () => {
|
|
||||||
unref(selectShowRef5).close()
|
|
||||||
}
|
|
||||||
|
|
||||||
//公司
|
//公司
|
||||||
const selectShowRef6 = ref()
|
const selectShowRef6 = ref()
|
||||||
@ -939,30 +896,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const submitCheck = async (type) => {
|
|
||||||
if (type == 2 && form2.value.remark == '') {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'error',
|
|
||||||
title: '请填写驳回理由'
|
|
||||||
})
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
form2.value.id = contractId.value
|
|
||||||
form2.value.type
|
|
||||||
await check(form2.value)
|
|
||||||
|
|
||||||
uni.showToast({
|
|
||||||
title: '审核成功',
|
|
||||||
icon: 'success',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
prePage().$vm.isRefresh = true
|
|
||||||
setTimeout(() => {
|
|
||||||
uni.navigateBack();
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 提交跟进
|
// 提交跟进
|
||||||
const uForm = ref()
|
const uForm = ref()
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
|
@ -71,8 +71,8 @@
|
|||||||
<view class="item-photo-list-item" style="font-size: 0; position: relative;margin-bottom: 60rpx;"
|
<view class="item-photo-list-item" style="font-size: 0; position: relative;margin-bottom: 60rpx;"
|
||||||
:style="{marginRight:(index+1)%3==0?'0rpx':'20rpx'}" v-for="(item, index) in imgFiles" :key="item"
|
:style="{marginRight:(index+1)%3==0?'0rpx':'20rpx'}" v-for="(item, index) in imgFiles" :key="item"
|
||||||
@click="replaceImage(item, index)">
|
@click="replaceImage(item, index)">
|
||||||
<image v-if="!isCheck" src="@/static/greyguanbi.png" mode="aspectFit" class="item-photo-list-item-close"
|
<image v-if="!isCheck" src="https://sys.znkjfw.com/imgs/crmimages/close.png" mode="aspectFit"
|
||||||
@click.stop="deleteItem(item, index)"></image>
|
class="item-photo-list-item-close" @click.stop="deleteItem(item, index)"></image>
|
||||||
<image v-if="!isCheck" :src="item.url" mode="" style="width: 100%; height: 100%"></image>
|
<image v-if="!isCheck" :src="item.url" mode="" style="width: 100%; height: 100%"></image>
|
||||||
</view>
|
</view>
|
||||||
<image src="http://sys.znkjfw.com/imgs/process/uploadzp.png" mode="aspectFill" class="item-photo-list-item"
|
<image src="http://sys.znkjfw.com/imgs/process/uploadzp.png" mode="aspectFill" class="item-photo-list-item"
|
||||||
@ -86,8 +86,8 @@
|
|||||||
<view class="item-photo-list">
|
<view class="item-photo-list">
|
||||||
<view class="item-photo-list-item" style="font-size: 0; position: relative;margin-bottom: 60rpx;"
|
<view class="item-photo-list-item" style="font-size: 0; position: relative;margin-bottom: 60rpx;"
|
||||||
:style="{marginRight:(index+1)%3==0?'0rpx':'20rpx'}" v-for="(item, index) in pdfList" :key="item">
|
:style="{marginRight:(index+1)%3==0?'0rpx':'20rpx'}" v-for="(item, index) in pdfList" :key="item">
|
||||||
<image v-if="!isCheck" src="@/static/greyguanbi.png" mode="aspectFit" class="item-photo-list-item-close"
|
<image v-if="!isCheck" src="https://sys.znkjfw.com/imgs/crmimages/close.png" mode="aspectFit"
|
||||||
@click.stop="deleteFiles(item, index)"></image>
|
class="item-photo-list-item-close" @click.stop="deleteFiles(item, index)"></image>
|
||||||
<image v-if="!isCheck" src="http://sys.znkjfw.com/imgs/process/pdfIcon.png" mode=""
|
<image v-if="!isCheck" src="http://sys.znkjfw.com/imgs/process/pdfIcon.png" mode=""
|
||||||
style="width: 100%; height: 100%">
|
style="width: 100%; height: 100%">
|
||||||
</image>
|
</image>
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
<template>
|
|
||||||
<uv-navbar :fixed="false" @leftClick="$onClickLeft" bgColor="#09b4f1">
|
|
||||||
<template v-slot:left>
|
|
||||||
<uv-icon name="arrow-left" size="19" color="#ffffff"></uv-icon>
|
|
||||||
</template>
|
|
||||||
<template v-slot:center>
|
|
||||||
<text style="color:#ffffff">{{title}}</text>
|
|
||||||
</template>
|
|
||||||
</uv-navbar>
|
|
||||||
<view class="bg-white">
|
|
||||||
<uv-cell-group>
|
|
||||||
<uv-cell icon="http://sys.znkjfw.com/imgs/crmimages/16.png" title="待办事项" label="待办事项消息提现" isLink
|
|
||||||
url="/pages/components/pages/msg/wait" iconStyle="height:70rpx;width:70rpx;margin-right:10rpx">
|
|
||||||
<template v-slot:right-icon>
|
|
||||||
<view class="flex align-center">
|
|
||||||
<uv-badge type="error" max="99" :value="waitCount"></uv-badge>
|
|
||||||
<uv-icon size="30rpx" name="arrow-right"></uv-icon>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</uv-cell>
|
|
||||||
<uv-cell icon="http://sys.znkjfw.com/imgs/crmimages/15.png" title="审批管理" label="审批消息提现" isLink
|
|
||||||
url="/pages/components/pages/msg/exam" iconStyle="height:70rpx;width:70rpx;margin-right:10rpx">
|
|
||||||
<template v-slot:right-icon>
|
|
||||||
<view class="flex align-center">
|
|
||||||
<uv-badge type="error" max="99" :value="checkCount"></uv-badge>
|
|
||||||
<uv-icon size="30rpx" name="arrow-right"></uv-icon>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</uv-cell>
|
|
||||||
<uv-cell icon="http://sys.znkjfw.com/imgs/crmimages/23.png" title="通知管理" label="系统公告通知" isLink
|
|
||||||
url="/pages/components/pages/mine/list" iconStyle="height:70rpx;width:70rpx;margin-right:10rpx">
|
|
||||||
<template v-slot:right-icon>
|
|
||||||
<view class="flex align-center">
|
|
||||||
<uv-badge type="error" max="99" :value="noticeCount"></uv-badge>
|
|
||||||
<uv-icon size="30rpx" name="arrow-right"></uv-icon>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</uv-cell>
|
|
||||||
</uv-cell-group>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import {
|
|
||||||
ref,
|
|
||||||
computed
|
|
||||||
} from 'vue'
|
|
||||||
import {
|
|
||||||
useMainStore
|
|
||||||
} from '@/store/store'
|
|
||||||
import {
|
|
||||||
storeToRefs
|
|
||||||
} from 'pinia'
|
|
||||||
import {
|
|
||||||
onLoad,
|
|
||||||
onShow
|
|
||||||
} from '@dcloudio/uni-app'
|
|
||||||
const main = useMainStore()
|
|
||||||
const {
|
|
||||||
indexCount
|
|
||||||
} = storeToRefs(main)
|
|
||||||
const title = ref('消息')
|
|
||||||
const cart = ref([])
|
|
||||||
const uToast = ref()
|
|
||||||
const waitCount = ref(0)
|
|
||||||
const checkCount = ref(0)
|
|
||||||
const noticeCount = ref(0)
|
|
||||||
|
|
||||||
onShow(() => {
|
|
||||||
noticeCount.value = indexCount.value.brieCountVO?.count13 || 0
|
|
||||||
waitCount.value = indexCount.value.followBusinessCount + indexCount.value.followCluesCount + indexCount.value
|
|
||||||
.followCustomerCount
|
|
||||||
checkCount.value = indexCount.value.contractCheckCount + indexCount.value.invoiceCheckCount + indexCount.value
|
|
||||||
.receivablesCheckCount
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
|
|
||||||
</style>
|
|
@ -1,23 +0,0 @@
|
|||||||
@font-face {
|
|
||||||
font-family: "iconfont"; /* Project id 4205200 */
|
|
||||||
src: url('~@/static/iconfont/iconfont.woff2?t=1691643169117') format('woff2'),
|
|
||||||
url('~@/static/iconfont/iconfont.woff?t=1691643169117') format('woff'),
|
|
||||||
url('~@/static/iconfont/iconfont.ttf?t=1691643169117') format('truetype');
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
font-family: "iconfont" !important;
|
|
||||||
font-size: 16px;
|
|
||||||
font-style: normal;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-waimai-:before {
|
|
||||||
content: "\e607";
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-tangshi:before {
|
|
||||||
content: "\e645";
|
|
||||||
}
|
|
||||||
|
|
@ -1,270 +0,0 @@
|
|||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'iconfont-yshop';
|
|
||||||
src: url('//at.alicdn.com/t/font_2012069_r7oux4ay0ls.eot');
|
|
||||||
src: url('//at.alicdn.com/t/font_2012069_r7oux4ay0ls.eot?#iefix') format('embedded-opentype'),
|
|
||||||
url('//at.alicdn.com/t/font_2012069_r7oux4ay0ls.woff2') format('woff2'),
|
|
||||||
url('//at.alicdn.com/t/font_2012069_r7oux4ay0ls.woff') format('woff'),
|
|
||||||
url('//at.alicdn.com/t/font_2012069_r7oux4ay0ls.ttf') format('truetype'),
|
|
||||||
url('//at.alicdn.com/t/font_2012069_r7oux4ay0ls.svg#iconfont-yshop') format('svg');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconfont-yshop {
|
|
||||||
font-family: 'iconfont-yshop' !important;
|
|
||||||
font-size: 16px;
|
|
||||||
font-style: normal;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
color: #09b4f1;
|
|
||||||
}
|
|
||||||
.icon-alipay:before {
|
|
||||||
content: '\e60a';
|
|
||||||
}
|
|
||||||
.icon-shop:before {
|
|
||||||
content: '\e664';
|
|
||||||
}
|
|
||||||
.icon-takein:before {
|
|
||||||
content: '\e666';
|
|
||||||
}
|
|
||||||
.icon-takeout:before {
|
|
||||||
content: '\e667';
|
|
||||||
}
|
|
||||||
.icon-location:before {
|
|
||||||
content: '\e633';
|
|
||||||
}
|
|
||||||
.icon-mobile:before {
|
|
||||||
content: '\e602';
|
|
||||||
}
|
|
||||||
.icon-box:before {
|
|
||||||
content: '\e665';
|
|
||||||
}
|
|
||||||
.icon-lamp:before {
|
|
||||||
content: '\e668';
|
|
||||||
}
|
|
||||||
.icon-doorbell:before {
|
|
||||||
content: '\e662';
|
|
||||||
}
|
|
||||||
.icon-daojishi:before {
|
|
||||||
content: '\e625';
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'iconfont';
|
|
||||||
src: url('//at.alicdn.com/t/font_1789197_z1gzlwq7idq.ttf?t=1589441233693') format('truetype');
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
font-family: 'iconfont' !important;
|
|
||||||
font-size: 16px;
|
|
||||||
font-style: normal;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconshoucang:before {
|
|
||||||
content: '\e667';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconshoucangfill:before {
|
|
||||||
content: '\e6c9';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconjifen:before {
|
|
||||||
content: '\e642';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconradio-button-off:before {
|
|
||||||
content: '\e688';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconradio-button-on:before {
|
|
||||||
content: '\e689';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconhelp:before {
|
|
||||||
content: '\e752';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconwxpay:before {
|
|
||||||
content: '\e611';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconbalance:before {
|
|
||||||
content: '\e619';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconadd-select:before {
|
|
||||||
content: '\e7b0';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconsami-select:before {
|
|
||||||
content: '\e7b1';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconmap:before {
|
|
||||||
content: '\e758';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconsuccess:before {
|
|
||||||
content: '\e767';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconsuccess-fill:before {
|
|
||||||
content: '\e78d';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconiconset0136:before {
|
|
||||||
content: '\e623';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconzan:before {
|
|
||||||
content: '\e640';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconjifenqiandao:before {
|
|
||||||
content: '\e6a6';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconshouyeshouye:before {
|
|
||||||
content: '\e606';
|
|
||||||
}
|
|
||||||
|
|
||||||
.icondaohang:before {
|
|
||||||
content: '\e641';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconwodelianxikefu:before {
|
|
||||||
content: '\e671';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconwodexinyuan:before {
|
|
||||||
content: '\e675';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconphone:before {
|
|
||||||
content: '\e6dd';
|
|
||||||
}
|
|
||||||
|
|
||||||
.icondingdan:before {
|
|
||||||
content: '\e645';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconliwu:before {
|
|
||||||
content: '\e61c';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconyinpinyinliao:before {
|
|
||||||
content: '\e60d';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconyinpin:before {
|
|
||||||
content: '\e70b';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconwaimaixinxi:before {
|
|
||||||
content: '\e685';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconico:before {
|
|
||||||
content: '\e646';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconwode:before {
|
|
||||||
content: '\e616';
|
|
||||||
}
|
|
||||||
|
|
||||||
.icongengduofuwu:before {
|
|
||||||
content: '\e607';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconqucan:before {
|
|
||||||
content: '\e625';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconyou:before {
|
|
||||||
content: '\e618';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconshouhuodizhi:before {
|
|
||||||
content: '\e666';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconshangcheng:before {
|
|
||||||
content: '\e63b';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconadd:before {
|
|
||||||
content: '\e742';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconarrow-right:before {
|
|
||||||
content: '\e743';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconarrow-lift:before {
|
|
||||||
content: '\e744';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconarrow-up:before {
|
|
||||||
content: '\e745';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconclose:before {
|
|
||||||
content: '\e747';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconleftbutton:before {
|
|
||||||
content: '\e755';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconreduce:before {
|
|
||||||
content: '\e75e';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconseleted:before {
|
|
||||||
content: '\e763';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconRightbutton:before {
|
|
||||||
content: '\e765';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconleftbutton-fill:before {
|
|
||||||
content: '\e782';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconRightbutton-fill:before {
|
|
||||||
content: '\e78a';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconarrow-down:before {
|
|
||||||
content: '\e7b2';
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconaixin1:before {
|
|
||||||
content: '\e63c';
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "iconfont"; /* Project id 4205200 */
|
|
||||||
src: url('~@/static/iconfont/iconfont.woff2') format('woff2'),
|
|
||||||
url('~@/static/iconfont/iconfont.woff') format('woff'),
|
|
||||||
url('~@/static/iconfont/iconfont.ttf') format('truetype');
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
font-family: "iconfont" !important;
|
|
||||||
font-size: 16px;
|
|
||||||
font-style: normal;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-waimai-:before {
|
|
||||||
content: "\e607";
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-tangshi:before {
|
|
||||||
content: "\e645";
|
|
||||||
}
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.6 KiB |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
6
uni.scss
6
uni.scss
@ -112,9 +112,3 @@ $uv-info: #909399;
|
|||||||
$uv-info-dark: #767a82;
|
$uv-info-dark: #767a82;
|
||||||
$uv-info-disabled: #c4c6c9;
|
$uv-info-disabled: #c4c6c9;
|
||||||
$uv-info-light: #f4f4f5;
|
$uv-info-light: #f4f4f5;
|
||||||
|
|
||||||
|
|
||||||
@import '~@/static/iconfont/iconfont.scss';
|
|
||||||
|
|
||||||
/* uni.scss */
|
|
||||||
// @import 'uview-ui/theme.scss';
|
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
## 1.0.2(2023-07-03)
|
|
||||||
1. 优化插槽自定义内容部分
|
|
||||||
2. 增加backToTop方法说明
|
|
||||||
## 1.0.1(2023-05-16)
|
|
||||||
1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
|
|
||||||
2. 优化部分功能
|
|
||||||
## 1.0.0(2023-05-10)
|
|
||||||
uv-back-top 返回顶部
|
|
@ -1,58 +0,0 @@
|
|||||||
export default {
|
|
||||||
props: {
|
|
||||||
// 返回顶部的形状,circle-圆形,square-方形
|
|
||||||
mode: {
|
|
||||||
type: String,
|
|
||||||
default: 'circle'
|
|
||||||
},
|
|
||||||
// 自定义图标
|
|
||||||
icon: {
|
|
||||||
type: String,
|
|
||||||
default: 'arrow-upward'
|
|
||||||
},
|
|
||||||
// 提示文字
|
|
||||||
text: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 返回顶部滚动时间
|
|
||||||
duration: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 100
|
|
||||||
},
|
|
||||||
// 滚动距离
|
|
||||||
scrollTop: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
// 距离顶部多少距离显示,单位px
|
|
||||||
top: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 400
|
|
||||||
},
|
|
||||||
// 返回顶部按钮到底部的距离,单位px
|
|
||||||
bottom: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 100
|
|
||||||
},
|
|
||||||
// 返回顶部按钮到右边的距离,单位px
|
|
||||||
right: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 20
|
|
||||||
},
|
|
||||||
// 层级
|
|
||||||
zIndex: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 9
|
|
||||||
},
|
|
||||||
// 图标的样式,对象形式
|
|
||||||
iconStyle: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({
|
|
||||||
color: '#909399',
|
|
||||||
fontSize: '19px'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
...uni.$uv?.props?.backtop
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,116 +0,0 @@
|
|||||||
<template>
|
|
||||||
<uv-transition mode="fade" :customStyle="backTopStyle" :show="show">
|
|
||||||
<slot>
|
|
||||||
<view class="uv-back-top" :style="[contentStyle]" @click="backToTop">
|
|
||||||
<uv-icon :name="icon" :custom-style="iconStyle"></uv-icon>
|
|
||||||
<text v-if="text" class="uv-back-top__text">{{text}}</text>
|
|
||||||
</view>
|
|
||||||
</slot>
|
|
||||||
</uv-transition>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
|
||||||
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
|
||||||
import props from './props.js';
|
|
||||||
// #ifdef APP-NVUE
|
|
||||||
const dom = weex.requireModule('dom')
|
|
||||||
// #endif
|
|
||||||
/**
|
|
||||||
* backTop 返回顶部
|
|
||||||
* @description 本组件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。
|
|
||||||
* @tutorial https://www.uvui.cn/components/backTop.html
|
|
||||||
* @property {String} mode 返回顶部的形状,circle-圆形,square-方形 (默认 'circle' )
|
|
||||||
* @property {String} icon 自定义图标 (默认 'arrow-upward' ) 见官方文档示例
|
|
||||||
* @property {String} text 提示文字
|
|
||||||
* @property {String | Number} duration 返回顶部滚动时间 (默认 100)
|
|
||||||
* @property {String | Number} scrollTop 滚动距离 (默认 0 )
|
|
||||||
* @property {String | Number} top 距离顶部多少距离显示,单位px (默认 400 )
|
|
||||||
* @property {String | Number} bottom 返回顶部按钮到底部的距离,单位px (默认 100 )
|
|
||||||
* @property {String | Number} right 返回顶部按钮到右边的距离,单位px (默认 20 )
|
|
||||||
* @property {String | Number} zIndex 层级 (默认 9 )
|
|
||||||
* @property {Object<Object>} iconStyle 图标的样式,对象形式 (默认 {color: '#909399',fontSize: '19px'})
|
|
||||||
* @property {Object} customStyle 定义需要用到的外部样式
|
|
||||||
*
|
|
||||||
* @example <uv-back-top :scrollTop="scrollTop"></uv-back-top>
|
|
||||||
*/
|
|
||||||
export default {
|
|
||||||
name: 'uv-back-top',
|
|
||||||
emits: ['click'],
|
|
||||||
mixins: [mpMixin, mixin, props],
|
|
||||||
computed: {
|
|
||||||
backTopStyle() {
|
|
||||||
// 动画组件样式
|
|
||||||
const style = {
|
|
||||||
bottom: this.$uv.addUnit(this.bottom),
|
|
||||||
right: this.$uv.addUnit(this.right),
|
|
||||||
width: '40px',
|
|
||||||
height: '40px',
|
|
||||||
position: 'fixed',
|
|
||||||
zIndex: 10,
|
|
||||||
}
|
|
||||||
return style
|
|
||||||
},
|
|
||||||
show() {
|
|
||||||
return this.$uv.getPx(this.scrollTop) > this.$uv.getPx(this.top)
|
|
||||||
},
|
|
||||||
contentStyle() {
|
|
||||||
const style = {}
|
|
||||||
let radius = 0
|
|
||||||
// 是否圆形
|
|
||||||
if (this.mode === 'circle') {
|
|
||||||
radius = '100px'
|
|
||||||
} else {
|
|
||||||
radius = '4px'
|
|
||||||
}
|
|
||||||
// 为了兼容安卓nvue,只能这么分开写
|
|
||||||
style.borderTopLeftRadius = radius
|
|
||||||
style.borderTopRightRadius = radius
|
|
||||||
style.borderBottomLeftRadius = radius
|
|
||||||
style.borderBottomRightRadius = radius
|
|
||||||
return this.$uv.deepMerge(style, this.$uv.addStyle(this.customStyle))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
backToTop() {
|
|
||||||
// #ifdef APP-NVUE
|
|
||||||
if (!this.$parent.$refs['uv-back-top']) {
|
|
||||||
this.$uv.error(`nvue页面需要给页面最外层元素设置"ref='uv-back-top'`)
|
|
||||||
}
|
|
||||||
dom.scrollToElement(this.$parent.$refs['uv-back-top'], {
|
|
||||||
offset: 0
|
|
||||||
})
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifndef APP-NVUE
|
|
||||||
uni.pageScrollTo({
|
|
||||||
scrollTop: 0,
|
|
||||||
duration: this.duration
|
|
||||||
});
|
|
||||||
// #endif
|
|
||||||
this.$emit('click')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
|
||||||
$uv-back-top-flex: 1 !default;
|
|
||||||
$uv-back-top-height: 100% !default;
|
|
||||||
$uv-back-top-background-color: #E1E1E1 !default;
|
|
||||||
$uv-back-top-tips-font-size: 12px !default;
|
|
||||||
.uv-back-top {
|
|
||||||
@include flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
flex: $uv-back-top-flex;
|
|
||||||
height: $uv-back-top-height;
|
|
||||||
justify-content: center;
|
|
||||||
background-color: $uv-back-top-background-color;
|
|
||||||
&__tips {
|
|
||||||
font-size: $uv-back-top-tips-font-size;
|
|
||||||
transform: scale(0.8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,89 +0,0 @@
|
|||||||
{
|
|
||||||
"id": "uv-back-top",
|
|
||||||
"displayName": "uv-back-top 返回顶部 全面兼容小程序、nvue、vue2、vue3等多端",
|
|
||||||
"version": "1.0.2",
|
|
||||||
"description": "返回顶部 组件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。",
|
|
||||||
"keywords": [
|
|
||||||
"uv-back-top",
|
|
||||||
"uvui",
|
|
||||||
"uv-ui",
|
|
||||||
"avatar",
|
|
||||||
"返回顶部"
|
|
||||||
],
|
|
||||||
"repository": "",
|
|
||||||
"engines": {
|
|
||||||
"HBuilderX": "^3.1.0"
|
|
||||||
},
|
|
||||||
"dcloudext": {
|
|
||||||
"type": "component-vue",
|
|
||||||
"sale": {
|
|
||||||
"regular": {
|
|
||||||
"price": "0.00"
|
|
||||||
},
|
|
||||||
"sourcecode": {
|
|
||||||
"price": "0.00"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"contact": {
|
|
||||||
"qq": ""
|
|
||||||
},
|
|
||||||
"declaration": {
|
|
||||||
"ads": "无",
|
|
||||||
"data": "插件不采集任何数据",
|
|
||||||
"permissions": "无"
|
|
||||||
},
|
|
||||||
"npmurl": ""
|
|
||||||
},
|
|
||||||
"uni_modules": {
|
|
||||||
"dependencies": [
|
|
||||||
"uv-ui-tools",
|
|
||||||
"uv-icon",
|
|
||||||
"uv-transition"
|
|
||||||
],
|
|
||||||
"encrypt": [],
|
|
||||||
"platforms": {
|
|
||||||
"cloud": {
|
|
||||||
"tcb": "y",
|
|
||||||
"aliyun": "y"
|
|
||||||
},
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
## BackTop 返回顶部
|
|
||||||
|
|
||||||
> **组件名:uv-back-top**
|
|
||||||
|
|
||||||
该组件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。
|
|
||||||
|
|
||||||
### <a href="https://www.uvui.cn/components/backTop.html" target="_blank">查看文档</a>
|
|
||||||
|
|
||||||
### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
|
||||||
|
|
||||||
#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
|
@ -1,32 +0,0 @@
|
|||||||
## 1.0.13(2023-10-11)
|
|
||||||
1. 优化同类问题:https://gitee.com/climblee/uv-ui/issues/I872VD
|
|
||||||
## 1.0.12(2023-09-22)
|
|
||||||
1. 修复change回调中v-model值不更新的BUG
|
|
||||||
## 1.0.11(2023-09-01)
|
|
||||||
1. 修复点击空隙处无效的问题
|
|
||||||
2. label支持插槽下可点击
|
|
||||||
## 1.0.10(2023-08-27)
|
|
||||||
1. 修复label设置布尔值不生效的BUG
|
|
||||||
## 1.0.9(2023-08-16)
|
|
||||||
1. 解决数据多不换行的BUG
|
|
||||||
## 1.0.8(2023-07-13)
|
|
||||||
1. 修复 uv-checkbox设置value属性不生效的BUG
|
|
||||||
## 1.0.7(2023-07-05)
|
|
||||||
修复vue3模式下,动态修改v-model绑定的值无效的BUG
|
|
||||||
## 1.0.6(2023-06-29)
|
|
||||||
1. 增加label插槽,与radio保持一致
|
|
||||||
2. 优化文档
|
|
||||||
## 1.0.5(2023-06-12)
|
|
||||||
1. 修复1.0.4改出的问题
|
|
||||||
## 1.0.4(2023-06-08)
|
|
||||||
1. 复选框修复全局设置不生效的BUG
|
|
||||||
## 1.0.3(2023-06-06)
|
|
||||||
1. uv-checkbox-group 兼容自定义样式customStyle,方便通过样式调整整体位置等;
|
|
||||||
2. .uv-checkbox-group--row增加flex-wrap: wrap;允许换行
|
|
||||||
## 1.0.2(2023-05-30)
|
|
||||||
1. 修复error报错的BUG
|
|
||||||
## 1.0.1(2023-05-16)
|
|
||||||
1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
|
|
||||||
2. 优化部分功能
|
|
||||||
## 1.0.0(2023-05-10)
|
|
||||||
uv-checkbox 复选框
|
|
@ -1,84 +0,0 @@
|
|||||||
export default {
|
|
||||||
props: {
|
|
||||||
// 绑定的值
|
|
||||||
value: {
|
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
},
|
|
||||||
modelValue: {
|
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
},
|
|
||||||
// 标识符
|
|
||||||
name: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 形状,circle-圆形,square-方形
|
|
||||||
shape: {
|
|
||||||
type: String,
|
|
||||||
default: 'square'
|
|
||||||
},
|
|
||||||
// 是否禁用全部checkbox
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值
|
|
||||||
activeColor: {
|
|
||||||
type: String,
|
|
||||||
default: '#2979ff'
|
|
||||||
},
|
|
||||||
// 未选中的颜色
|
|
||||||
inactiveColor: {
|
|
||||||
type: String,
|
|
||||||
default: '#c8c9cc'
|
|
||||||
},
|
|
||||||
// 整个组件的尺寸,默认px
|
|
||||||
size: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 18
|
|
||||||
},
|
|
||||||
// 布局方式,row-横向,column-纵向
|
|
||||||
placement: {
|
|
||||||
type: String,
|
|
||||||
default: 'row'
|
|
||||||
},
|
|
||||||
// label的字体大小,px单位
|
|
||||||
labelSize: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 14
|
|
||||||
},
|
|
||||||
// label的字体颜色
|
|
||||||
labelColor: {
|
|
||||||
type: [String],
|
|
||||||
default: '#303133'
|
|
||||||
},
|
|
||||||
// 是否禁止点击文本操作
|
|
||||||
labelDisabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 图标颜色
|
|
||||||
iconColor: {
|
|
||||||
type: String,
|
|
||||||
default: '#fff'
|
|
||||||
},
|
|
||||||
// 图标的大小,单位px
|
|
||||||
iconSize: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 12
|
|
||||||
},
|
|
||||||
// 勾选图标的对齐方式,left-左边,right-右边
|
|
||||||
iconPlacement: {
|
|
||||||
type: String,
|
|
||||||
default: 'left'
|
|
||||||
},
|
|
||||||
// 竖向配列时,是否显示下划线
|
|
||||||
borderBottom: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
...uni.$uv?.props?.checkboxGroup
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,119 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view
|
|
||||||
class="uv-checkbox-group"
|
|
||||||
:class="bemClass"
|
|
||||||
:style="[$uv.addStyle(this.customStyle)]"
|
|
||||||
>
|
|
||||||
<slot></slot>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
|
||||||
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
|
||||||
import props from './props.js';
|
|
||||||
/**
|
|
||||||
* checkboxGroup 复选框组
|
|
||||||
* @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
|
|
||||||
* @tutorial https://www.uvui.cn/components/checkbox.html
|
|
||||||
* @property {String} name 标识符
|
|
||||||
* @property {Array} value 绑定的值
|
|
||||||
* @property {String} shape 形状,circle-圆形,square-方形 (默认 'square' )
|
|
||||||
* @property {Boolean} disabled 是否禁用全部checkbox (默认 false )
|
|
||||||
* @property {String} activeColor 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值 (默认 '#2979ff' )
|
|
||||||
* @property {String} inactiveColor 未选中的颜色 (默认 '#c8c9cc' )
|
|
||||||
* @property {String | Number} size 整个组件的尺寸 单位px (默认 18 )
|
|
||||||
* @property {String} placement 布局方式,row-横向,column-纵向 (默认 'row' )
|
|
||||||
* @property {String | Number} labelSize label的字体大小,px单位 (默认 14 )
|
|
||||||
* @property {String} labelColor label的字体颜色 (默认 '#303133' )
|
|
||||||
* @property {Boolean} labelDisabled 是否禁止点击文本操作 (默认 false )
|
|
||||||
* @property {String} iconColor 图标颜色 (默认 '#ffffff' )
|
|
||||||
* @property {String | Number} iconSize 图标的大小,单位px (默认 12 )
|
|
||||||
* @property {String} iconPlacement 勾选图标的对齐方式,left-左边,right-右边 (默认 'left' )
|
|
||||||
* @property {Boolean} borderBottom placement为row时,是否显示下边框 (默认 false )
|
|
||||||
* @event {Function} change 任一个checkbox状态发生变化时触发,回调为一个对象
|
|
||||||
* @event {Function} input 修改通过v-model绑定的值时触发,回调为一个对象
|
|
||||||
* @example <uv-checkbox-group></uv-checkbox-group>
|
|
||||||
*/
|
|
||||||
export default {
|
|
||||||
name: 'uv-checkbox-group',
|
|
||||||
mixins: [mpMixin, mixin, props],
|
|
||||||
computed: {
|
|
||||||
// 这里computed的变量,都是子组件uv-checkbox需要用到的,由于头条小程序的兼容性差异,子组件无法实时监听父组件参数的变化
|
|
||||||
// 所以需要手动通知子组件,这里返回一个parentData变量,供watch监听,在其中去通知每一个子组件重新从父组件(uv-checkbox-group)
|
|
||||||
// 拉取父组件新的变化后的参数
|
|
||||||
parentData() {
|
|
||||||
let value = [];
|
|
||||||
if(this.value.length) {
|
|
||||||
value = this.value;
|
|
||||||
} else if (this.modelValue.length){
|
|
||||||
value = this.modelValue;
|
|
||||||
}
|
|
||||||
return [value, this.disabled, this.inactiveColor, this.activeColor, this.size, this.labelDisabled, this.shape,
|
|
||||||
this.iconSize, this.borderBottom, this.placement, this.labelSize, this.labelColor]
|
|
||||||
},
|
|
||||||
bemClass() {
|
|
||||||
// this.bem为一个computed变量,在mixin中
|
|
||||||
return this.bem('checkbox-group', ['placement'])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
// 当父组件需要子组件需要共享的参数发生了变化,手动通知子组件
|
|
||||||
parentData() {
|
|
||||||
if (this.children.length) {
|
|
||||||
this.children.map(child => {
|
|
||||||
// 判断子组件(uv-checkbox)如果有init方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
|
|
||||||
typeof(child.init) === 'function' && child.init()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.children = []
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 将其他的checkbox设置为未选中的状态
|
|
||||||
unCheckedOther(childInstance) {
|
|
||||||
const values = []
|
|
||||||
this.children.map(child => {
|
|
||||||
// 将被选中的checkbox,放到数组中返回
|
|
||||||
if (child.isChecked) {
|
|
||||||
values.push(child.name)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// 修改通过v-model绑定的值
|
|
||||||
// #ifdef VUE2
|
|
||||||
this.$emit('input', values)
|
|
||||||
// #endif
|
|
||||||
// #ifdef VUE3
|
|
||||||
this.$emit('update:modelValue',values)
|
|
||||||
// #endif
|
|
||||||
// 发出事件
|
|
||||||
this.$emit('change', values)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
|
|
||||||
|
|
||||||
.uv-checkbox-group {
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
&--row {
|
|
||||||
@include flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--column {
|
|
||||||
@include flex(column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,70 +0,0 @@
|
|||||||
export default {
|
|
||||||
props: {
|
|
||||||
// checkbox的名称
|
|
||||||
name: {
|
|
||||||
type: [String, Number, Boolean],
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 形状,square为方形,circle为圆型
|
|
||||||
shape: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 整体的大小
|
|
||||||
size: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 是否默认选中
|
|
||||||
checked: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 是否禁用
|
|
||||||
disabled: {
|
|
||||||
type: [String, Boolean],
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值
|
|
||||||
activeColor: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 未选中的颜色
|
|
||||||
inactiveColor: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 图标的大小,单位px
|
|
||||||
iconSize: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 图标颜色
|
|
||||||
iconColor: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式
|
|
||||||
label: {
|
|
||||||
type: [String, Number, Boolean],
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// label的字体大小,px单位
|
|
||||||
labelSize: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// label的颜色
|
|
||||||
labelColor: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 是否禁止点击提示语选中复选框
|
|
||||||
labelDisabled: {
|
|
||||||
type: [String, Boolean],
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
...uni.$uv?.props?.checkbox
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,369 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view
|
|
||||||
class="uv-checkbox"
|
|
||||||
:style="[checkboxStyle]"
|
|
||||||
@tap.stop="wrapperClickHandler"
|
|
||||||
:class="[`uv-checkbox-label--${parentData.iconPlacement}`, parentData.borderBottom && parentData.placement === 'column' && 'uv-border-bottom']"
|
|
||||||
>
|
|
||||||
<view
|
|
||||||
class="uv-checkbox__icon-wrap"
|
|
||||||
@tap.stop="iconClickHandler"
|
|
||||||
:class="iconClasses"
|
|
||||||
:style="[iconWrapStyle]"
|
|
||||||
>
|
|
||||||
<slot name="icon">
|
|
||||||
<uv-icon
|
|
||||||
class="uv-checkbox__icon-wrap__icon"
|
|
||||||
name="checkbox-mark"
|
|
||||||
:size="elIconSize"
|
|
||||||
:color="elIconColor"
|
|
||||||
/>
|
|
||||||
</slot>
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
class="uv-checkbox__label-wrap"
|
|
||||||
@tap.stop="labelClickHandler">
|
|
||||||
<slot>
|
|
||||||
<text
|
|
||||||
:style="{
|
|
||||||
color: elDisabled ? elInactiveColor : elLabelColor,
|
|
||||||
fontSize: elLabelSize,
|
|
||||||
lineHeight: elLabelSize
|
|
||||||
}"
|
|
||||||
>{{label}}</text>
|
|
||||||
</slot>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
|
||||||
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
|
||||||
import props from './props.js';
|
|
||||||
/**
|
|
||||||
* checkbox 复选框
|
|
||||||
* @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
|
|
||||||
* @tutorial https://www.uvui.cn/components/checkbox.html
|
|
||||||
* @property {String | Number | Boolean} name checkbox组件的标示符
|
|
||||||
* @property {String} shape 形状,square为方形,circle为圆型
|
|
||||||
* @property {String | Number} size 整体的大小
|
|
||||||
* @property {Boolean} checked 是否默认选中
|
|
||||||
* @property {String | Boolean} disabled 是否禁用
|
|
||||||
* @property {String} activeColor 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值
|
|
||||||
* @property {String} inactiveColor 未选中的颜色
|
|
||||||
* @property {String | Number} iconSize 图标的大小,单位px
|
|
||||||
* @property {String} iconColor 图标颜色
|
|
||||||
* @property {String | Number} label label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式
|
|
||||||
* @property {String} labelColor label的颜色
|
|
||||||
* @property {String | Number} labelSize label的字体大小,px单位
|
|
||||||
* @property {String | Boolean} labelDisabled 是否禁止点击提示语选中复选框
|
|
||||||
* @property {Object} customStyle 定义需要用到的外部样式
|
|
||||||
*
|
|
||||||
* @event {Function} change 任一个checkbox状态发生变化时触发,回调为一个对象
|
|
||||||
* @example <uv-checkbox v-model="checked" :disabled="false">天涯</uv-checkbox>
|
|
||||||
*/
|
|
||||||
export default {
|
|
||||||
name: "uv-checkbox",
|
|
||||||
mixins: [mpMixin, mixin, props],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isChecked: false,
|
|
||||||
// 父组件的默认值,因为头条小程序不支持在computed中使用this.parent.shape的形式
|
|
||||||
// 故只能使用如此方法
|
|
||||||
parentData: {
|
|
||||||
iconSize: 12,
|
|
||||||
labelDisabled: null,
|
|
||||||
disabled: null,
|
|
||||||
shape: 'square',
|
|
||||||
activeColor: null,
|
|
||||||
inactiveColor: null,
|
|
||||||
size: 18,
|
|
||||||
value: null,
|
|
||||||
modelValue: null,
|
|
||||||
iconColor: null,
|
|
||||||
placement: 'row',
|
|
||||||
borderBottom: false,
|
|
||||||
iconPlacement: 'left',
|
|
||||||
labelSize: 14,
|
|
||||||
labelColor: '#303133'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
// 是否禁用,如果父组件uv-raios-group禁用的话,将会忽略子组件的配置
|
|
||||||
elDisabled() {
|
|
||||||
return this.disabled !== '' ? this.disabled : this.parentData.disabled !== null ? this.parentData.disabled : false;
|
|
||||||
},
|
|
||||||
// 是否禁用label点击
|
|
||||||
elLabelDisabled() {
|
|
||||||
return this.labelDisabled !== '' ? this.labelDisabled : this.parentData.labelDisabled !== null ? this.parentData.labelDisabled :
|
|
||||||
false;
|
|
||||||
},
|
|
||||||
// 组件尺寸,对应size的值,默认值为21px
|
|
||||||
elSize() {
|
|
||||||
return this.size ? this.size : (this.parentData.size ? this.parentData.size : 21);
|
|
||||||
},
|
|
||||||
// 组件的勾选图标的尺寸,默认12px
|
|
||||||
elIconSize() {
|
|
||||||
return this.iconSize ? this.iconSize : (this.parentData.iconSize ? this.parentData.iconSize : 12);
|
|
||||||
},
|
|
||||||
// 组件选中激活时的颜色
|
|
||||||
elActiveColor() {
|
|
||||||
return this.activeColor ? this.activeColor : (this.parentData.activeColor ? this.parentData.activeColor : '#2979ff');
|
|
||||||
},
|
|
||||||
// 组件选未中激活时的颜色
|
|
||||||
elInactiveColor() {
|
|
||||||
return this.inactiveColor ? this.inactiveColor : (this.parentData.inactiveColor ? this.parentData.inactiveColor :
|
|
||||||
'#c8c9cc');
|
|
||||||
},
|
|
||||||
// label的颜色
|
|
||||||
elLabelColor() {
|
|
||||||
return this.labelColor ? this.labelColor : (this.parentData.labelColor ? this.parentData.labelColor : '#606266')
|
|
||||||
},
|
|
||||||
// 组件的形状
|
|
||||||
elShape() {
|
|
||||||
return this.shape ? this.shape : (this.parentData.shape ? this.parentData.shape : 'circle');
|
|
||||||
},
|
|
||||||
// label大小
|
|
||||||
elLabelSize() {
|
|
||||||
return this.$uv.addUnit(this.labelSize ? this.labelSize : (this.parentData.labelSize ? this.parentData.labelSize :
|
|
||||||
'15'))
|
|
||||||
},
|
|
||||||
elIconColor() {
|
|
||||||
const iconColor = this.iconColor ? this.iconColor : (this.parentData.iconColor ? this.parentData.iconColor :
|
|
||||||
'#ffffff');
|
|
||||||
// 图标的颜色
|
|
||||||
if (this.elDisabled) {
|
|
||||||
// disabled状态下,已勾选的checkbox图标改为elInactiveColor
|
|
||||||
return this.isChecked ? this.elInactiveColor : 'transparent'
|
|
||||||
} else {
|
|
||||||
return this.isChecked ? iconColor : 'transparent'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
iconClasses() {
|
|
||||||
let classes = []
|
|
||||||
// 组件的形状
|
|
||||||
classes.push('uv-checkbox__icon-wrap--' + this.elShape)
|
|
||||||
if (this.elDisabled) {
|
|
||||||
classes.push('uv-checkbox__icon-wrap--disabled')
|
|
||||||
}
|
|
||||||
if (this.isChecked && this.elDisabled) {
|
|
||||||
classes.push('uv-checkbox__icon-wrap--disabled--checked')
|
|
||||||
}
|
|
||||||
// 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效
|
|
||||||
// #ifdef MP-ALIPAY || MP-TOUTIAO
|
|
||||||
classes = classes.join(' ')
|
|
||||||
// #endif
|
|
||||||
return classes
|
|
||||||
},
|
|
||||||
iconWrapStyle() {
|
|
||||||
// checkbox的整体样式
|
|
||||||
const style = {}
|
|
||||||
style.backgroundColor = this.isChecked && !this.elDisabled ? this.elActiveColor : '#ffffff'
|
|
||||||
style.borderColor = this.isChecked && !this.elDisabled ? this.elActiveColor : this.elInactiveColor
|
|
||||||
style.width = this.$uv.addUnit(this.elSize)
|
|
||||||
style.height = this.$uv.addUnit(this.elSize)
|
|
||||||
// 如果是图标在右边的话,移除它的右边距
|
|
||||||
if (this.parentData.iconPlacement === 'right') {
|
|
||||||
style.marginRight = 0
|
|
||||||
}
|
|
||||||
return style
|
|
||||||
},
|
|
||||||
checkboxStyle() {
|
|
||||||
const style = {}
|
|
||||||
if (this.parentData.borderBottom && this.parentData.placement === 'row') {
|
|
||||||
this.$uv.error('检测到您将borderBottom设置为true,需要同时将uv-checkbox-group的placement设置为column才有效')
|
|
||||||
}
|
|
||||||
// 当父组件设置了显示下边框并且排列形式为纵向时,给内容和边框之间加上一定间隔
|
|
||||||
if (this.parentData.borderBottom && this.parentData.placement === 'column') {
|
|
||||||
style.paddingBottom = '8px'
|
|
||||||
}
|
|
||||||
return this.$uv.deepMerge(style, this.$uv.addStyle(this.customStyle))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.init()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
init() {
|
|
||||||
// 支付宝小程序不支持provide/inject,所以使用这个方法获取整个父组件,在created定义,避免循环引用
|
|
||||||
this.updateParentData()
|
|
||||||
if (!this.parent) {
|
|
||||||
this.$uv.error('uv-checkbox必须搭配uv-checkbox-group组件使用')
|
|
||||||
}
|
|
||||||
this.$nextTick(()=>{
|
|
||||||
let parentValue = [];
|
|
||||||
if(this.parentData.value.length) {
|
|
||||||
parentValue = this.parentData.value;
|
|
||||||
} else if (this.parentData.modelValue.length){
|
|
||||||
parentValue = this.parentData.modelValue;
|
|
||||||
}
|
|
||||||
// 设置初始化时,是否默认选中的状态,父组件uv-checkbox-group的value可能是array,所以额外判断
|
|
||||||
if (this.checked) {
|
|
||||||
this.isChecked = true
|
|
||||||
} else if (this.$uv.test.array(parentValue)) {
|
|
||||||
// 查找数组是是否存在this.name元素值
|
|
||||||
this.isChecked = parentValue.some(item => {
|
|
||||||
return item === this.name
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
updateParentData() {
|
|
||||||
this.getParentData('uv-checkbox-group')
|
|
||||||
},
|
|
||||||
// 横向两端排列时,点击组件即可触发选中事件
|
|
||||||
wrapperClickHandler(e) {
|
|
||||||
this.parentData.iconPlacement === 'right' && this.iconClickHandler(e)
|
|
||||||
},
|
|
||||||
// 点击图标
|
|
||||||
iconClickHandler(e) {
|
|
||||||
this.preventEvent(e)
|
|
||||||
// 如果整体被禁用,不允许被点击
|
|
||||||
if (!this.elDisabled) {
|
|
||||||
this.setRadioCheckedStatus()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 点击label
|
|
||||||
labelClickHandler(e) {
|
|
||||||
this.preventEvent(e)
|
|
||||||
// 如果按钮整体被禁用或者label被禁用,则不允许点击文字修改状态
|
|
||||||
if (!this.elLabelDisabled && !this.elDisabled) {
|
|
||||||
this.setRadioCheckedStatus()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
emitEvent() {
|
|
||||||
this.$emit('change', this.isChecked)
|
|
||||||
// 尝试调用uv-form的验证方法,进行一定延迟,否则微信小程序更新可能会不及时
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$uv.formValidate(this, 'change')
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 改变组件选中状态
|
|
||||||
// 这里的改变的依据是,更改本组件的checked值为true,同时通过父组件遍历所有uv-checkbox实例
|
|
||||||
// 将本组件外的其他uv-checkbox的checked都设置为false(都被取消选中状态),因而只剩下一个为选中状态
|
|
||||||
setRadioCheckedStatus() {
|
|
||||||
// 将本组件标记为与原来相反的状态
|
|
||||||
this.isChecked = !this.isChecked
|
|
||||||
this.emitEvent()
|
|
||||||
typeof this.parent.unCheckedOther === 'function' && this.parent.unCheckedOther(this)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch:{
|
|
||||||
checked(){
|
|
||||||
this.isChecked = this.checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
$show-border: 1;
|
|
||||||
$show-border-bottom: 1;
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/variable.scss';
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
|
|
||||||
$uv-checkbox-label-wrap-padding-right:6px !default;
|
|
||||||
$uv-checkbox-icon-wrap-font-size:6px !default;
|
|
||||||
$uv-checkbox-icon-wrap-border-width:1px !default;
|
|
||||||
$uv-checkbox-icon-wrap-border-color:#c8c9cc !default;
|
|
||||||
$uv-checkbox-icon-wrap-icon-line-height:0 !default;
|
|
||||||
$uv-checkbox-icon-wrap-circle-border-radius:100% !default;
|
|
||||||
$uv-checkbox-icon-wrap-square-border-radius:3px !default;
|
|
||||||
$uv-checkbox-icon-wrap-checked-color:#fff !default;
|
|
||||||
$uv-checkbox-icon-wrap-checked-background-color:red !default;
|
|
||||||
$uv-checkbox-icon-wrap-checked-border-color:#2979ff !default;
|
|
||||||
$uv-checkbox-icon-wrap-disabled-background-color:#ebedf0 !default;
|
|
||||||
$uv-checkbox-icon-wrap-disabled-checked-color:#c8c9cc !default;
|
|
||||||
$uv-checkbox-label-margin-left:5px !default;
|
|
||||||
$uv-checkbox-label-margin-right:12px !default;
|
|
||||||
$uv-checkbox-label-color:$uv-content-color !default;
|
|
||||||
$uv-checkbox-label-font-size:15px !default;
|
|
||||||
$uv-checkbox-label-disabled-color:#c8c9cc !default;
|
|
||||||
|
|
||||||
.uv-checkbox {
|
|
||||||
/* #ifndef APP-NVUE */
|
|
||||||
@include flex(row);
|
|
||||||
/* #endif */
|
|
||||||
overflow: hidden;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
&-label--left {
|
|
||||||
flex-direction: row
|
|
||||||
}
|
|
||||||
|
|
||||||
&-label--right {
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
justify-content: space-between
|
|
||||||
}
|
|
||||||
|
|
||||||
&__icon-wrap {
|
|
||||||
/* #ifndef APP-NVUE */
|
|
||||||
box-sizing: border-box;
|
|
||||||
// nvue下,border-color过渡有问题
|
|
||||||
transition-property: border-color, background-color, color;
|
|
||||||
transition-duration: 0.2s;
|
|
||||||
/* #endif */
|
|
||||||
color: $uv-content-color;
|
|
||||||
@include flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: transparent;
|
|
||||||
text-align: center;
|
|
||||||
font-size: $uv-checkbox-icon-wrap-font-size;
|
|
||||||
border-width: $uv-checkbox-icon-wrap-border-width;
|
|
||||||
border-color: $uv-checkbox-icon-wrap-border-color;
|
|
||||||
border-style: solid;
|
|
||||||
|
|
||||||
/* #ifdef MP-TOUTIAO */
|
|
||||||
// 头条小程序兼容性问题,需要设置行高为0,否则图标偏下
|
|
||||||
&__icon {
|
|
||||||
line-height: $uv-checkbox-icon-wrap-icon-line-height;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* #endif */
|
|
||||||
|
|
||||||
&--circle {
|
|
||||||
border-radius: $uv-checkbox-icon-wrap-circle-border-radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--square {
|
|
||||||
border-radius: $uv-checkbox-icon-wrap-square-border-radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--checked {
|
|
||||||
color: $uv-checkbox-icon-wrap-checked-color;
|
|
||||||
background-color: $uv-checkbox-icon-wrap-checked-background-color;
|
|
||||||
border-color: $uv-checkbox-icon-wrap-checked-border-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--disabled {
|
|
||||||
background-color: $uv-checkbox-icon-wrap-disabled-background-color !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--disabled--checked {
|
|
||||||
color: $uv-checkbox-icon-wrap-disabled-checked-color !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__label {
|
|
||||||
/* #ifndef APP-NVUE */
|
|
||||||
word-wrap: break-word;
|
|
||||||
/* #endif */
|
|
||||||
margin-left: $uv-checkbox-label-margin-left;
|
|
||||||
margin-right: $uv-checkbox-label-margin-right;
|
|
||||||
color: $uv-checkbox-label-color;
|
|
||||||
font-size: $uv-checkbox-label-font-size;
|
|
||||||
|
|
||||||
&--disabled {
|
|
||||||
color: $uv-checkbox-label-disabled-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__label-wrap {
|
|
||||||
padding-left: $uv-checkbox-label-wrap-padding-right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,88 +0,0 @@
|
|||||||
{
|
|
||||||
"id": "uv-checkbox",
|
|
||||||
"displayName": "uv-checkbox 复选框 全面兼容vue3+2、app、h5、小程序等多端",
|
|
||||||
"version": "1.0.13",
|
|
||||||
"description": "复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便。",
|
|
||||||
"keywords": [
|
|
||||||
"uv-checkbox",
|
|
||||||
"uvui",
|
|
||||||
"uv-ui",
|
|
||||||
"checkbox",
|
|
||||||
"复选框"
|
|
||||||
],
|
|
||||||
"repository": "",
|
|
||||||
"engines": {
|
|
||||||
"HBuilderX": "^3.1.0"
|
|
||||||
},
|
|
||||||
"dcloudext": {
|
|
||||||
"type": "component-vue",
|
|
||||||
"sale": {
|
|
||||||
"regular": {
|
|
||||||
"price": "0.00"
|
|
||||||
},
|
|
||||||
"sourcecode": {
|
|
||||||
"price": "0.00"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"contact": {
|
|
||||||
"qq": ""
|
|
||||||
},
|
|
||||||
"declaration": {
|
|
||||||
"ads": "无",
|
|
||||||
"data": "插件不采集任何数据",
|
|
||||||
"permissions": "无"
|
|
||||||
},
|
|
||||||
"npmurl": ""
|
|
||||||
},
|
|
||||||
"uni_modules": {
|
|
||||||
"dependencies": [
|
|
||||||
"uv-ui-tools",
|
|
||||||
"uv-icon"
|
|
||||||
],
|
|
||||||
"encrypt": [],
|
|
||||||
"platforms": {
|
|
||||||
"cloud": {
|
|
||||||
"tcb": "y",
|
|
||||||
"aliyun": "y"
|
|
||||||
},
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
## Checkbox 复选框
|
|
||||||
|
|
||||||
> **组件名:uv-checkbox**
|
|
||||||
|
|
||||||
复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便。可配合 `uv-form` 组件进行表单验证等场景使用。
|
|
||||||
|
|
||||||
# <a href="https://www.uvui.cn/components/checkbox.html" target="_blank">查看文档</a>
|
|
||||||
|
|
||||||
## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>(请不要 下载插件ZIP)</small>
|
|
||||||
|
|
||||||
### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
|
||||||
|
|
||||||
<a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank">
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
</a>
|
|
||||||
|
|
||||||
#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
|
@ -1,5 +0,0 @@
|
|||||||
## 1.0.1(2023-05-16)
|
|
||||||
1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
|
|
||||||
2. 优化部分功能
|
|
||||||
## 1.0.0(2023-05-10)
|
|
||||||
uv-no-network 无网络提示
|
|
File diff suppressed because one or more lines are too long
@ -1,222 +0,0 @@
|
|||||||
<template>
|
|
||||||
<uv-overlay
|
|
||||||
:show="!isConnected"
|
|
||||||
:zIndex="zIndex"
|
|
||||||
@touchmove.stop.prevent="noop"
|
|
||||||
:customStyle="{
|
|
||||||
backgroundColor: '#fff',
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'center',
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<view
|
|
||||||
class="uv-no-network"
|
|
||||||
>
|
|
||||||
<uv-icon
|
|
||||||
:name="image"
|
|
||||||
size="150"
|
|
||||||
imgMode="widthFit"
|
|
||||||
class="uv-no-network__error-icon"
|
|
||||||
></uv-icon>
|
|
||||||
<text class="uv-no-network__tips">{{tips}}</text>
|
|
||||||
<!-- 只有APP平台,才能跳转设置页,因为需要调用plus环境 -->
|
|
||||||
<!-- #ifdef APP-PLUS -->
|
|
||||||
<view class="uv-no-network__app">
|
|
||||||
<text class="uv-no-network__app__setting">请检查网络,或前往</text>
|
|
||||||
<text
|
|
||||||
class="uv-no-network__app__to-setting"
|
|
||||||
@tap="openSettings"
|
|
||||||
>设置</text>
|
|
||||||
</view>
|
|
||||||
<!-- #endif -->
|
|
||||||
<view class="uv-no-network__retry">
|
|
||||||
<uv-button
|
|
||||||
size="mini"
|
|
||||||
text="重试"
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
@click="retry"
|
|
||||||
></uv-button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</uv-overlay>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
|
||||||
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
|
||||||
import props from './props.js';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* noNetwork 无网络提示
|
|
||||||
* @description 该组件无需任何配置,引入即可,内部自动处理所有功能和事件。
|
|
||||||
* @tutorial https://www.uvui.cn/components/noNetwork.html
|
|
||||||
* @property {String} tips 没有网络时的提示语 (默认:'哎呀,网络信号丢失' )
|
|
||||||
* @property {String | Number} zIndex 组件的z-index值
|
|
||||||
* @property {String} image 无网络的图片提示,可用的src地址或base64图片
|
|
||||||
* @event {Function} retry 用户点击页面的"重试"按钮时触发
|
|
||||||
* @example <uv-no-network></uv-no-network>
|
|
||||||
*/
|
|
||||||
export default {
|
|
||||||
name: "uv-no-network",
|
|
||||||
mixins: [mpMixin, mixin, props],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isConnected: true, // 是否有网络连接
|
|
||||||
networkType: "none", // 网络类型
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.isIOS = (uni.getSystemInfoSync().platform === 'ios')
|
|
||||||
uni.onNetworkStatusChange((res) => {
|
|
||||||
this.isConnected = res.isConnected
|
|
||||||
this.networkType = res.networkType
|
|
||||||
this.emitEvent(this.networkType)
|
|
||||||
})
|
|
||||||
uni.getNetworkType({
|
|
||||||
success: (res) => {
|
|
||||||
this.networkType = res.networkType
|
|
||||||
this.emitEvent(this.networkType)
|
|
||||||
if (res.networkType == 'none') {
|
|
||||||
this.isConnected = false
|
|
||||||
} else {
|
|
||||||
this.isConnected = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
retry() {
|
|
||||||
// 重新检查网络
|
|
||||||
uni.getNetworkType({
|
|
||||||
success: (res) => {
|
|
||||||
this.networkType = res.networkType
|
|
||||||
this.emitEvent(this.networkType)
|
|
||||||
if (res.networkType == 'none') {
|
|
||||||
this.$uv.toast('无网络连接')
|
|
||||||
this.isConnected = false
|
|
||||||
} else {
|
|
||||||
this.$uv.toast('网络已连接')
|
|
||||||
this.isConnected = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.$emit('retry')
|
|
||||||
},
|
|
||||||
// 发出事件给父组件
|
|
||||||
emitEvent(networkType) {
|
|
||||||
this.$emit(networkType === 'none' ? 'disconnected' : 'connected')
|
|
||||||
},
|
|
||||||
async openSettings() {
|
|
||||||
if (this.networkType == "none") {
|
|
||||||
this.openSystemSettings()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
},
|
|
||||||
openAppSettings() {
|
|
||||||
this.gotoAppSetting()
|
|
||||||
},
|
|
||||||
openSystemSettings() {
|
|
||||||
// 以下方法来自5+范畴,如需深究,请自行查阅相关文档
|
|
||||||
// https://ask.dcloud.net.cn/docs/
|
|
||||||
if (this.isIOS) {
|
|
||||||
this.gotoiOSSetting()
|
|
||||||
} else {
|
|
||||||
this.gotoAndroidSetting()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
network() {
|
|
||||||
var result = null
|
|
||||||
var cellularData = plus.ios.newObject("CTCellularData")
|
|
||||||
var state = cellularData.plusGetAttribute("restrictedState")
|
|
||||||
if (state == 0) {
|
|
||||||
result = null
|
|
||||||
} else if (state == 2) {
|
|
||||||
result = 1
|
|
||||||
} else if (state == 1) {
|
|
||||||
result = 2
|
|
||||||
}
|
|
||||||
plus.ios.deleteObject(cellularData)
|
|
||||||
return result
|
|
||||||
},
|
|
||||||
gotoAppSetting() {
|
|
||||||
if (this.isIOS) {
|
|
||||||
var UIApplication = plus.ios.import("UIApplication")
|
|
||||||
var application2 = UIApplication.sharedApplication()
|
|
||||||
var NSURL2 = plus.ios.import("NSURL")
|
|
||||||
var setting2 = NSURL2.URLWithString("app-settings:")
|
|
||||||
application2.openURL(setting2)
|
|
||||||
plus.ios.deleteObject(setting2)
|
|
||||||
plus.ios.deleteObject(NSURL2)
|
|
||||||
plus.ios.deleteObject(application2)
|
|
||||||
} else {
|
|
||||||
var Intent = plus.android.importClass("android.content.Intent")
|
|
||||||
var Settings = plus.android.importClass("android.provider.Settings")
|
|
||||||
var Uri = plus.android.importClass("android.net.Uri")
|
|
||||||
var mainActivity = plus.android.runtimeMainActivity()
|
|
||||||
var intent = new Intent()
|
|
||||||
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
|
||||||
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null)
|
|
||||||
intent.setData(uri)
|
|
||||||
mainActivity.startActivity(intent)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
gotoiOSSetting() {
|
|
||||||
var UIApplication = plus.ios.import("UIApplication")
|
|
||||||
var application2 = UIApplication.sharedApplication()
|
|
||||||
var NSURL2 = plus.ios.import("NSURL")
|
|
||||||
var setting2 = NSURL2.URLWithString("App-prefs:root=General")
|
|
||||||
application2.openURL(setting2)
|
|
||||||
plus.ios.deleteObject(setting2)
|
|
||||||
plus.ios.deleteObject(NSURL2)
|
|
||||||
plus.ios.deleteObject(application2)
|
|
||||||
},
|
|
||||||
gotoAndroidSetting() {
|
|
||||||
var Intent = plus.android.importClass("android.content.Intent")
|
|
||||||
var Settings = plus.android.importClass("android.provider.Settings")
|
|
||||||
var mainActivity = plus.android.runtimeMainActivity()
|
|
||||||
var intent = new Intent(Settings.ACTION_SETTINGS)
|
|
||||||
mainActivity.startActivity(intent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
|
|
||||||
.uv-no-network {
|
|
||||||
@include flex(column);
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
margin-top: -100px;
|
|
||||||
|
|
||||||
&__tips {
|
|
||||||
color: $uv-tips-color;
|
|
||||||
font-size: 14px;
|
|
||||||
margin-top: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__app {
|
|
||||||
@include flex(row);
|
|
||||||
margin-top: 6px;
|
|
||||||
|
|
||||||
&__setting {
|
|
||||||
color: $uv-light-color;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__to-setting {
|
|
||||||
font-size: 13px;
|
|
||||||
color: $uv-primary;
|
|
||||||
margin-left: 3px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__retry {
|
|
||||||
@include flex(row);
|
|
||||||
justify-content: center;
|
|
||||||
margin-top: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,90 +0,0 @@
|
|||||||
{
|
|
||||||
"id": "uv-no-network",
|
|
||||||
"displayName": "uv-no-network 无网络提示 全面兼容小程序、nvue、vue2、vue3等多端",
|
|
||||||
"version": "1.0.1",
|
|
||||||
"description": "uv-no-network 该组件在没有任何网络的情况下,显示在内容上方,无需任何配置,引入即可,内部自动处理所有功能和事件。",
|
|
||||||
"keywords": [
|
|
||||||
"uv-no-network",
|
|
||||||
"uvui",
|
|
||||||
"uv-ui",
|
|
||||||
"network",
|
|
||||||
"无网络"
|
|
||||||
],
|
|
||||||
"repository": "",
|
|
||||||
"engines": {
|
|
||||||
"HBuilderX": "^3.1.0"
|
|
||||||
},
|
|
||||||
"dcloudext": {
|
|
||||||
"type": "component-vue",
|
|
||||||
"sale": {
|
|
||||||
"regular": {
|
|
||||||
"price": "0.00"
|
|
||||||
},
|
|
||||||
"sourcecode": {
|
|
||||||
"price": "0.00"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"contact": {
|
|
||||||
"qq": ""
|
|
||||||
},
|
|
||||||
"declaration": {
|
|
||||||
"ads": "无",
|
|
||||||
"data": "插件不采集任何数据",
|
|
||||||
"permissions": "无"
|
|
||||||
},
|
|
||||||
"npmurl": ""
|
|
||||||
},
|
|
||||||
"uni_modules": {
|
|
||||||
"dependencies": [
|
|
||||||
"uv-ui-tools",
|
|
||||||
"uv-overlay",
|
|
||||||
"uv-icon",
|
|
||||||
"uv-button"
|
|
||||||
],
|
|
||||||
"encrypt": [],
|
|
||||||
"platforms": {
|
|
||||||
"cloud": {
|
|
||||||
"tcb": "y",
|
|
||||||
"aliyun": "y"
|
|
||||||
},
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
## NoNetwork 无网络提示
|
|
||||||
|
|
||||||
> **组件名:uv-no-network**
|
|
||||||
|
|
||||||
该组件在没有任何网络的情况下,显示在内容上方,无需任何配置,引入即可,内部自动处理所有功能和事件。
|
|
||||||
|
|
||||||
### <a href="https://www.uvui.cn/components/noNetwork.html" target="_blank">查看文档</a>
|
|
||||||
|
|
||||||
### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
|
||||||
|
|
||||||
#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
|
@ -1,11 +0,0 @@
|
|||||||
## 1.0.4(2023-07-17)
|
|
||||||
1. 优化文档
|
|
||||||
2. 优化其他
|
|
||||||
## 1.0.3(2023-06-26)
|
|
||||||
1. H5增加属性h5SaveTip 保存二维码时候是否显示提示
|
|
||||||
## 1.0.2(2023-06-01)
|
|
||||||
1. 修复点击触发两次事件的BUG
|
|
||||||
## 1.0.1(2023-05-23)
|
|
||||||
1. 修复在部分平台不显示加载效果的BUG
|
|
||||||
## 1.0.0(2023-05-17)
|
|
||||||
1. 新增uv-qrcode组件
|
|
@ -1 +0,0 @@
|
|||||||
export const cacheImageList = [];
|
|
@ -1,241 +0,0 @@
|
|||||||
const isWeex = typeof WXEnvironment !== 'undefined';
|
|
||||||
const isWeexIOS = isWeex && /ios/i.test(WXEnvironment.platform);
|
|
||||||
const isWeexAndroid = isWeex && !isWeexIOS;
|
|
||||||
|
|
||||||
import GLmethod from '../context-webgl/GLmethod';
|
|
||||||
|
|
||||||
const GCanvasModule =
|
|
||||||
(typeof weex !== 'undefined' && weex.requireModule) ? (weex.requireModule('gcanvas')) :
|
|
||||||
(typeof __weex_require__ !== 'undefined') ? (__weex_require__('@weex-module/gcanvas')) : {};
|
|
||||||
|
|
||||||
let isDebugging = false;
|
|
||||||
|
|
||||||
let isComboDisabled = false;
|
|
||||||
|
|
||||||
const logCommand = (function () {
|
|
||||||
const methodQuery = [];
|
|
||||||
Object.keys(GLmethod).forEach(key => {
|
|
||||||
methodQuery[GLmethod[key]] = key;
|
|
||||||
})
|
|
||||||
const queryMethod = (id) => {
|
|
||||||
return methodQuery[parseInt(id)] || 'NotFoundMethod';
|
|
||||||
}
|
|
||||||
const logCommand = (id, cmds) => {
|
|
||||||
const mId = cmds.split(',')[0];
|
|
||||||
const mName = queryMethod(mId);
|
|
||||||
console.log(`=== callNative - componentId:${id}; method: ${mName}; cmds: ${cmds}`);
|
|
||||||
}
|
|
||||||
return logCommand;
|
|
||||||
})();
|
|
||||||
|
|
||||||
function joinArray(arr, sep) {
|
|
||||||
let res = '';
|
|
||||||
for (let i = 0; i < arr.length; i++) {
|
|
||||||
if (i !== 0) {
|
|
||||||
res += sep;
|
|
||||||
}
|
|
||||||
res += arr[i];
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
const commandsCache = {}
|
|
||||||
|
|
||||||
const GBridge = {
|
|
||||||
|
|
||||||
callEnable: (ref, configArray) => {
|
|
||||||
|
|
||||||
commandsCache[ref] = [];
|
|
||||||
|
|
||||||
return GCanvasModule.enable({
|
|
||||||
componentId: ref,
|
|
||||||
config: configArray
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
callEnableDebug: () => {
|
|
||||||
isDebugging = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
callEnableDisableCombo: () => {
|
|
||||||
isComboDisabled = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
callSetContextType: function (componentId, context_type) {
|
|
||||||
GCanvasModule.setContextType(context_type, componentId);
|
|
||||||
},
|
|
||||||
|
|
||||||
callReset: function(id){
|
|
||||||
GCanvasModule.resetComponent && canvasModule.resetComponent(componentId);
|
|
||||||
},
|
|
||||||
|
|
||||||
render: isWeexIOS ? function (componentId) {
|
|
||||||
return GCanvasModule.extendCallNative({
|
|
||||||
contextId: componentId,
|
|
||||||
type: 0x60000001
|
|
||||||
});
|
|
||||||
} : function (componentId) {
|
|
||||||
return callGCanvasLinkNative(componentId, 0x60000001, 'render');
|
|
||||||
},
|
|
||||||
|
|
||||||
render2d: isWeexIOS ? function (componentId, commands, callback) {
|
|
||||||
|
|
||||||
if (isDebugging) {
|
|
||||||
console.log('>>> >>> render2d ===');
|
|
||||||
console.log('>>> commands: ' + commands);
|
|
||||||
}
|
|
||||||
|
|
||||||
GCanvasModule.render([commands, callback?true:false], componentId, callback);
|
|
||||||
|
|
||||||
} : function (componentId, commands,callback) {
|
|
||||||
|
|
||||||
if (isDebugging) {
|
|
||||||
console.log('>>> >>> render2d ===');
|
|
||||||
console.log('>>> commands: ' + commands);
|
|
||||||
}
|
|
||||||
|
|
||||||
callGCanvasLinkNative(componentId, 0x20000001, commands);
|
|
||||||
if(callback){
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
callExtendCallNative: isWeexIOS ? function (componentId, cmdArgs) {
|
|
||||||
|
|
||||||
throw 'should not be here anymore ' + cmdArgs;
|
|
||||||
|
|
||||||
} : function (componentId, cmdArgs) {
|
|
||||||
|
|
||||||
throw 'should not be here anymore ' + cmdArgs;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
flushNative: isWeexIOS ? function (componentId) {
|
|
||||||
|
|
||||||
const cmdArgs = joinArray(commandsCache[componentId], ';');
|
|
||||||
commandsCache[componentId] = [];
|
|
||||||
|
|
||||||
if (isDebugging) {
|
|
||||||
console.log('>>> >>> flush native ===');
|
|
||||||
console.log('>>> commands: ' + cmdArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = GCanvasModule.extendCallNative({
|
|
||||||
"contextId": componentId,
|
|
||||||
"type": 0x60000000,
|
|
||||||
"args": cmdArgs
|
|
||||||
});
|
|
||||||
|
|
||||||
const res = result && result.result;
|
|
||||||
|
|
||||||
if (isDebugging) {
|
|
||||||
console.log('>>> result: ' + res);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
} : function (componentId) {
|
|
||||||
|
|
||||||
const cmdArgs = joinArray(commandsCache[componentId], ';');
|
|
||||||
commandsCache[componentId] = [];
|
|
||||||
|
|
||||||
if (isDebugging) {
|
|
||||||
console.log('>>> >>> flush native ===');
|
|
||||||
console.log('>>> commands: ' + cmdArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = callGCanvasLinkNative(componentId, 0x60000000, cmdArgs);
|
|
||||||
|
|
||||||
if (isDebugging) {
|
|
||||||
console.log('>>> result: ' + result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
callNative: function (componentId, cmdArgs, cache) {
|
|
||||||
|
|
||||||
if (isDebugging) {
|
|
||||||
logCommand(componentId, cmdArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
commandsCache[componentId].push(cmdArgs);
|
|
||||||
|
|
||||||
if (!cache || isComboDisabled) {
|
|
||||||
return GBridge.flushNative(componentId);
|
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
texImage2D(componentId, ...args) {
|
|
||||||
if (isWeexIOS) {
|
|
||||||
if (args.length === 6) {
|
|
||||||
const [target, level, internalformat, format, type, image] = args;
|
|
||||||
GBridge.callNative(
|
|
||||||
componentId,
|
|
||||||
GLmethod.texImage2D + ',' + 6 + ',' + target + ',' + level + ',' + internalformat + ',' + format + ',' + type + ',' + image.src
|
|
||||||
)
|
|
||||||
} else if (args.length === 9) {
|
|
||||||
const [target, level, internalformat, width, height, border, format, type, image] = args;
|
|
||||||
GBridge.callNative(
|
|
||||||
componentId,
|
|
||||||
GLmethod.texImage2D + ',' + 9 + ',' + target + ',' + level + ',' + internalformat + ',' + width + ',' + height + ',' + border + ',' +
|
|
||||||
+ format + ',' + type + ',' + (image ? image.src : 0)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (isWeexAndroid) {
|
|
||||||
if (args.length === 6) {
|
|
||||||
const [target, level, internalformat, format, type, image] = args;
|
|
||||||
GCanvasModule.texImage2D(componentId, target, level, internalformat, format, type, image.src);
|
|
||||||
} else if (args.length === 9) {
|
|
||||||
const [target, level, internalformat, width, height, border, format, type, image] = args;
|
|
||||||
GCanvasModule.texImage2D(componentId, target, level, internalformat, width, height, border, format, type, (image ? image.src : 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image) {
|
|
||||||
if (isWeexIOS) {
|
|
||||||
if (arguments.length === 8) {
|
|
||||||
GBridge.callNative(
|
|
||||||
componentId,
|
|
||||||
GLmethod.texSubImage2D + ',' + 6 + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset, + ',' + format + ',' + type + ',' + image.src
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (isWeexAndroid) {
|
|
||||||
GCanvasModule.texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image.src);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
bindImageTexture(componentId, src, imageId) {
|
|
||||||
GCanvasModule.bindImageTexture([src, imageId], componentId);
|
|
||||||
},
|
|
||||||
|
|
||||||
perloadImage([url, id], callback) {
|
|
||||||
GCanvasModule.preLoadImage([url, id], function (image) {
|
|
||||||
image.url = url;
|
|
||||||
image.id = id;
|
|
||||||
callback(image);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
measureText(text, fontStyle, componentId) {
|
|
||||||
return GCanvasModule.measureText([text, fontStyle], componentId);
|
|
||||||
},
|
|
||||||
|
|
||||||
getImageData (componentId, x, y, w, h, callback) {
|
|
||||||
GCanvasModule.getImageData([x, y,w,h],componentId,callback);
|
|
||||||
},
|
|
||||||
|
|
||||||
putImageData (componentId, data, x, y, w, h, callback) {
|
|
||||||
GCanvasModule.putImageData([x, y,w,h,data],componentId,callback);
|
|
||||||
},
|
|
||||||
|
|
||||||
toTempFilePath(componentId, x, y, width, height, destWidth, destHeight, fileType, quality, callback){
|
|
||||||
GCanvasModule.toTempFilePath([x, y, width,height, destWidth, destHeight, fileType, quality], componentId, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default GBridge;
|
|
@ -1,18 +0,0 @@
|
|||||||
class FillStyleLinearGradient {
|
|
||||||
|
|
||||||
constructor(x0, y0, x1, y1) {
|
|
||||||
this._start_pos = { _x: x0, _y: y0 };
|
|
||||||
this._end_pos = { _x: x1, _y: y1 };
|
|
||||||
this._stop_count = 0;
|
|
||||||
this._stops = [0, 0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
|
|
||||||
addColorStop = function (pos, color) {
|
|
||||||
if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) {
|
|
||||||
this._stops[this._stop_count] = { _pos: pos, _color: color };
|
|
||||||
this._stop_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default FillStyleLinearGradient;
|
|
@ -1,8 +0,0 @@
|
|||||||
class FillStylePattern {
|
|
||||||
constructor(img, pattern) {
|
|
||||||
this._style = pattern;
|
|
||||||
this._img = img;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default FillStylePattern;
|
|
@ -1,17 +0,0 @@
|
|||||||
class FillStyleRadialGradient {
|
|
||||||
constructor(x0, y0, r0, x1, y1, r1) {
|
|
||||||
this._start_pos = { _x: x0, _y: y0, _r: r0 };
|
|
||||||
this._end_pos = { _x: x1, _y: y1, _r: r1 };
|
|
||||||
this._stop_count = 0;
|
|
||||||
this._stops = [0, 0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
|
|
||||||
addColorStop(pos, color) {
|
|
||||||
if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) {
|
|
||||||
this._stops[this._stop_count] = { _pos: pos, _color: color };
|
|
||||||
this._stop_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default FillStyleRadialGradient;
|
|
@ -1,666 +0,0 @@
|
|||||||
import FillStylePattern from './FillStylePattern';
|
|
||||||
import FillStyleLinearGradient from './FillStyleLinearGradient';
|
|
||||||
import FillStyleRadialGradient from './FillStyleRadialGradient';
|
|
||||||
import GImage from '../env/image.js';
|
|
||||||
import {
|
|
||||||
ArrayBufferToBase64,
|
|
||||||
Base64ToUint8ClampedArray
|
|
||||||
} from '../env/tool.js';
|
|
||||||
|
|
||||||
export default class CanvasRenderingContext2D {
|
|
||||||
|
|
||||||
_drawCommands = '';
|
|
||||||
|
|
||||||
_globalAlpha = 1.0;
|
|
||||||
|
|
||||||
_fillStyle = 'rgb(0,0,0)';
|
|
||||||
_strokeStyle = 'rgb(0,0,0)';
|
|
||||||
|
|
||||||
_lineWidth = 1;
|
|
||||||
_lineCap = 'butt';
|
|
||||||
_lineJoin = 'miter';
|
|
||||||
|
|
||||||
_miterLimit = 10;
|
|
||||||
|
|
||||||
_globalCompositeOperation = 'source-over';
|
|
||||||
|
|
||||||
_textAlign = 'start';
|
|
||||||
_textBaseline = 'alphabetic';
|
|
||||||
|
|
||||||
_font = '10px sans-serif';
|
|
||||||
|
|
||||||
_savedGlobalAlpha = [];
|
|
||||||
|
|
||||||
timer = null;
|
|
||||||
componentId = null;
|
|
||||||
|
|
||||||
_notCommitDrawImageCache = [];
|
|
||||||
_needRedrawImageCache = [];
|
|
||||||
_redrawCommands = '';
|
|
||||||
_autoSaveContext = true;
|
|
||||||
// _imageMap = new GHashMap();
|
|
||||||
// _textureMap = new GHashMap();
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.className = 'CanvasRenderingContext2D';
|
|
||||||
//this.save()
|
|
||||||
}
|
|
||||||
|
|
||||||
setFillStyle(value) {
|
|
||||||
this.fillStyle = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
set fillStyle(value) {
|
|
||||||
this._fillStyle = value;
|
|
||||||
|
|
||||||
if (typeof(value) == 'string') {
|
|
||||||
this._drawCommands = this._drawCommands.concat("F" + value + ";");
|
|
||||||
} else if (value instanceof FillStylePattern) {
|
|
||||||
const image = value._img;
|
|
||||||
if (!image.complete) {
|
|
||||||
image.onload = () => {
|
|
||||||
var index = this._needRedrawImageCache.indexOf(image);
|
|
||||||
if (index > -1) {
|
|
||||||
this._needRedrawImageCache.splice(index, 1);
|
|
||||||
CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
|
|
||||||
this._redrawflush(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._notCommitDrawImageCache.push(image);
|
|
||||||
} else {
|
|
||||||
CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
|
|
||||||
this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";");
|
|
||||||
} else if (value instanceof FillStyleLinearGradient) {
|
|
||||||
var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," +
|
|
||||||
value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," +
|
|
||||||
value._stop_count;
|
|
||||||
for (var i = 0; i < value._stop_count; ++i) {
|
|
||||||
command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
|
|
||||||
}
|
|
||||||
this._drawCommands = this._drawCommands.concat(command + ";");
|
|
||||||
} else if (value instanceof FillStyleRadialGradient) {
|
|
||||||
var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r
|
|
||||||
.toFixed(2) + "," +
|
|
||||||
value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," + value._end_pos._r.toFixed(2) + "," +
|
|
||||||
value._stop_count;
|
|
||||||
for (var i = 0; i < value._stop_count; ++i) {
|
|
||||||
command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
|
|
||||||
}
|
|
||||||
this._drawCommands = this._drawCommands.concat(command + ";");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get fillStyle() {
|
|
||||||
return this._fillStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
get globalAlpha() {
|
|
||||||
return this._globalAlpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
setGlobalAlpha(value) {
|
|
||||||
this.globalAlpha = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
set globalAlpha(value) {
|
|
||||||
this._globalAlpha = value;
|
|
||||||
this._drawCommands = this._drawCommands.concat("a" + value.toFixed(2) + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
get strokeStyle() {
|
|
||||||
return this._strokeStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
setStrokeStyle(value) {
|
|
||||||
this.strokeStyle = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
set strokeStyle(value) {
|
|
||||||
|
|
||||||
this._strokeStyle = value;
|
|
||||||
|
|
||||||
if (typeof(value) == 'string') {
|
|
||||||
this._drawCommands = this._drawCommands.concat("S" + value + ";");
|
|
||||||
} else if (value instanceof FillStylePattern) {
|
|
||||||
CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
|
|
||||||
this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";");
|
|
||||||
} else if (value instanceof FillStyleLinearGradient) {
|
|
||||||
var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," +
|
|
||||||
value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," +
|
|
||||||
value._stop_count;
|
|
||||||
|
|
||||||
for (var i = 0; i < value._stop_count; ++i) {
|
|
||||||
command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
|
|
||||||
}
|
|
||||||
this._drawCommands = this._drawCommands.concat(command + ";");
|
|
||||||
} else if (value instanceof FillStyleRadialGradient) {
|
|
||||||
var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r
|
|
||||||
.toFixed(2) + "," +
|
|
||||||
value._end_pos._x.toFixed(2) + "," + value._end_pos._y + ",".toFixed(2) + value._end_pos._r.toFixed(2) + "," +
|
|
||||||
value._stop_count;
|
|
||||||
|
|
||||||
for (var i = 0; i < value._stop_count; ++i) {
|
|
||||||
command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
|
|
||||||
}
|
|
||||||
this._drawCommands = this._drawCommands.concat(command + ";");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get lineWidth() {
|
|
||||||
return this._lineWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
setLineWidth(value) {
|
|
||||||
this.lineWidth = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
set lineWidth(value) {
|
|
||||||
this._lineWidth = value;
|
|
||||||
this._drawCommands = this._drawCommands.concat("W" + value + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
get lineCap() {
|
|
||||||
return this._lineCap;
|
|
||||||
}
|
|
||||||
|
|
||||||
setLineCap(value) {
|
|
||||||
this.lineCap = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
set lineCap(value) {
|
|
||||||
this._lineCap = value;
|
|
||||||
this._drawCommands = this._drawCommands.concat("C" + value + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
get lineJoin() {
|
|
||||||
return this._lineJoin;
|
|
||||||
}
|
|
||||||
|
|
||||||
setLineJoin(value) {
|
|
||||||
this.lineJoin = value
|
|
||||||
}
|
|
||||||
|
|
||||||
set lineJoin(value) {
|
|
||||||
this._lineJoin = value;
|
|
||||||
this._drawCommands = this._drawCommands.concat("J" + value + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
get miterLimit() {
|
|
||||||
return this._miterLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
setMiterLimit(value) {
|
|
||||||
this.miterLimit = value
|
|
||||||
}
|
|
||||||
|
|
||||||
set miterLimit(value) {
|
|
||||||
this._miterLimit = value;
|
|
||||||
this._drawCommands = this._drawCommands.concat("M" + value + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
get globalCompositeOperation() {
|
|
||||||
return this._globalCompositeOperation;
|
|
||||||
}
|
|
||||||
|
|
||||||
set globalCompositeOperation(value) {
|
|
||||||
|
|
||||||
this._globalCompositeOperation = value;
|
|
||||||
let mode = 0;
|
|
||||||
switch (value) {
|
|
||||||
case "source-over":
|
|
||||||
mode = 0;
|
|
||||||
break;
|
|
||||||
case "source-atop":
|
|
||||||
mode = 5;
|
|
||||||
break;
|
|
||||||
case "source-in":
|
|
||||||
mode = 0;
|
|
||||||
break;
|
|
||||||
case "source-out":
|
|
||||||
mode = 2;
|
|
||||||
break;
|
|
||||||
case "destination-over":
|
|
||||||
mode = 4;
|
|
||||||
break;
|
|
||||||
case "destination-atop":
|
|
||||||
mode = 4;
|
|
||||||
break;
|
|
||||||
case "destination-in":
|
|
||||||
mode = 4;
|
|
||||||
break;
|
|
||||||
case "destination-out":
|
|
||||||
mode = 3;
|
|
||||||
break;
|
|
||||||
case "lighter":
|
|
||||||
mode = 1;
|
|
||||||
break;
|
|
||||||
case "copy":
|
|
||||||
mode = 2;
|
|
||||||
break;
|
|
||||||
case "xor":
|
|
||||||
mode = 6;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._drawCommands = this._drawCommands.concat("B" + mode + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
get textAlign() {
|
|
||||||
return this._textAlign;
|
|
||||||
}
|
|
||||||
|
|
||||||
setTextAlign(value) {
|
|
||||||
this.textAlign = value
|
|
||||||
}
|
|
||||||
|
|
||||||
set textAlign(value) {
|
|
||||||
|
|
||||||
this._textAlign = value;
|
|
||||||
let Align = 0;
|
|
||||||
switch (value) {
|
|
||||||
case "start":
|
|
||||||
Align = 0;
|
|
||||||
break;
|
|
||||||
case "end":
|
|
||||||
Align = 1;
|
|
||||||
break;
|
|
||||||
case "left":
|
|
||||||
Align = 2;
|
|
||||||
break;
|
|
||||||
case "center":
|
|
||||||
Align = 3;
|
|
||||||
break;
|
|
||||||
case "right":
|
|
||||||
Align = 4;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Align = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._drawCommands = this._drawCommands.concat("A" + Align + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
get textBaseline() {
|
|
||||||
return this._textBaseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
setTextBaseline(value) {
|
|
||||||
this.textBaseline = value
|
|
||||||
}
|
|
||||||
|
|
||||||
set textBaseline(value) {
|
|
||||||
this._textBaseline = value;
|
|
||||||
let baseline = 0;
|
|
||||||
switch (value) {
|
|
||||||
case "alphabetic":
|
|
||||||
baseline = 0;
|
|
||||||
break;
|
|
||||||
case "middle":
|
|
||||||
baseline = 1;
|
|
||||||
break;
|
|
||||||
case "top":
|
|
||||||
baseline = 2;
|
|
||||||
break;
|
|
||||||
case "hanging":
|
|
||||||
baseline = 3;
|
|
||||||
break;
|
|
||||||
case "bottom":
|
|
||||||
baseline = 4;
|
|
||||||
break;
|
|
||||||
case "ideographic":
|
|
||||||
baseline = 5;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
baseline = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._drawCommands = this._drawCommands.concat("E" + baseline + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
get font() {
|
|
||||||
return this._font;
|
|
||||||
}
|
|
||||||
|
|
||||||
setFontSize(size) {
|
|
||||||
var str = this._font;
|
|
||||||
var strs = str.trim().split(/\s+/);
|
|
||||||
for (var i = 0; i < strs.length; i++) {
|
|
||||||
var values = ["normal", "italic", "oblique", "normal", "small-caps", "normal", "bold",
|
|
||||||
"bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900",
|
|
||||||
"normal", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed",
|
|
||||||
"semi-expanded", "expanded", "extra-expanded", "ultra-expanded"
|
|
||||||
];
|
|
||||||
|
|
||||||
if (-1 == values.indexOf(strs[i].trim())) {
|
|
||||||
if (typeof size === 'string') {
|
|
||||||
strs[i] = size;
|
|
||||||
} else if (typeof size === 'number') {
|
|
||||||
strs[i] = String(size) + 'px';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.font = strs.join(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
set font(value) {
|
|
||||||
this._font = value;
|
|
||||||
this._drawCommands = this._drawCommands.concat("j" + value + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
setTransform(a, b, c, d, tx, ty) {
|
|
||||||
this._drawCommands = this._drawCommands.concat("t" +
|
|
||||||
(a === 1 ? "1" : a.toFixed(2)) + "," +
|
|
||||||
(b === 0 ? "0" : b.toFixed(2)) + "," +
|
|
||||||
(c === 0 ? "0" : c.toFixed(2)) + "," +
|
|
||||||
(d === 1 ? "1" : d.toFixed(2)) + "," + tx.toFixed(2) + "," + ty.toFixed(2) + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
transform(a, b, c, d, tx, ty) {
|
|
||||||
this._drawCommands = this._drawCommands.concat("f" +
|
|
||||||
(a === 1 ? "1" : a.toFixed(2)) + "," +
|
|
||||||
(b === 0 ? "0" : b.toFixed(2)) + "," +
|
|
||||||
(c === 0 ? "0" : c.toFixed(2)) + "," +
|
|
||||||
(d === 1 ? "1" : d.toFixed(2)) + "," + tx + "," + ty + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
resetTransform() {
|
|
||||||
this._drawCommands = this._drawCommands.concat("m;");
|
|
||||||
}
|
|
||||||
|
|
||||||
scale(a, d) {
|
|
||||||
this._drawCommands = this._drawCommands.concat("k" + a.toFixed(2) + "," +
|
|
||||||
d.toFixed(2) + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
rotate(angle) {
|
|
||||||
this._drawCommands = this._drawCommands
|
|
||||||
.concat("r" + angle.toFixed(6) + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
translate(tx, ty) {
|
|
||||||
this._drawCommands = this._drawCommands.concat("l" + tx.toFixed(2) + "," + ty.toFixed(2) + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
save() {
|
|
||||||
this._savedGlobalAlpha.push(this._globalAlpha);
|
|
||||||
this._drawCommands = this._drawCommands.concat("v;");
|
|
||||||
}
|
|
||||||
|
|
||||||
restore() {
|
|
||||||
this._drawCommands = this._drawCommands.concat("e;");
|
|
||||||
this._globalAlpha = this._savedGlobalAlpha.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
createPattern(img, pattern) {
|
|
||||||
if (typeof img === 'string') {
|
|
||||||
var imgObj = new GImage();
|
|
||||||
imgObj.src = img;
|
|
||||||
img = imgObj;
|
|
||||||
}
|
|
||||||
return new FillStylePattern(img, pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
createLinearGradient(x0, y0, x1, y1) {
|
|
||||||
return new FillStyleLinearGradient(x0, y0, x1, y1);
|
|
||||||
}
|
|
||||||
|
|
||||||
createRadialGradient = function(x0, y0, r0, x1, y1, r1) {
|
|
||||||
return new FillStyleRadialGradient(x0, y0, r0, x1, y1, r1);
|
|
||||||
};
|
|
||||||
|
|
||||||
createCircularGradient = function(x0, y0, r0) {
|
|
||||||
return new FillStyleRadialGradient(x0, y0, 0, x0, y0, r0);
|
|
||||||
};
|
|
||||||
|
|
||||||
strokeRect(x, y, w, h) {
|
|
||||||
this._drawCommands = this._drawCommands.concat("s" + x + "," + y + "," + w + "," + h + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
clearRect(x, y, w, h) {
|
|
||||||
this._drawCommands = this._drawCommands.concat("c" + x + "," + y + "," + w +
|
|
||||||
"," + h + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
clip() {
|
|
||||||
this._drawCommands = this._drawCommands.concat("p;");
|
|
||||||
}
|
|
||||||
|
|
||||||
resetClip() {
|
|
||||||
this._drawCommands = this._drawCommands.concat("q;");
|
|
||||||
}
|
|
||||||
|
|
||||||
closePath() {
|
|
||||||
this._drawCommands = this._drawCommands.concat("o;");
|
|
||||||
}
|
|
||||||
|
|
||||||
moveTo(x, y) {
|
|
||||||
this._drawCommands = this._drawCommands.concat("g" + x.toFixed(2) + "," + y.toFixed(2) + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
lineTo(x, y) {
|
|
||||||
this._drawCommands = this._drawCommands.concat("i" + x.toFixed(2) + "," + y.toFixed(2) + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
quadraticCurveTo = function(cpx, cpy, x, y) {
|
|
||||||
this._drawCommands = this._drawCommands.concat("u" + cpx + "," + cpy + "," + x + "," + y + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, ) {
|
|
||||||
this._drawCommands = this._drawCommands.concat(
|
|
||||||
"z" + cp1x.toFixed(2) + "," + cp1y.toFixed(2) + "," + cp2x.toFixed(2) + "," + cp2y.toFixed(2) + "," +
|
|
||||||
x.toFixed(2) + "," + y.toFixed(2) + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
arcTo(x1, y1, x2, y2, radius) {
|
|
||||||
this._drawCommands = this._drawCommands.concat("h" + x1 + "," + y1 + "," + x2 + "," + y2 + "," + radius + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
beginPath() {
|
|
||||||
this._drawCommands = this._drawCommands.concat("b;");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fillRect(x, y, w, h) {
|
|
||||||
this._drawCommands = this._drawCommands.concat("n" + x + "," + y + "," + w +
|
|
||||||
"," + h + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
rect(x, y, w, h) {
|
|
||||||
this._drawCommands = this._drawCommands.concat("w" + x + "," + y + "," + w + "," + h + ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
fill() {
|
|
||||||
this._drawCommands = this._drawCommands.concat("L;");
|
|
||||||
}
|
|
||||||
|
|
||||||
stroke(path) {
|
|
||||||
this._drawCommands = this._drawCommands.concat("x;");
|
|
||||||
}
|
|
||||||
|
|
||||||
arc(x, y, radius, startAngle, endAngle, anticlockwise) {
|
|
||||||
|
|
||||||
let ianticlockwise = 0;
|
|
||||||
if (anticlockwise) {
|
|
||||||
ianticlockwise = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._drawCommands = this._drawCommands.concat(
|
|
||||||
"y" + x.toFixed(2) + "," + y.toFixed(2) + "," +
|
|
||||||
radius.toFixed(2) + "," + startAngle + "," + endAngle + "," + ianticlockwise +
|
|
||||||
";"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fillText(text, x, y) {
|
|
||||||
let tmptext = text.replace(/!/g, "!!");
|
|
||||||
tmptext = tmptext.replace(/,/g, "!,");
|
|
||||||
tmptext = tmptext.replace(/;/g, "!;");
|
|
||||||
this._drawCommands = this._drawCommands.concat("T" + tmptext + "," + x + "," + y + ",0.0;");
|
|
||||||
}
|
|
||||||
|
|
||||||
strokeText = function(text, x, y) {
|
|
||||||
let tmptext = text.replace(/!/g, "!!");
|
|
||||||
tmptext = tmptext.replace(/,/g, "!,");
|
|
||||||
tmptext = tmptext.replace(/;/g, "!;");
|
|
||||||
this._drawCommands = this._drawCommands.concat("U" + tmptext + "," + x + "," + y + ",0.0;");
|
|
||||||
}
|
|
||||||
|
|
||||||
measureText(text) {
|
|
||||||
return CanvasRenderingContext2D.GBridge.measureText(text, this.font, this.componentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
isPointInPath = function(x, y) {
|
|
||||||
throw new Error('GCanvas not supported yet');
|
|
||||||
}
|
|
||||||
|
|
||||||
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {
|
|
||||||
if (typeof image === 'string') {
|
|
||||||
var imgObj = new GImage();
|
|
||||||
imgObj.src = image;
|
|
||||||
image = imgObj;
|
|
||||||
}
|
|
||||||
if (image instanceof GImage) {
|
|
||||||
if (!image.complete) {
|
|
||||||
imgObj.onload = () => {
|
|
||||||
var index = this._needRedrawImageCache.indexOf(image);
|
|
||||||
if (index > -1) {
|
|
||||||
this._needRedrawImageCache.splice(index, 1);
|
|
||||||
CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
|
|
||||||
this._redrawflush(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._notCommitDrawImageCache.push(image);
|
|
||||||
} else {
|
|
||||||
CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
|
|
||||||
}
|
|
||||||
var srcArgs = [image, sx, sy, sw, sh, dx, dy, dw, dh];
|
|
||||||
var args = [];
|
|
||||||
for (var arg in srcArgs) {
|
|
||||||
if (typeof(srcArgs[arg]) != 'undefined') {
|
|
||||||
args.push(srcArgs[arg]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.__drawImage.apply(this, args);
|
|
||||||
//this.__drawImage(image,sx, sy, sw, sh, dx, dy, dw, dh);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {
|
|
||||||
const numArgs = arguments.length;
|
|
||||||
|
|
||||||
function drawImageCommands() {
|
|
||||||
|
|
||||||
if (numArgs === 3) {
|
|
||||||
const x = parseFloat(sx) || 0.0;
|
|
||||||
const y = parseFloat(sy) || 0.0;
|
|
||||||
|
|
||||||
return ("d" + image._id + ",0,0," +
|
|
||||||
image.width + "," + image.height + "," +
|
|
||||||
x + "," + y + "," + image.width + "," + image.height + ";");
|
|
||||||
} else if (numArgs === 5) {
|
|
||||||
const x = parseFloat(sx) || 0.0;
|
|
||||||
const y = parseFloat(sy) || 0.0;
|
|
||||||
const width = parseInt(sw) || image.width;
|
|
||||||
const height = parseInt(sh) || image.height;
|
|
||||||
|
|
||||||
return ("d" + image._id + ",0,0," +
|
|
||||||
image.width + "," + image.height + "," +
|
|
||||||
x + "," + y + "," + width + "," + height + ";");
|
|
||||||
} else if (numArgs === 9) {
|
|
||||||
sx = parseFloat(sx) || 0.0;
|
|
||||||
sy = parseFloat(sy) || 0.0;
|
|
||||||
sw = parseInt(sw) || image.width;
|
|
||||||
sh = parseInt(sh) || image.height;
|
|
||||||
dx = parseFloat(dx) || 0.0;
|
|
||||||
dy = parseFloat(dy) || 0.0;
|
|
||||||
dw = parseInt(dw) || image.width;
|
|
||||||
dh = parseInt(dh) || image.height;
|
|
||||||
|
|
||||||
return ("d" + image._id + "," +
|
|
||||||
sx + "," + sy + "," + sw + "," + sh + "," +
|
|
||||||
dx + "," + dy + "," + dw + "," + dh + ";");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._drawCommands += drawImageCommands();
|
|
||||||
}
|
|
||||||
|
|
||||||
_flush(reserve, callback) {
|
|
||||||
const commands = this._drawCommands;
|
|
||||||
this._drawCommands = '';
|
|
||||||
CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback);
|
|
||||||
this._needRender = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_redrawflush(reserve, callback) {
|
|
||||||
const commands = this._redrawCommands;
|
|
||||||
CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback);
|
|
||||||
if (this._needRedrawImageCache.length == 0) {
|
|
||||||
this._redrawCommands = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
draw(reserve, callback) {
|
|
||||||
if (!reserve) {
|
|
||||||
this._globalAlpha = this._savedGlobalAlpha.pop();
|
|
||||||
this._savedGlobalAlpha.push(this._globalAlpha);
|
|
||||||
this._redrawCommands = this._drawCommands;
|
|
||||||
this._needRedrawImageCache = this._notCommitDrawImageCache;
|
|
||||||
if (this._autoSaveContext) {
|
|
||||||
this._drawCommands = ("v;" + this._drawCommands);
|
|
||||||
this._autoSaveContext = false;
|
|
||||||
} else {
|
|
||||||
this._drawCommands = ("e;X;v;" + this._drawCommands);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this._needRedrawImageCache = this._needRedrawImageCache.concat(this._notCommitDrawImageCache);
|
|
||||||
this._redrawCommands += this._drawCommands;
|
|
||||||
if (this._autoSaveContext) {
|
|
||||||
this._drawCommands = ("v;" + this._drawCommands);
|
|
||||||
this._autoSaveContext = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._notCommitDrawImageCache = [];
|
|
||||||
if (this._flush) {
|
|
||||||
this._flush(reserve, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getImageData(x, y, w, h, callback) {
|
|
||||||
CanvasRenderingContext2D.GBridge.getImageData(this.componentId, x, y, w, h, function(res) {
|
|
||||||
res.data = Base64ToUint8ClampedArray(res.data);
|
|
||||||
if (typeof(callback) == 'function') {
|
|
||||||
callback(res);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
putImageData(data, x, y, w, h, callback) {
|
|
||||||
if (data instanceof Uint8ClampedArray) {
|
|
||||||
data = ArrayBufferToBase64(data);
|
|
||||||
CanvasRenderingContext2D.GBridge.putImageData(this.componentId, data, x, y, w, h, function(res) {
|
|
||||||
if (typeof(callback) == 'function') {
|
|
||||||
callback(res);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toTempFilePath(x, y, width, height, destWidth, destHeight, fileType, quality, callback) {
|
|
||||||
CanvasRenderingContext2D.GBridge.toTempFilePath(this.componentId, x, y, width, height, destWidth, destHeight,
|
|
||||||
fileType, quality,
|
|
||||||
function(res) {
|
|
||||||
if (typeof(callback) == 'function') {
|
|
||||||
callback(res);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
export default class WebGLActiveInfo {
|
|
||||||
className = 'WebGLActiveInfo';
|
|
||||||
|
|
||||||
constructor({
|
|
||||||
type, name, size
|
|
||||||
}) {
|
|
||||||
this.type = type;
|
|
||||||
this.name = name;
|
|
||||||
this.size = size;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
import {getTransferedObjectUUID} from './classUtils';
|
|
||||||
|
|
||||||
const name = 'WebGLBuffer';
|
|
||||||
|
|
||||||
function uuid(id) {
|
|
||||||
return getTransferedObjectUUID(name, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class WebGLBuffer {
|
|
||||||
className = name;
|
|
||||||
|
|
||||||
constructor(id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uuid = uuid;
|
|
||||||
|
|
||||||
uuid() {
|
|
||||||
return uuid(this.id);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
import {getTransferedObjectUUID} from './classUtils';
|
|
||||||
|
|
||||||
const name = 'WebGLFrameBuffer';
|
|
||||||
|
|
||||||
function uuid(id) {
|
|
||||||
return getTransferedObjectUUID(name, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class WebGLFramebuffer {
|
|
||||||
className = name;
|
|
||||||
|
|
||||||
constructor(id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uuid = uuid;
|
|
||||||
|
|
||||||
uuid() {
|
|
||||||
return uuid(this.id);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,298 +0,0 @@
|
|||||||
export default {
|
|
||||||
"DEPTH_BUFFER_BIT": 256,
|
|
||||||
"STENCIL_BUFFER_BIT": 1024,
|
|
||||||
"COLOR_BUFFER_BIT": 16384,
|
|
||||||
"POINTS": 0,
|
|
||||||
"LINES": 1,
|
|
||||||
"LINE_LOOP": 2,
|
|
||||||
"LINE_STRIP": 3,
|
|
||||||
"TRIANGLES": 4,
|
|
||||||
"TRIANGLE_STRIP": 5,
|
|
||||||
"TRIANGLE_FAN": 6,
|
|
||||||
"ZERO": 0,
|
|
||||||
"ONE": 1,
|
|
||||||
"SRC_COLOR": 768,
|
|
||||||
"ONE_MINUS_SRC_COLOR": 769,
|
|
||||||
"SRC_ALPHA": 770,
|
|
||||||
"ONE_MINUS_SRC_ALPHA": 771,
|
|
||||||
"DST_ALPHA": 772,
|
|
||||||
"ONE_MINUS_DST_ALPHA": 773,
|
|
||||||
"DST_COLOR": 774,
|
|
||||||
"ONE_MINUS_DST_COLOR": 775,
|
|
||||||
"SRC_ALPHA_SATURATE": 776,
|
|
||||||
"FUNC_ADD": 32774,
|
|
||||||
"BLEND_EQUATION": 32777,
|
|
||||||
"BLEND_EQUATION_RGB": 32777,
|
|
||||||
"BLEND_EQUATION_ALPHA": 34877,
|
|
||||||
"FUNC_SUBTRACT": 32778,
|
|
||||||
"FUNC_REVERSE_SUBTRACT": 32779,
|
|
||||||
"BLEND_DST_RGB": 32968,
|
|
||||||
"BLEND_SRC_RGB": 32969,
|
|
||||||
"BLEND_DST_ALPHA": 32970,
|
|
||||||
"BLEND_SRC_ALPHA": 32971,
|
|
||||||
"CONSTANT_COLOR": 32769,
|
|
||||||
"ONE_MINUS_CONSTANT_COLOR": 32770,
|
|
||||||
"CONSTANT_ALPHA": 32771,
|
|
||||||
"ONE_MINUS_CONSTANT_ALPHA": 32772,
|
|
||||||
"BLEND_COLOR": 32773,
|
|
||||||
"ARRAY_BUFFER": 34962,
|
|
||||||
"ELEMENT_ARRAY_BUFFER": 34963,
|
|
||||||
"ARRAY_BUFFER_BINDING": 34964,
|
|
||||||
"ELEMENT_ARRAY_BUFFER_BINDING": 34965,
|
|
||||||
"STREAM_DRAW": 35040,
|
|
||||||
"STATIC_DRAW": 35044,
|
|
||||||
"DYNAMIC_DRAW": 35048,
|
|
||||||
"BUFFER_SIZE": 34660,
|
|
||||||
"BUFFER_USAGE": 34661,
|
|
||||||
"CURRENT_VERTEX_ATTRIB": 34342,
|
|
||||||
"FRONT": 1028,
|
|
||||||
"BACK": 1029,
|
|
||||||
"FRONT_AND_BACK": 1032,
|
|
||||||
"TEXTURE_2D": 3553,
|
|
||||||
"CULL_FACE": 2884,
|
|
||||||
"BLEND": 3042,
|
|
||||||
"DITHER": 3024,
|
|
||||||
"STENCIL_TEST": 2960,
|
|
||||||
"DEPTH_TEST": 2929,
|
|
||||||
"SCISSOR_TEST": 3089,
|
|
||||||
"POLYGON_OFFSET_FILL": 32823,
|
|
||||||
"SAMPLE_ALPHA_TO_COVERAGE": 32926,
|
|
||||||
"SAMPLE_COVERAGE": 32928,
|
|
||||||
"NO_ERROR": 0,
|
|
||||||
"INVALID_ENUM": 1280,
|
|
||||||
"INVALID_VALUE": 1281,
|
|
||||||
"INVALID_OPERATION": 1282,
|
|
||||||
"OUT_OF_MEMORY": 1285,
|
|
||||||
"CW": 2304,
|
|
||||||
"CCW": 2305,
|
|
||||||
"LINE_WIDTH": 2849,
|
|
||||||
"ALIASED_POINT_SIZE_RANGE": 33901,
|
|
||||||
"ALIASED_LINE_WIDTH_RANGE": 33902,
|
|
||||||
"CULL_FACE_MODE": 2885,
|
|
||||||
"FRONT_FACE": 2886,
|
|
||||||
"DEPTH_RANGE": 2928,
|
|
||||||
"DEPTH_WRITEMASK": 2930,
|
|
||||||
"DEPTH_CLEAR_VALUE": 2931,
|
|
||||||
"DEPTH_FUNC": 2932,
|
|
||||||
"STENCIL_CLEAR_VALUE": 2961,
|
|
||||||
"STENCIL_FUNC": 2962,
|
|
||||||
"STENCIL_FAIL": 2964,
|
|
||||||
"STENCIL_PASS_DEPTH_FAIL": 2965,
|
|
||||||
"STENCIL_PASS_DEPTH_PASS": 2966,
|
|
||||||
"STENCIL_REF": 2967,
|
|
||||||
"STENCIL_VALUE_MASK": 2963,
|
|
||||||
"STENCIL_WRITEMASK": 2968,
|
|
||||||
"STENCIL_BACK_FUNC": 34816,
|
|
||||||
"STENCIL_BACK_FAIL": 34817,
|
|
||||||
"STENCIL_BACK_PASS_DEPTH_FAIL": 34818,
|
|
||||||
"STENCIL_BACK_PASS_DEPTH_PASS": 34819,
|
|
||||||
"STENCIL_BACK_REF": 36003,
|
|
||||||
"STENCIL_BACK_VALUE_MASK": 36004,
|
|
||||||
"STENCIL_BACK_WRITEMASK": 36005,
|
|
||||||
"VIEWPORT": 2978,
|
|
||||||
"SCISSOR_BOX": 3088,
|
|
||||||
"COLOR_CLEAR_VALUE": 3106,
|
|
||||||
"COLOR_WRITEMASK": 3107,
|
|
||||||
"UNPACK_ALIGNMENT": 3317,
|
|
||||||
"PACK_ALIGNMENT": 3333,
|
|
||||||
"MAX_TEXTURE_SIZE": 3379,
|
|
||||||
"MAX_VIEWPORT_DIMS": 3386,
|
|
||||||
"SUBPIXEL_BITS": 3408,
|
|
||||||
"RED_BITS": 3410,
|
|
||||||
"GREEN_BITS": 3411,
|
|
||||||
"BLUE_BITS": 3412,
|
|
||||||
"ALPHA_BITS": 3413,
|
|
||||||
"DEPTH_BITS": 3414,
|
|
||||||
"STENCIL_BITS": 3415,
|
|
||||||
"POLYGON_OFFSET_UNITS": 10752,
|
|
||||||
"POLYGON_OFFSET_FACTOR": 32824,
|
|
||||||
"TEXTURE_BINDING_2D": 32873,
|
|
||||||
"SAMPLE_BUFFERS": 32936,
|
|
||||||
"SAMPLES": 32937,
|
|
||||||
"SAMPLE_COVERAGE_VALUE": 32938,
|
|
||||||
"SAMPLE_COVERAGE_INVERT": 32939,
|
|
||||||
"COMPRESSED_TEXTURE_FORMATS": 34467,
|
|
||||||
"DONT_CARE": 4352,
|
|
||||||
"FASTEST": 4353,
|
|
||||||
"NICEST": 4354,
|
|
||||||
"GENERATE_MIPMAP_HINT": 33170,
|
|
||||||
"BYTE": 5120,
|
|
||||||
"UNSIGNED_BYTE": 5121,
|
|
||||||
"SHORT": 5122,
|
|
||||||
"UNSIGNED_SHORT": 5123,
|
|
||||||
"INT": 5124,
|
|
||||||
"UNSIGNED_INT": 5125,
|
|
||||||
"FLOAT": 5126,
|
|
||||||
"DEPTH_COMPONENT": 6402,
|
|
||||||
"ALPHA": 6406,
|
|
||||||
"RGB": 6407,
|
|
||||||
"RGBA": 6408,
|
|
||||||
"LUMINANCE": 6409,
|
|
||||||
"LUMINANCE_ALPHA": 6410,
|
|
||||||
"UNSIGNED_SHORT_4_4_4_4": 32819,
|
|
||||||
"UNSIGNED_SHORT_5_5_5_1": 32820,
|
|
||||||
"UNSIGNED_SHORT_5_6_5": 33635,
|
|
||||||
"FRAGMENT_SHADER": 35632,
|
|
||||||
"VERTEX_SHADER": 35633,
|
|
||||||
"MAX_VERTEX_ATTRIBS": 34921,
|
|
||||||
"MAX_VERTEX_UNIFORM_VECTORS": 36347,
|
|
||||||
"MAX_VARYING_VECTORS": 36348,
|
|
||||||
"MAX_COMBINED_TEXTURE_IMAGE_UNITS": 35661,
|
|
||||||
"MAX_VERTEX_TEXTURE_IMAGE_UNITS": 35660,
|
|
||||||
"MAX_TEXTURE_IMAGE_UNITS": 34930,
|
|
||||||
"MAX_FRAGMENT_UNIFORM_VECTORS": 36349,
|
|
||||||
"SHADER_TYPE": 35663,
|
|
||||||
"DELETE_STATUS": 35712,
|
|
||||||
"LINK_STATUS": 35714,
|
|
||||||
"VALIDATE_STATUS": 35715,
|
|
||||||
"ATTACHED_SHADERS": 35717,
|
|
||||||
"ACTIVE_UNIFORMS": 35718,
|
|
||||||
"ACTIVE_ATTRIBUTES": 35721,
|
|
||||||
"SHADING_LANGUAGE_VERSION": 35724,
|
|
||||||
"CURRENT_PROGRAM": 35725,
|
|
||||||
"NEVER": 512,
|
|
||||||
"LESS": 513,
|
|
||||||
"EQUAL": 514,
|
|
||||||
"LEQUAL": 515,
|
|
||||||
"GREATER": 516,
|
|
||||||
"NOTEQUAL": 517,
|
|
||||||
"GEQUAL": 518,
|
|
||||||
"ALWAYS": 519,
|
|
||||||
"KEEP": 7680,
|
|
||||||
"REPLACE": 7681,
|
|
||||||
"INCR": 7682,
|
|
||||||
"DECR": 7683,
|
|
||||||
"INVERT": 5386,
|
|
||||||
"INCR_WRAP": 34055,
|
|
||||||
"DECR_WRAP": 34056,
|
|
||||||
"VENDOR": 7936,
|
|
||||||
"RENDERER": 7937,
|
|
||||||
"VERSION": 7938,
|
|
||||||
"NEAREST": 9728,
|
|
||||||
"LINEAR": 9729,
|
|
||||||
"NEAREST_MIPMAP_NEAREST": 9984,
|
|
||||||
"LINEAR_MIPMAP_NEAREST": 9985,
|
|
||||||
"NEAREST_MIPMAP_LINEAR": 9986,
|
|
||||||
"LINEAR_MIPMAP_LINEAR": 9987,
|
|
||||||
"TEXTURE_MAG_FILTER": 10240,
|
|
||||||
"TEXTURE_MIN_FILTER": 10241,
|
|
||||||
"TEXTURE_WRAP_S": 10242,
|
|
||||||
"TEXTURE_WRAP_T": 10243,
|
|
||||||
"TEXTURE": 5890,
|
|
||||||
"TEXTURE_CUBE_MAP": 34067,
|
|
||||||
"TEXTURE_BINDING_CUBE_MAP": 34068,
|
|
||||||
"TEXTURE_CUBE_MAP_POSITIVE_X": 34069,
|
|
||||||
"TEXTURE_CUBE_MAP_NEGATIVE_X": 34070,
|
|
||||||
"TEXTURE_CUBE_MAP_POSITIVE_Y": 34071,
|
|
||||||
"TEXTURE_CUBE_MAP_NEGATIVE_Y": 34072,
|
|
||||||
"TEXTURE_CUBE_MAP_POSITIVE_Z": 34073,
|
|
||||||
"TEXTURE_CUBE_MAP_NEGATIVE_Z": 34074,
|
|
||||||
"MAX_CUBE_MAP_TEXTURE_SIZE": 34076,
|
|
||||||
"TEXTURE0": 33984,
|
|
||||||
"TEXTURE1": 33985,
|
|
||||||
"TEXTURE2": 33986,
|
|
||||||
"TEXTURE3": 33987,
|
|
||||||
"TEXTURE4": 33988,
|
|
||||||
"TEXTURE5": 33989,
|
|
||||||
"TEXTURE6": 33990,
|
|
||||||
"TEXTURE7": 33991,
|
|
||||||
"TEXTURE8": 33992,
|
|
||||||
"TEXTURE9": 33993,
|
|
||||||
"TEXTURE10": 33994,
|
|
||||||
"TEXTURE11": 33995,
|
|
||||||
"TEXTURE12": 33996,
|
|
||||||
"TEXTURE13": 33997,
|
|
||||||
"TEXTURE14": 33998,
|
|
||||||
"TEXTURE15": 33999,
|
|
||||||
"TEXTURE16": 34000,
|
|
||||||
"TEXTURE17": 34001,
|
|
||||||
"TEXTURE18": 34002,
|
|
||||||
"TEXTURE19": 34003,
|
|
||||||
"TEXTURE20": 34004,
|
|
||||||
"TEXTURE21": 34005,
|
|
||||||
"TEXTURE22": 34006,
|
|
||||||
"TEXTURE23": 34007,
|
|
||||||
"TEXTURE24": 34008,
|
|
||||||
"TEXTURE25": 34009,
|
|
||||||
"TEXTURE26": 34010,
|
|
||||||
"TEXTURE27": 34011,
|
|
||||||
"TEXTURE28": 34012,
|
|
||||||
"TEXTURE29": 34013,
|
|
||||||
"TEXTURE30": 34014,
|
|
||||||
"TEXTURE31": 34015,
|
|
||||||
"ACTIVE_TEXTURE": 34016,
|
|
||||||
"REPEAT": 10497,
|
|
||||||
"CLAMP_TO_EDGE": 33071,
|
|
||||||
"MIRRORED_REPEAT": 33648,
|
|
||||||
"FLOAT_VEC2": 35664,
|
|
||||||
"FLOAT_VEC3": 35665,
|
|
||||||
"FLOAT_VEC4": 35666,
|
|
||||||
"INT_VEC2": 35667,
|
|
||||||
"INT_VEC3": 35668,
|
|
||||||
"INT_VEC4": 35669,
|
|
||||||
"BOOL": 35670,
|
|
||||||
"BOOL_VEC2": 35671,
|
|
||||||
"BOOL_VEC3": 35672,
|
|
||||||
"BOOL_VEC4": 35673,
|
|
||||||
"FLOAT_MAT2": 35674,
|
|
||||||
"FLOAT_MAT3": 35675,
|
|
||||||
"FLOAT_MAT4": 35676,
|
|
||||||
"SAMPLER_2D": 35678,
|
|
||||||
"SAMPLER_CUBE": 35680,
|
|
||||||
"VERTEX_ATTRIB_ARRAY_ENABLED": 34338,
|
|
||||||
"VERTEX_ATTRIB_ARRAY_SIZE": 34339,
|
|
||||||
"VERTEX_ATTRIB_ARRAY_STRIDE": 34340,
|
|
||||||
"VERTEX_ATTRIB_ARRAY_TYPE": 34341,
|
|
||||||
"VERTEX_ATTRIB_ARRAY_NORMALIZED": 34922,
|
|
||||||
"VERTEX_ATTRIB_ARRAY_POINTER": 34373,
|
|
||||||
"VERTEX_ATTRIB_ARRAY_BUFFER_BINDING": 34975,
|
|
||||||
"IMPLEMENTATION_COLOR_READ_TYPE": 35738,
|
|
||||||
"IMPLEMENTATION_COLOR_READ_FORMAT": 35739,
|
|
||||||
"COMPILE_STATUS": 35713,
|
|
||||||
"LOW_FLOAT": 36336,
|
|
||||||
"MEDIUM_FLOAT": 36337,
|
|
||||||
"HIGH_FLOAT": 36338,
|
|
||||||
"LOW_INT": 36339,
|
|
||||||
"MEDIUM_INT": 36340,
|
|
||||||
"HIGH_INT": 36341,
|
|
||||||
"FRAMEBUFFER": 36160,
|
|
||||||
"RENDERBUFFER": 36161,
|
|
||||||
"RGBA4": 32854,
|
|
||||||
"RGB5_A1": 32855,
|
|
||||||
"RGB565": 36194,
|
|
||||||
"DEPTH_COMPONENT16": 33189,
|
|
||||||
"STENCIL_INDEX8": 36168,
|
|
||||||
"DEPTH_STENCIL": 34041,
|
|
||||||
"RENDERBUFFER_WIDTH": 36162,
|
|
||||||
"RENDERBUFFER_HEIGHT": 36163,
|
|
||||||
"RENDERBUFFER_INTERNAL_FORMAT": 36164,
|
|
||||||
"RENDERBUFFER_RED_SIZE": 36176,
|
|
||||||
"RENDERBUFFER_GREEN_SIZE": 36177,
|
|
||||||
"RENDERBUFFER_BLUE_SIZE": 36178,
|
|
||||||
"RENDERBUFFER_ALPHA_SIZE": 36179,
|
|
||||||
"RENDERBUFFER_DEPTH_SIZE": 36180,
|
|
||||||
"RENDERBUFFER_STENCIL_SIZE": 36181,
|
|
||||||
"FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE": 36048,
|
|
||||||
"FRAMEBUFFER_ATTACHMENT_OBJECT_NAME": 36049,
|
|
||||||
"FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL": 36050,
|
|
||||||
"FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE": 36051,
|
|
||||||
"COLOR_ATTACHMENT0": 36064,
|
|
||||||
"DEPTH_ATTACHMENT": 36096,
|
|
||||||
"STENCIL_ATTACHMENT": 36128,
|
|
||||||
"DEPTH_STENCIL_ATTACHMENT": 33306,
|
|
||||||
"NONE": 0,
|
|
||||||
"FRAMEBUFFER_COMPLETE": 36053,
|
|
||||||
"FRAMEBUFFER_INCOMPLETE_ATTACHMENT": 36054,
|
|
||||||
"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT": 36055,
|
|
||||||
"FRAMEBUFFER_INCOMPLETE_DIMENSIONS": 36057,
|
|
||||||
"FRAMEBUFFER_UNSUPPORTED": 36061,
|
|
||||||
"FRAMEBUFFER_BINDING": 36006,
|
|
||||||
"RENDERBUFFER_BINDING": 36007,
|
|
||||||
"MAX_RENDERBUFFER_SIZE": 34024,
|
|
||||||
"INVALID_FRAMEBUFFER_OPERATION": 1286,
|
|
||||||
"UNPACK_FLIP_Y_WEBGL": 37440,
|
|
||||||
"UNPACK_PREMULTIPLY_ALPHA_WEBGL": 37441,
|
|
||||||
"CONTEXT_LOST_WEBGL": 37442,
|
|
||||||
"UNPACK_COLORSPACE_CONVERSION_WEBGL": 37443,
|
|
||||||
"BROWSER_DEFAULT_WEBGL": 37444
|
|
||||||
};
|
|
@ -1,142 +0,0 @@
|
|||||||
let i = 1;
|
|
||||||
|
|
||||||
const GLmethod = {};
|
|
||||||
|
|
||||||
GLmethod.activeTexture = i++; //1
|
|
||||||
GLmethod.attachShader = i++;
|
|
||||||
GLmethod.bindAttribLocation = i++;
|
|
||||||
GLmethod.bindBuffer = i++;
|
|
||||||
GLmethod.bindFramebuffer = i++;
|
|
||||||
GLmethod.bindRenderbuffer = i++;
|
|
||||||
GLmethod.bindTexture = i++;
|
|
||||||
GLmethod.blendColor = i++;
|
|
||||||
GLmethod.blendEquation = i++;
|
|
||||||
GLmethod.blendEquationSeparate = i++; //10
|
|
||||||
GLmethod.blendFunc = i++;
|
|
||||||
GLmethod.blendFuncSeparate = i++;
|
|
||||||
GLmethod.bufferData = i++;
|
|
||||||
GLmethod.bufferSubData = i++;
|
|
||||||
GLmethod.checkFramebufferStatus = i++;
|
|
||||||
GLmethod.clear = i++;
|
|
||||||
GLmethod.clearColor = i++;
|
|
||||||
GLmethod.clearDepth = i++;
|
|
||||||
GLmethod.clearStencil = i++;
|
|
||||||
GLmethod.colorMask = i++; //20
|
|
||||||
GLmethod.compileShader = i++;
|
|
||||||
GLmethod.compressedTexImage2D = i++;
|
|
||||||
GLmethod.compressedTexSubImage2D = i++;
|
|
||||||
GLmethod.copyTexImage2D = i++;
|
|
||||||
GLmethod.copyTexSubImage2D = i++;
|
|
||||||
GLmethod.createBuffer = i++;
|
|
||||||
GLmethod.createFramebuffer = i++;
|
|
||||||
GLmethod.createProgram = i++;
|
|
||||||
GLmethod.createRenderbuffer = i++;
|
|
||||||
GLmethod.createShader = i++; //30
|
|
||||||
GLmethod.createTexture = i++;
|
|
||||||
GLmethod.cullFace = i++;
|
|
||||||
GLmethod.deleteBuffer = i++;
|
|
||||||
GLmethod.deleteFramebuffer = i++;
|
|
||||||
GLmethod.deleteProgram = i++;
|
|
||||||
GLmethod.deleteRenderbuffer = i++;
|
|
||||||
GLmethod.deleteShader = i++;
|
|
||||||
GLmethod.deleteTexture = i++;
|
|
||||||
GLmethod.depthFunc = i++;
|
|
||||||
GLmethod.depthMask = i++; //40
|
|
||||||
GLmethod.depthRange = i++;
|
|
||||||
GLmethod.detachShader = i++;
|
|
||||||
GLmethod.disable = i++;
|
|
||||||
GLmethod.disableVertexAttribArray = i++;
|
|
||||||
GLmethod.drawArrays = i++;
|
|
||||||
GLmethod.drawArraysInstancedANGLE = i++;
|
|
||||||
GLmethod.drawElements = i++;
|
|
||||||
GLmethod.drawElementsInstancedANGLE = i++;
|
|
||||||
GLmethod.enable = i++;
|
|
||||||
GLmethod.enableVertexAttribArray = i++; //50
|
|
||||||
GLmethod.flush = i++;
|
|
||||||
GLmethod.framebufferRenderbuffer = i++;
|
|
||||||
GLmethod.framebufferTexture2D = i++;
|
|
||||||
GLmethod.frontFace = i++;
|
|
||||||
GLmethod.generateMipmap = i++;
|
|
||||||
GLmethod.getActiveAttrib = i++;
|
|
||||||
GLmethod.getActiveUniform = i++;
|
|
||||||
GLmethod.getAttachedShaders = i++;
|
|
||||||
GLmethod.getAttribLocation = i++;
|
|
||||||
GLmethod.getBufferParameter = i++; //60
|
|
||||||
GLmethod.getContextAttributes = i++;
|
|
||||||
GLmethod.getError = i++;
|
|
||||||
GLmethod.getExtension = i++;
|
|
||||||
GLmethod.getFramebufferAttachmentParameter = i++;
|
|
||||||
GLmethod.getParameter = i++;
|
|
||||||
GLmethod.getProgramInfoLog = i++;
|
|
||||||
GLmethod.getProgramParameter = i++;
|
|
||||||
GLmethod.getRenderbufferParameter = i++;
|
|
||||||
GLmethod.getShaderInfoLog = i++;
|
|
||||||
GLmethod.getShaderParameter = i++; //70
|
|
||||||
GLmethod.getShaderPrecisionFormat = i++;
|
|
||||||
GLmethod.getShaderSource = i++;
|
|
||||||
GLmethod.getSupportedExtensions = i++;
|
|
||||||
GLmethod.getTexParameter = i++;
|
|
||||||
GLmethod.getUniform = i++;
|
|
||||||
GLmethod.getUniformLocation = i++;
|
|
||||||
GLmethod.getVertexAttrib = i++;
|
|
||||||
GLmethod.getVertexAttribOffset = i++;
|
|
||||||
GLmethod.isBuffer = i++;
|
|
||||||
GLmethod.isContextLost = i++; //80
|
|
||||||
GLmethod.isEnabled = i++;
|
|
||||||
GLmethod.isFramebuffer = i++;
|
|
||||||
GLmethod.isProgram = i++;
|
|
||||||
GLmethod.isRenderbuffer = i++;
|
|
||||||
GLmethod.isShader = i++;
|
|
||||||
GLmethod.isTexture = i++;
|
|
||||||
GLmethod.lineWidth = i++;
|
|
||||||
GLmethod.linkProgram = i++;
|
|
||||||
GLmethod.pixelStorei = i++;
|
|
||||||
GLmethod.polygonOffset = i++; //90
|
|
||||||
GLmethod.readPixels = i++;
|
|
||||||
GLmethod.renderbufferStorage = i++;
|
|
||||||
GLmethod.sampleCoverage = i++;
|
|
||||||
GLmethod.scissor = i++;
|
|
||||||
GLmethod.shaderSource = i++;
|
|
||||||
GLmethod.stencilFunc = i++;
|
|
||||||
GLmethod.stencilFuncSeparate = i++;
|
|
||||||
GLmethod.stencilMask = i++;
|
|
||||||
GLmethod.stencilMaskSeparate = i++;
|
|
||||||
GLmethod.stencilOp = i++; //100
|
|
||||||
GLmethod.stencilOpSeparate = i++;
|
|
||||||
GLmethod.texImage2D = i++;
|
|
||||||
GLmethod.texParameterf = i++;
|
|
||||||
GLmethod.texParameteri = i++;
|
|
||||||
GLmethod.texSubImage2D = i++;
|
|
||||||
GLmethod.uniform1f = i++;
|
|
||||||
GLmethod.uniform1fv = i++;
|
|
||||||
GLmethod.uniform1i = i++;
|
|
||||||
GLmethod.uniform1iv = i++;
|
|
||||||
GLmethod.uniform2f = i++; //110
|
|
||||||
GLmethod.uniform2fv = i++;
|
|
||||||
GLmethod.uniform2i = i++;
|
|
||||||
GLmethod.uniform2iv = i++;
|
|
||||||
GLmethod.uniform3f = i++;
|
|
||||||
GLmethod.uniform3fv = i++;
|
|
||||||
GLmethod.uniform3i = i++;
|
|
||||||
GLmethod.uniform3iv = i++;
|
|
||||||
GLmethod.uniform4f = i++;
|
|
||||||
GLmethod.uniform4fv = i++;
|
|
||||||
GLmethod.uniform4i = i++; //120
|
|
||||||
GLmethod.uniform4iv = i++;
|
|
||||||
GLmethod.uniformMatrix2fv = i++;
|
|
||||||
GLmethod.uniformMatrix3fv = i++;
|
|
||||||
GLmethod.uniformMatrix4fv = i++;
|
|
||||||
GLmethod.useProgram = i++;
|
|
||||||
GLmethod.validateProgram = i++;
|
|
||||||
GLmethod.vertexAttrib1f = i++; //new
|
|
||||||
GLmethod.vertexAttrib2f = i++; //new
|
|
||||||
GLmethod.vertexAttrib3f = i++; //new
|
|
||||||
GLmethod.vertexAttrib4f = i++; //new //130
|
|
||||||
GLmethod.vertexAttrib1fv = i++; //new
|
|
||||||
GLmethod.vertexAttrib2fv = i++; //new
|
|
||||||
GLmethod.vertexAttrib3fv = i++; //new
|
|
||||||
GLmethod.vertexAttrib4fv = i++; //new
|
|
||||||
GLmethod.vertexAttribPointer = i++;
|
|
||||||
GLmethod.viewport = i++;
|
|
||||||
|
|
||||||
export default GLmethod;
|
|
@ -1,23 +0,0 @@
|
|||||||
const GLtype = {};
|
|
||||||
|
|
||||||
[
|
|
||||||
"GLbitfield",
|
|
||||||
"GLboolean",
|
|
||||||
"GLbyte",
|
|
||||||
"GLclampf",
|
|
||||||
"GLenum",
|
|
||||||
"GLfloat",
|
|
||||||
"GLint",
|
|
||||||
"GLintptr",
|
|
||||||
"GLsizei",
|
|
||||||
"GLsizeiptr",
|
|
||||||
"GLshort",
|
|
||||||
"GLubyte",
|
|
||||||
"GLuint",
|
|
||||||
"GLushort"
|
|
||||||
].sort().map((typeName, i) => GLtype[typeName] = 1 >> (i + 1));
|
|
||||||
|
|
||||||
export default GLtype;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
|||||||
import {getTransferedObjectUUID} from './classUtils';
|
|
||||||
|
|
||||||
const name = 'WebGLProgram';
|
|
||||||
|
|
||||||
function uuid(id) {
|
|
||||||
return getTransferedObjectUUID(name, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class WebGLProgram {
|
|
||||||
className = name;
|
|
||||||
|
|
||||||
constructor(id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uuid = uuid;
|
|
||||||
|
|
||||||
uuid() {
|
|
||||||
return uuid(this.id);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
import {getTransferedObjectUUID} from './classUtils';
|
|
||||||
|
|
||||||
const name = 'WebGLRenderBuffer';
|
|
||||||
|
|
||||||
function uuid(id) {
|
|
||||||
return getTransferedObjectUUID(name, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class WebGLRenderbuffer {
|
|
||||||
className = name;
|
|
||||||
|
|
||||||
constructor(id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uuid = uuid;
|
|
||||||
|
|
||||||
uuid() {
|
|
||||||
return uuid(this.id);
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,22 +0,0 @@
|
|||||||
import {getTransferedObjectUUID} from './classUtils';
|
|
||||||
|
|
||||||
const name = 'WebGLShader';
|
|
||||||
|
|
||||||
function uuid(id) {
|
|
||||||
return getTransferedObjectUUID(name, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class WebGLShader {
|
|
||||||
className = name;
|
|
||||||
|
|
||||||
constructor(id, type) {
|
|
||||||
this.id = id;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uuid = uuid;
|
|
||||||
|
|
||||||
uuid() {
|
|
||||||
return uuid(this.id);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
export default class WebGLShaderPrecisionFormat {
|
|
||||||
className = 'WebGLShaderPrecisionFormat';
|
|
||||||
|
|
||||||
constructor({
|
|
||||||
rangeMin, rangeMax, precision
|
|
||||||
}) {
|
|
||||||
this.rangeMin = rangeMin;
|
|
||||||
this.rangeMax = rangeMax;
|
|
||||||
this.precision = precision;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
import {getTransferedObjectUUID} from './classUtils';
|
|
||||||
|
|
||||||
const name = 'WebGLTexture';
|
|
||||||
|
|
||||||
function uuid(id) {
|
|
||||||
return getTransferedObjectUUID(name, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class WebGLTexture {
|
|
||||||
className = name;
|
|
||||||
|
|
||||||
constructor(id, type) {
|
|
||||||
this.id = id;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uuid = uuid;
|
|
||||||
|
|
||||||
uuid() {
|
|
||||||
return uuid(this.id);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
import {getTransferedObjectUUID} from './classUtils';
|
|
||||||
|
|
||||||
const name = 'WebGLUniformLocation';
|
|
||||||
|
|
||||||
function uuid(id) {
|
|
||||||
return getTransferedObjectUUID(name, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class WebGLUniformLocation {
|
|
||||||
className = name;
|
|
||||||
|
|
||||||
constructor(id, type) {
|
|
||||||
this.id = id;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uuid = uuid;
|
|
||||||
|
|
||||||
uuid() {
|
|
||||||
return uuid(this.id);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
export function getTransferedObjectUUID(name, id) {
|
|
||||||
return `${name.toLowerCase()}-${id}`;
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
import GContext2D from '../context-2d/RenderingContext';
|
|
||||||
import GContextWebGL from '../context-webgl/RenderingContext';
|
|
||||||
|
|
||||||
export default class GCanvas {
|
|
||||||
|
|
||||||
// static GBridge = null;
|
|
||||||
|
|
||||||
id = null;
|
|
||||||
|
|
||||||
_needRender = true;
|
|
||||||
|
|
||||||
constructor(id, { disableAutoSwap }) {
|
|
||||||
this.id = id;
|
|
||||||
|
|
||||||
this._disableAutoSwap = disableAutoSwap;
|
|
||||||
if (disableAutoSwap) {
|
|
||||||
this._swapBuffers = () => {
|
|
||||||
GCanvas.GBridge.render(this.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getContext(type) {
|
|
||||||
|
|
||||||
let context = null;
|
|
||||||
|
|
||||||
if (type.match(/webgl/i)) {
|
|
||||||
context = new GContextWebGL(this);
|
|
||||||
|
|
||||||
context.componentId = this.id;
|
|
||||||
|
|
||||||
if (!this._disableAutoSwap) {
|
|
||||||
const render = () => {
|
|
||||||
if (this._needRender) {
|
|
||||||
GCanvas.GBridge.render(this.id);
|
|
||||||
this._needRender = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setInterval(render, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
GCanvas.GBridge.callSetContextType(this.id, 1); // 0 for 2d; 1 for webgl
|
|
||||||
} else if (type.match(/2d/i)) {
|
|
||||||
context = new GContext2D(this);
|
|
||||||
|
|
||||||
context.componentId = this.id;
|
|
||||||
|
|
||||||
// const render = ( callback ) => {
|
|
||||||
//
|
|
||||||
// const commands = context._drawCommands;
|
|
||||||
// context._drawCommands = '';
|
|
||||||
//
|
|
||||||
// GCanvas.GBridge.render2d(this.id, commands, callback);
|
|
||||||
// this._needRender = false;
|
|
||||||
// }
|
|
||||||
// //draw方法触发
|
|
||||||
// context._flush = render;
|
|
||||||
// //setInterval(render, 16);
|
|
||||||
|
|
||||||
GCanvas.GBridge.callSetContextType(this.id, 0);
|
|
||||||
} else {
|
|
||||||
throw new Error('not supported context ' + type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return context;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
reset() {
|
|
||||||
GCanvas.GBridge.callReset(this.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,96 +0,0 @@
|
|||||||
let incId = 1;
|
|
||||||
|
|
||||||
const noop = function () { };
|
|
||||||
|
|
||||||
class GImage {
|
|
||||||
|
|
||||||
static GBridge = null;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this._id = incId++;
|
|
||||||
this._width = 0;
|
|
||||||
this._height = 0;
|
|
||||||
this._src = undefined;
|
|
||||||
this._onload = noop;
|
|
||||||
this._onerror = noop;
|
|
||||||
this.complete = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
get width() {
|
|
||||||
return this._width;
|
|
||||||
}
|
|
||||||
set width(v) {
|
|
||||||
this._width = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
get height() {
|
|
||||||
return this._height;
|
|
||||||
}
|
|
||||||
|
|
||||||
set height(v) {
|
|
||||||
this._height = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
get src() {
|
|
||||||
return this._src;
|
|
||||||
}
|
|
||||||
|
|
||||||
set src(v) {
|
|
||||||
|
|
||||||
if (v.startsWith('//')) {
|
|
||||||
v = 'http:' + v;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._src = v;
|
|
||||||
|
|
||||||
GImage.GBridge.perloadImage([this._src, this._id], (data) => {
|
|
||||||
if (typeof data === 'string') {
|
|
||||||
data = JSON.parse(data);
|
|
||||||
}
|
|
||||||
if (data.error) {
|
|
||||||
var evt = { type: 'error', target: this };
|
|
||||||
this.onerror(evt);
|
|
||||||
} else {
|
|
||||||
this.complete = true;
|
|
||||||
this.width = typeof data.width === 'number' ? data.width : 0;
|
|
||||||
this.height = typeof data.height === 'number' ? data.height : 0;
|
|
||||||
var evt = { type: 'load', target: this };
|
|
||||||
this.onload(evt);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
addEventListener(name, listener) {
|
|
||||||
if (name === 'load') {
|
|
||||||
this.onload = listener;
|
|
||||||
} else if (name === 'error') {
|
|
||||||
this.onerror = listener;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
removeEventListener(name, listener) {
|
|
||||||
if (name === 'load') {
|
|
||||||
this.onload = noop;
|
|
||||||
} else if (name === 'error') {
|
|
||||||
this.onerror = noop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get onload() {
|
|
||||||
return this._onload;
|
|
||||||
}
|
|
||||||
|
|
||||||
set onload(v) {
|
|
||||||
this._onload = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
get onerror() {
|
|
||||||
return this._onerror;
|
|
||||||
}
|
|
||||||
|
|
||||||
set onerror(v) {
|
|
||||||
this._onerror = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default GImage;
|
|
@ -1,24 +0,0 @@
|
|||||||
|
|
||||||
export function ArrayBufferToBase64 (buffer) {
|
|
||||||
var binary = '';
|
|
||||||
var bytes = new Uint8ClampedArray(buffer);
|
|
||||||
for (var len = bytes.byteLength, i = 0; i < len; i++) {
|
|
||||||
binary += String.fromCharCode(bytes[i]);
|
|
||||||
}
|
|
||||||
return btoa(binary);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Base64ToUint8ClampedArray(base64String) {
|
|
||||||
const padding = '='.repeat((4 - base64String.length % 4) % 4);
|
|
||||||
const base64 = (base64String + padding)
|
|
||||||
.replace(/\-/g, '+')
|
|
||||||
.replace(/_/g, '/');
|
|
||||||
|
|
||||||
const rawData = atob(base64);
|
|
||||||
const outputArray = new Uint8ClampedArray(rawData.length);
|
|
||||||
|
|
||||||
for (let i = 0; i < rawData.length; ++i) {
|
|
||||||
outputArray[i] = rawData.charCodeAt(i);
|
|
||||||
}
|
|
||||||
return outputArray;
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
import GCanvas from './env/canvas';
|
|
||||||
import GImage from './env/image';
|
|
||||||
|
|
||||||
import GWebGLRenderingContext from './context-webgl/RenderingContext';
|
|
||||||
import GContext2D from './context-2d/RenderingContext';
|
|
||||||
|
|
||||||
import GBridgeWeex from './bridge/bridge-weex';
|
|
||||||
|
|
||||||
export let Image = GImage;
|
|
||||||
|
|
||||||
export let WeexBridge = GBridgeWeex;
|
|
||||||
|
|
||||||
export function enable(el, { bridge, debug, disableAutoSwap, disableComboCommands } = {}) {
|
|
||||||
|
|
||||||
const GBridge = GImage.GBridge = GCanvas.GBridge = GWebGLRenderingContext.GBridge = GContext2D.GBridge = bridge;
|
|
||||||
|
|
||||||
GBridge.callEnable(el.ref, [
|
|
||||||
0, // renderMode: 0--RENDERMODE_WHEN_DIRTY, 1--RENDERMODE_CONTINUOUSLY
|
|
||||||
-1, // hybridLayerType: 0--LAYER_TYPE_NONE 1--LAYER_TYPE_SOFTWARE 2--LAYER_TYPE_HARDWARE
|
|
||||||
false, // supportScroll
|
|
||||||
false, // newCanvasMode
|
|
||||||
1, // compatible
|
|
||||||
'white',// clearColor
|
|
||||||
false // sameLevel: newCanvasMode = true && true => GCanvasView and Webview is same level
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (debug === true) {
|
|
||||||
GBridge.callEnableDebug();
|
|
||||||
}
|
|
||||||
if (disableComboCommands) {
|
|
||||||
GBridge.callEnableDisableCombo();
|
|
||||||
}
|
|
||||||
|
|
||||||
var canvas = new GCanvas(el.ref, { disableAutoSwap });
|
|
||||||
canvas.width = el.style.width;
|
|
||||||
canvas.height = el.style.height;
|
|
||||||
|
|
||||||
return canvas;
|
|
||||||
};
|
|
@ -1,85 +0,0 @@
|
|||||||
export default {
|
|
||||||
props: {
|
|
||||||
//二维码内容
|
|
||||||
value: {
|
|
||||||
type: [String, Number]
|
|
||||||
},
|
|
||||||
//选项
|
|
||||||
options: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//二维码大小
|
|
||||||
size: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 200
|
|
||||||
},
|
|
||||||
//导出的文件类型
|
|
||||||
fileType: {
|
|
||||||
type: String,
|
|
||||||
default: 'png'
|
|
||||||
},
|
|
||||||
//是否初始化组件后就开始生成
|
|
||||||
start: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
//是否数据发生改变自动重绘
|
|
||||||
auto: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
//隐藏组件
|
|
||||||
hide: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* canvas 类型,微信小程序默认使用2d,非2d微信官方已放弃维护,问题比较多
|
|
||||||
* 注意:微信小程序type2d手机上正常,PC上微信内打开小程序toDataURL报错,看后期微信官方团队会不会做兼容,不兼容的话只能在自行判断在PC使用非2d,或者直接提示用户请在手机上操作,微信团队的海报中心小程序就是这么做的
|
|
||||||
*/
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: () => {
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
return '2d';
|
|
||||||
// #endif
|
|
||||||
// #ifndef MP-WEIXIN
|
|
||||||
return 'normal';
|
|
||||||
// #endif
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//队列绘制,主要针对NVue端
|
|
||||||
queue: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
//是否队列加载图片,可减少canvas发起的网络资源请求,节省服务器资源
|
|
||||||
isQueueLoadImage: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
//loading态
|
|
||||||
loading: {
|
|
||||||
type: Boolean,
|
|
||||||
default: undefined
|
|
||||||
},
|
|
||||||
//H5保存即自动下载(在支持的环境下),默认false为仅弹层提示用户需要长按图片保存,不会自动下载
|
|
||||||
h5SaveIsDownload: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
//H5下载名称
|
|
||||||
h5DownloadName: {
|
|
||||||
type: String,
|
|
||||||
default: 'uvQRCode'
|
|
||||||
},
|
|
||||||
// H5保存二维码时候是否显示提示
|
|
||||||
h5SaveTip: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
@ -1,41 +0,0 @@
|
|||||||
function Queue() {
|
|
||||||
let waitingQueue = this.waitingQueue = [];
|
|
||||||
let isRunning = this.isRunning = false; // 记录是否有未完成的任务
|
|
||||||
|
|
||||||
function execute(task, resolve, reject) {
|
|
||||||
task()
|
|
||||||
.then((data) => {
|
|
||||||
resolve(data);
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
reject(e);
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
// 等待任务队列中如果有任务,则触发它;否则设置isRunning = false,表示无任务状态
|
|
||||||
if (waitingQueue.length) {
|
|
||||||
const next = waitingQueue.shift();
|
|
||||||
execute(next.task, next.resolve, next.reject);
|
|
||||||
} else {
|
|
||||||
isRunning = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.exec = function(task) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (isRunning) {
|
|
||||||
waitingQueue.push({
|
|
||||||
task,
|
|
||||||
resolve,
|
|
||||||
reject
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
isRunning = true;
|
|
||||||
execute(task, resolve, reject);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 队列实例,某些平台一起使用多个组件时需要通过队列逐一绘制,否则部分绘制方法异常,nvue端的iOS gcanvas尤其明显,在不通过队列绘制时会出现图片丢失的情况 */
|
|
||||||
export const queueDraw = new Queue();
|
|
||||||
export const queueLoadImage = new Queue();
|
|
File diff suppressed because one or more lines are too long
@ -1,87 +0,0 @@
|
|||||||
{
|
|
||||||
"id": "uv-qrcode",
|
|
||||||
"displayName": "uv-qrcode 二维码 全面兼容vue3+2、app、h5、小程序等多端",
|
|
||||||
"version": "1.0.4",
|
|
||||||
"description": "该组件是超级强大二维码生成功能,可扩展性高。自定义二维码样式,如随机颜色、圆点、方块、块与块之间的间距等等,具体请查看文档。",
|
|
||||||
"keywords": [
|
|
||||||
"uv-qrcode",
|
|
||||||
"qrcode",
|
|
||||||
"uvui",
|
|
||||||
"uv-ui",
|
|
||||||
"二维码"
|
|
||||||
],
|
|
||||||
"repository": "",
|
|
||||||
"engines": {
|
|
||||||
"HBuilderX": "^3.1.0"
|
|
||||||
},
|
|
||||||
"dcloudext": {
|
|
||||||
"type": "component-vue",
|
|
||||||
"sale": {
|
|
||||||
"regular": {
|
|
||||||
"price": "0.00"
|
|
||||||
},
|
|
||||||
"sourcecode": {
|
|
||||||
"price": "0.00"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"contact": {
|
|
||||||
"qq": ""
|
|
||||||
},
|
|
||||||
"declaration": {
|
|
||||||
"ads": "无",
|
|
||||||
"data": "插件不采集任何数据",
|
|
||||||
"permissions": "无"
|
|
||||||
},
|
|
||||||
"npmurl": ""
|
|
||||||
},
|
|
||||||
"uni_modules": {
|
|
||||||
"dependencies": [
|
|
||||||
"uv-ui-tools"
|
|
||||||
],
|
|
||||||
"encrypt": [],
|
|
||||||
"platforms": {
|
|
||||||
"cloud": {
|
|
||||||
"tcb": "y",
|
|
||||||
"aliyun": "y"
|
|
||||||
},
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
## QRCode 二维码生成器
|
|
||||||
|
|
||||||
> **组件名:uv-qrcode**
|
|
||||||
|
|
||||||
超级强大二维码生成组件,可扩展性高。自定义二维码样式,如随机颜色、圆点、方块、块与块之间的间距等等,具体请在下方查看文档。
|
|
||||||
|
|
||||||
灵活配置,开箱即用,文档全面,支持自定义二维码风格。
|
|
||||||
|
|
||||||
# <a href="https://www.uvui.cn/components/qrcode.html" target="_blank">查看文档</a>
|
|
||||||
|
|
||||||
## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small style="font-size:14px;">(请不要 下载插件ZIP)</small>
|
|
||||||
|
|
||||||
### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
|
||||||
|
|
||||||
<a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank">
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
</a>
|
|
||||||
|
|
||||||
#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
|
@ -1,10 +0,0 @@
|
|||||||
## 1.0.3(2023-06-29)
|
|
||||||
1. 增加customStyle参数,方便设置样式
|
|
||||||
## 1.0.2(2023-06-29)
|
|
||||||
1. 新增title自定义
|
|
||||||
2. 完善文档说明
|
|
||||||
## 1.0.1(2023-05-16)
|
|
||||||
1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
|
|
||||||
2. 优化部分功能
|
|
||||||
## 1.0.0(2023-05-10)
|
|
||||||
uv-steps 步骤条
|
|
@ -1,25 +0,0 @@
|
|||||||
export default {
|
|
||||||
props: {
|
|
||||||
// 标题
|
|
||||||
title: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 描述文本
|
|
||||||
desc: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 图标大小
|
|
||||||
iconSize: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 17
|
|
||||||
},
|
|
||||||
// 当前步骤是否处于失败状态
|
|
||||||
error: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
...uni.$uv?.props?.stepsItem
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,347 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view
|
|
||||||
class="uv-steps-item"
|
|
||||||
ref="uv-steps-item"
|
|
||||||
:class="[`uv-steps-item--${parentData.direction}`]"
|
|
||||||
:style="[$uv.addStyle(customStyle)]"
|
|
||||||
>
|
|
||||||
<view
|
|
||||||
class="uv-steps-item__line"
|
|
||||||
v-if="index + 1 < childLength"
|
|
||||||
:class="[`uv-steps-item__line--${parentData.direction}`]"
|
|
||||||
:style="[lineStyle]">
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
:class="[
|
|
||||||
'uv-steps-item__wrapper',
|
|
||||||
`uv-steps-item__wrapper--${parentData.direction}`,
|
|
||||||
parentData.dot && `uv-steps-item__wrapper--${parentData.direction}--dot`
|
|
||||||
]">
|
|
||||||
<slot name="icon">
|
|
||||||
<view
|
|
||||||
class="uv-steps-item__wrapper__dot"
|
|
||||||
v-if="parentData.dot"
|
|
||||||
:style="{
|
|
||||||
backgroundColor: statusColor
|
|
||||||
}">
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
class="uv-steps-item__wrapper__icon"
|
|
||||||
v-else-if="parentData.activeIcon || parentData.inactiveIcon">
|
|
||||||
<uv-icon
|
|
||||||
:name="index <= parentData.current ? parentData.activeIcon : parentData.inactiveIcon"
|
|
||||||
:size="iconSize"
|
|
||||||
:color="index <= parentData.current ? parentData.activeColor : parentData.inactiveColor">
|
|
||||||
</uv-icon>
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
v-else
|
|
||||||
:style="{
|
|
||||||
backgroundColor: statusClass === 'process' ? parentData.activeColor : 'transparent',
|
|
||||||
borderColor: statusColor
|
|
||||||
}"
|
|
||||||
class="uv-steps-item__wrapper__circle">
|
|
||||||
<text
|
|
||||||
v-if="statusClass === 'process' || statusClass === 'wait'"
|
|
||||||
class="uv-steps-item__wrapper__circle__text"
|
|
||||||
:style="{
|
|
||||||
color: index == parentData.current ? '#ffffff' : parentData.inactiveColor
|
|
||||||
}">{{ index + 1}}</text>
|
|
||||||
<uv-icon
|
|
||||||
v-else
|
|
||||||
:color="statusClass === 'error' ? 'error' : parentData.activeColor"
|
|
||||||
size="12"
|
|
||||||
:name="statusClass === 'error' ? 'close' : 'checkmark'">
|
|
||||||
</uv-icon>
|
|
||||||
</view>
|
|
||||||
</slot>
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
:class="[
|
|
||||||
'uv-steps-item__content',
|
|
||||||
`uv-steps-item__content--${parentData.direction}`
|
|
||||||
]"
|
|
||||||
:style="[contentStyle]"
|
|
||||||
>
|
|
||||||
<slot name="title">
|
|
||||||
<uv-text
|
|
||||||
:text="title"
|
|
||||||
:type="parentData.current == index ? 'main' : 'content'"
|
|
||||||
lineHeight="20px"
|
|
||||||
:size="parentData.current == index ? 14 : 13"
|
|
||||||
></uv-text>
|
|
||||||
</slot>
|
|
||||||
<slot name="desc">
|
|
||||||
<uv-text
|
|
||||||
:text="desc"
|
|
||||||
type="tips"
|
|
||||||
size="12"
|
|
||||||
></uv-text>
|
|
||||||
</slot>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
|
||||||
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
|
||||||
import props from './props.js';
|
|
||||||
// #ifdef APP-NVUE
|
|
||||||
const dom = uni.requireNativePlugin('dom')
|
|
||||||
// #endif
|
|
||||||
/**
|
|
||||||
* StepsItem 步骤条的子组件
|
|
||||||
* @description 本组件需要和uv-steps配合使用
|
|
||||||
* @tutorial https://www.uvui.cn/components/steps.html
|
|
||||||
* @property {String} title 标题文字
|
|
||||||
* @property {String} current 描述文本
|
|
||||||
* @property {String | Number} iconSize 图标大小 (默认 17 )
|
|
||||||
* @property {Boolean} error 当前步骤是否处于失败状态 (默认 false )
|
|
||||||
* @example <uv-steps current="0"><uv-steps-item title="已出库" desc="10:35" ></uv-steps-item></uv-steps>
|
|
||||||
*/
|
|
||||||
export default {
|
|
||||||
name: 'uv-steps-item',
|
|
||||||
mixins: [mpMixin, mixin, props],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
index: 0,
|
|
||||||
childLength: 0,
|
|
||||||
showLine: false,
|
|
||||||
size: {
|
|
||||||
height: 0,
|
|
||||||
width: 0
|
|
||||||
},
|
|
||||||
parentData: {
|
|
||||||
direction: 'row',
|
|
||||||
current: 0,
|
|
||||||
activeColor: '',
|
|
||||||
inactiveColor: '',
|
|
||||||
activeIcon: '',
|
|
||||||
inactiveIcon: '',
|
|
||||||
dot: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
'parentData'(newValue, oldValue) {}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.init()
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
lineStyle() {
|
|
||||||
const style = {}
|
|
||||||
if (this.parentData.direction === 'row') {
|
|
||||||
style.width = this.size.width + 'px'
|
|
||||||
style.left = this.size.width / 2 + 'px'
|
|
||||||
} else {
|
|
||||||
style.height = this.size.height + 'px'
|
|
||||||
}
|
|
||||||
style.backgroundColor = this.parent.children?.[this.index + 1]?.error ? '#f56c6c' : this.index < this.parentData.current ? this.parentData.activeColor : this.parentData.inactiveColor
|
|
||||||
return style
|
|
||||||
},
|
|
||||||
statusClass() {
|
|
||||||
const {
|
|
||||||
index,
|
|
||||||
error
|
|
||||||
} = this
|
|
||||||
const {
|
|
||||||
current
|
|
||||||
} = this.parentData
|
|
||||||
if (current == index) {
|
|
||||||
return error === true ? 'error' : 'process'
|
|
||||||
} else if (error) {
|
|
||||||
return 'error'
|
|
||||||
} else if (current > index) {
|
|
||||||
return 'finish'
|
|
||||||
} else {
|
|
||||||
return 'wait'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
statusColor() {
|
|
||||||
let color = ''
|
|
||||||
switch (this.statusClass) {
|
|
||||||
case 'finish':
|
|
||||||
color = this.parentData.activeColor
|
|
||||||
break
|
|
||||||
case 'error':
|
|
||||||
color = '#f56c6c'
|
|
||||||
break
|
|
||||||
case 'process':
|
|
||||||
color = this.parentData.dot ? this.parentData.activeColor : 'transparent'
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
color = this.parentData.inactiveColor
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return color
|
|
||||||
},
|
|
||||||
contentStyle() {
|
|
||||||
const style = {}
|
|
||||||
if (this.parentData.direction === 'column') {
|
|
||||||
style.marginLeft = this.parentData.dot ? '2px' : '6px'
|
|
||||||
style.marginTop = this.parentData.dot ? '0px' : '6px'
|
|
||||||
} else {
|
|
||||||
style.marginTop = this.parentData.dot ? '2px' : '6px'
|
|
||||||
style.marginLeft = this.parentData.dot ? '2px' : '6px'
|
|
||||||
}
|
|
||||||
return style
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.parent && this.parent.updateFromChild()
|
|
||||||
this.$uv.sleep().then(() => {
|
|
||||||
this.getStepsItemRect()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
init() {
|
|
||||||
// 初始化数据
|
|
||||||
this.updateParentData()
|
|
||||||
if (!this.parent) {
|
|
||||||
return this.$uv.error('uv-steps-item必须要搭配uv-steps组件使用')
|
|
||||||
}
|
|
||||||
this.index = this.parent.children.indexOf(this)
|
|
||||||
this.childLength = this.parent.children.length
|
|
||||||
},
|
|
||||||
updateParentData() {
|
|
||||||
// 此方法在mixin中
|
|
||||||
this.getParentData('uv-steps')
|
|
||||||
},
|
|
||||||
// 父组件数据发生变化
|
|
||||||
updateFromParent() {
|
|
||||||
this.init()
|
|
||||||
},
|
|
||||||
// 获取组件的尺寸,用于设置横线的位置
|
|
||||||
getStepsItemRect() {
|
|
||||||
// #ifndef APP-NVUE
|
|
||||||
this.$uvGetRect('.uv-steps-item').then(size => {
|
|
||||||
this.size = size
|
|
||||||
})
|
|
||||||
// #endif
|
|
||||||
// #ifdef APP-NVUE
|
|
||||||
dom.getComponentRect(this.$refs['uv-steps-item'], res => {
|
|
||||||
const {
|
|
||||||
size
|
|
||||||
} = res
|
|
||||||
this.size = size
|
|
||||||
})
|
|
||||||
// #endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
|
|
||||||
.uv-steps-item {
|
|
||||||
flex: 1;
|
|
||||||
@include flex;
|
|
||||||
|
|
||||||
&--row {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--column {
|
|
||||||
position: relative;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: flex-start;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__wrapper {
|
|
||||||
@include flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
position: relative;
|
|
||||||
background-color: #fff;
|
|
||||||
|
|
||||||
&--column {
|
|
||||||
width: 20px;
|
|
||||||
height: 32px;
|
|
||||||
|
|
||||||
&--dot {
|
|
||||||
height: 20px;
|
|
||||||
width: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--row {
|
|
||||||
width: 32px;
|
|
||||||
height: 20px;
|
|
||||||
|
|
||||||
&--dot {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__circle {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
/* #ifndef APP-NVUE */
|
|
||||||
box-sizing: border-box;
|
|
||||||
flex-shrink: 0;
|
|
||||||
/* #endif */
|
|
||||||
border-radius: 100px;
|
|
||||||
border-width: 1px;
|
|
||||||
border-color: $uv-tips-color;
|
|
||||||
border-style: solid;
|
|
||||||
@include flex(row);
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
transition: background-color 0.3s;
|
|
||||||
|
|
||||||
&__text {
|
|
||||||
color: $uv-tips-color;
|
|
||||||
font-size: 11px;
|
|
||||||
@include flex(row);
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 11px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__dot {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
border-radius: 100px;
|
|
||||||
background-color: $uv-content-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__content {
|
|
||||||
@include flex;
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
&--row {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--column {
|
|
||||||
flex-direction: column;
|
|
||||||
margin-left: 6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__line {
|
|
||||||
position: absolute;
|
|
||||||
background: $uv-tips-color;
|
|
||||||
|
|
||||||
&--row {
|
|
||||||
top: 10px;
|
|
||||||
height: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--column {
|
|
||||||
width: 1px;
|
|
||||||
left: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,40 +0,0 @@
|
|||||||
export default {
|
|
||||||
props: {
|
|
||||||
// 排列方向
|
|
||||||
direction: {
|
|
||||||
type: String,
|
|
||||||
default: 'row'
|
|
||||||
},
|
|
||||||
// 设置第几个步骤
|
|
||||||
current: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
// 激活状态颜色
|
|
||||||
activeColor: {
|
|
||||||
type: String,
|
|
||||||
default: '#3c9cff'
|
|
||||||
},
|
|
||||||
// 未激活状态颜色
|
|
||||||
inactiveColor: {
|
|
||||||
type: String,
|
|
||||||
default: '#969799'
|
|
||||||
},
|
|
||||||
// 激活状态的图标
|
|
||||||
activeIcon: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 未激活状态图标
|
|
||||||
inactiveIcon: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 是否显示点类型
|
|
||||||
dot: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
...uni.$uv?.props?.steps
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view
|
|
||||||
:class="['uv-steps',`uv-steps--${direction}`]"
|
|
||||||
:style="[$uv.addStyle(customStyle)]"
|
|
||||||
>
|
|
||||||
<slot></slot>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { func } from '@/uni_modules/uv-ui-tools/libs/function/test.js'
|
|
||||||
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
|
||||||
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
|
||||||
import props from './props.js';
|
|
||||||
/**
|
|
||||||
* Steps 步骤条
|
|
||||||
* @description 该组件一般用于完成一个任务要分几个步骤,标识目前处于第几步的场景。
|
|
||||||
* @tutorial https://www.uvui.cn/components/steps.html
|
|
||||||
* @property {String} direction row-横向,column-竖向 (默认 'row' )
|
|
||||||
* @property {String | Number} current 设置当前处于第几步 (默认 0 )
|
|
||||||
* @property {String} activeColor 激活状态颜色 (默认 '#3c9cff' )
|
|
||||||
* @property {String} inactiveColor 未激活状态颜色 (默认 '#969799' )
|
|
||||||
* @property {String} activeIcon 激活状态的图标
|
|
||||||
* @property {String} inactiveIcon 未激活状态图标
|
|
||||||
* @property {Boolean} dot 是否显示点类型 (默认 false )
|
|
||||||
* @example <uv-steps current="0"><uv-steps-item title="已出库" desc="10:35" ></uv-steps-item></uv-steps>
|
|
||||||
*/
|
|
||||||
export default {
|
|
||||||
name: 'uv-steps',
|
|
||||||
mixins: [mpMixin, mixin, props],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
children() {
|
|
||||||
this.updateChildData()
|
|
||||||
},
|
|
||||||
parentData() {
|
|
||||||
this.updateChildData()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
// 监听参数的变化,通过watch中,手动去更新子组件的数据,否则子组件不会自动变化
|
|
||||||
parentData() {
|
|
||||||
return [this.current, this.direction, this.activeColor, this.inactiveColor, this.activeIcon, this.inactiveIcon, this.dot]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 更新子组件的数据
|
|
||||||
updateChildData() {
|
|
||||||
this.children.map(child => {
|
|
||||||
// 先判断子组件是否存在对应的方法
|
|
||||||
func((child || {}).updateFromParent()) && child.updateFromParent()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 接受子组件的通知,去修改其他子组件的数据
|
|
||||||
updateFromChild() {
|
|
||||||
this.updateChildData()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.children = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
|
||||||
|
|
||||||
.uv-steps {
|
|
||||||
@include flex;
|
|
||||||
|
|
||||||
&--column {
|
|
||||||
flex-direction: column
|
|
||||||
}
|
|
||||||
|
|
||||||
&--row {
|
|
||||||
flex-direction: row;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,89 +0,0 @@
|
|||||||
{
|
|
||||||
"id": "uv-steps",
|
|
||||||
"displayName": "uv-steps 步骤条 全面兼容小程序、nvue、vue2、vue3等多端",
|
|
||||||
"version": "1.0.3",
|
|
||||||
"description": "步骤条组件一般用于完成一个任务要分几个步骤,标识目前处于第几步的场景。",
|
|
||||||
"keywords": [
|
|
||||||
"uv-steps",
|
|
||||||
"uvui",
|
|
||||||
"uv-ui",
|
|
||||||
"steps",
|
|
||||||
"步骤条"
|
|
||||||
],
|
|
||||||
"repository": "",
|
|
||||||
"engines": {
|
|
||||||
"HBuilderX": "^3.1.0"
|
|
||||||
},
|
|
||||||
"dcloudext": {
|
|
||||||
"type": "component-vue",
|
|
||||||
"sale": {
|
|
||||||
"regular": {
|
|
||||||
"price": "0.00"
|
|
||||||
},
|
|
||||||
"sourcecode": {
|
|
||||||
"price": "0.00"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"contact": {
|
|
||||||
"qq": ""
|
|
||||||
},
|
|
||||||
"declaration": {
|
|
||||||
"ads": "无",
|
|
||||||
"data": "插件不采集任何数据",
|
|
||||||
"permissions": "无"
|
|
||||||
},
|
|
||||||
"npmurl": ""
|
|
||||||
},
|
|
||||||
"uni_modules": {
|
|
||||||
"dependencies": [
|
|
||||||
"uv-ui-tools",
|
|
||||||
"uv-icon",
|
|
||||||
"uv-text"
|
|
||||||
],
|
|
||||||
"encrypt": [],
|
|
||||||
"platforms": {
|
|
||||||
"cloud": {
|
|
||||||
"tcb": "y",
|
|
||||||
"aliyun": "y"
|
|
||||||
},
|
|
||||||
"client": {
|
|
||||||
"Vue": {
|
|
||||||
"vue2": "y",
|
|
||||||
"vue3": "y"
|
|
||||||
},
|
|
||||||
"App": {
|
|
||||||
"app-vue": "y",
|
|
||||||
"app-nvue": "n"
|
|
||||||
},
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
## Steps 步骤条
|
|
||||||
|
|
||||||
> **组件名:uv-steps**
|
|
||||||
|
|
||||||
该组件一般用于完成一个任务要分几个步骤,标识目前处于第几步的场景。
|
|
||||||
|
|
||||||
### <a href="https://www.uvui.cn/components/steps.html" target="_blank">查看文档</a>
|
|
||||||
|
|
||||||
### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
|
||||||
|
|
||||||
#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
|
@ -1,11 +0,0 @@
|
|||||||
## 1.0.4(2023-10-13)
|
|
||||||
1. 优化
|
|
||||||
## 1.0.3(2023-10-13)
|
|
||||||
1. unmounted兼容vue3
|
|
||||||
## 1.0.2(2023-05-27)
|
|
||||||
1. 不支持抖音小程序说明
|
|
||||||
## 1.0.1(2023-05-16)
|
|
||||||
1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
|
|
||||||
2. 优化部分功能
|
|
||||||
## 1.0.0(2023-05-10)
|
|
||||||
uv-swipe-action 滑动单元格
|
|
@ -1,256 +0,0 @@
|
|||||||
/**
|
|
||||||
* 此为wxs模块,只支持APP-VUE,微信和QQ小程序以及H5平台
|
|
||||||
* wxs内部不支持es6语法,变量只能使用var定义,无法使用解构,箭头函数等特性
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 开始触摸
|
|
||||||
function touchstart(event, ownerInstance) {
|
|
||||||
// 触发事件的组件的ComponentDescriptor实例
|
|
||||||
var instance = event.instance
|
|
||||||
// wxs内的局部变量快照,此快照是属于整个组件的,在touchstart和touchmove事件中都能获取到相同的结果
|
|
||||||
var state = instance.getState()
|
|
||||||
if (state.disable) return
|
|
||||||
var touches = event.touches
|
|
||||||
// 如果进行的是多指触控,不允许进行操作
|
|
||||||
if (touches && touches.length > 1) return
|
|
||||||
// 标识当前为滑动中状态
|
|
||||||
state.moving = true
|
|
||||||
// 记录触摸开始点的坐标值
|
|
||||||
state.startX = touches[0].pageX
|
|
||||||
state.startY = touches[0].pageY
|
|
||||||
}
|
|
||||||
|
|
||||||
// 触摸滑动
|
|
||||||
function touchmove(event, ownerInstance) {
|
|
||||||
// 触发事件的组件的ComponentDescriptor实例
|
|
||||||
var instance = event.instance
|
|
||||||
// wxs内的局部变量快照
|
|
||||||
var state = instance.getState()
|
|
||||||
if (state.disabled || !state.moving) return
|
|
||||||
|
|
||||||
var touches = event.touches
|
|
||||||
var pageX = touches[0].pageX
|
|
||||||
var pageY = touches[0].pageY
|
|
||||||
var moveX = pageX - state.startX
|
|
||||||
var moveY = pageY - state.startY
|
|
||||||
var buttonsWidth = state.buttonsWidth
|
|
||||||
|
|
||||||
// 移动的X轴距离大于Y轴距离,也即终点与起点位置连线,与X轴夹角小于45度时,禁止页面滚动
|
|
||||||
if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > state.threshold) {
|
|
||||||
event.preventDefault()
|
|
||||||
event.stopPropagation()
|
|
||||||
}
|
|
||||||
// 如果移动的X轴距离小于Y轴距离,也即终点位置与起点位置连线,与Y轴夹角小于45度时,认为是页面上下滑动,而不是左右滑动单元格
|
|
||||||
if (Math.abs(moveX) < Math.abs(moveY)) return
|
|
||||||
|
|
||||||
// 限制右滑的距离,不允许内容部分往右偏移,右滑会导致X轴偏移值大于0,以此做判断
|
|
||||||
// 此处不能直接return,因为滑动过程中会缺失某些关键点坐标,会导致错乱,最好的办法就是
|
|
||||||
// 在超出后,设置为0
|
|
||||||
if (state.status === 'open') {
|
|
||||||
// 在开启状态下,向左滑动,需忽略
|
|
||||||
if (moveX < 0) moveX = 0
|
|
||||||
// 想要收起菜单,最大能移动的距离为按钮的总宽度
|
|
||||||
if (moveX > buttonsWidth) moveX = buttonsWidth
|
|
||||||
// 如果是已经打开了的状态,向左滑动时,移动收起菜单
|
|
||||||
moveSwipeAction(-buttonsWidth + moveX, instance, ownerInstance)
|
|
||||||
} else {
|
|
||||||
// 关闭状态下,右滑动需忽略
|
|
||||||
if (moveX > 0) moveX = 0
|
|
||||||
// 滑动的距离不允许超过所有按钮的总宽度,此时只能是左滑,最终设置按钮的总宽度,同时为负数
|
|
||||||
if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth
|
|
||||||
// 只要是在滑过程中,就不断移动菜单的内容部分,从而使隐藏的菜单显示出来
|
|
||||||
moveSwipeAction(moveX, instance, ownerInstance)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 触摸结束
|
|
||||||
function touchend(event, ownerInstance) {
|
|
||||||
// 触发事件的组件的ComponentDescriptor实例
|
|
||||||
var instance = event.instance
|
|
||||||
// wxs内的局部变量快照
|
|
||||||
var state = instance.getState()
|
|
||||||
if (!state.moving || state.disabled) return
|
|
||||||
var touches = event.changedTouches ? event.changedTouches[0] : {}
|
|
||||||
var pageX = touches.pageX
|
|
||||||
var pageY = touches.pageY
|
|
||||||
var moveX = pageX - state.startX
|
|
||||||
if (state.status === 'open') {
|
|
||||||
// 在展开的状态下,继续左滑,无需操作
|
|
||||||
if (moveX < 0) return
|
|
||||||
// 在开启状态下,点击一下内容区域,moveX为0,也即没有进行移动,这时执行收起菜单逻辑
|
|
||||||
if (moveX === 0) {
|
|
||||||
return closeSwipeAction(instance, ownerInstance)
|
|
||||||
}
|
|
||||||
// 在开启状态下,滑动距离小于阈值,则默认为不关闭,同时恢复原来的打开状态
|
|
||||||
if (Math.abs(moveX) < state.threshold) {
|
|
||||||
openSwipeAction(instance, ownerInstance)
|
|
||||||
} else {
|
|
||||||
// 如果滑动距离大于阈值,则执行收起逻辑
|
|
||||||
closeSwipeAction(instance, ownerInstance)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 在关闭的状态下,右滑,无需操作
|
|
||||||
if (moveX > 0) return
|
|
||||||
// 理由同上
|
|
||||||
if (Math.abs(moveX) < state.threshold) {
|
|
||||||
closeSwipeAction(instance, ownerInstance)
|
|
||||||
} else {
|
|
||||||
openSwipeAction(instance, ownerInstance)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取过渡时间
|
|
||||||
function getDuration(value) {
|
|
||||||
if (value.toString().indexOf('s') >= 0) return value
|
|
||||||
return value > 30 ? value + 'ms' : value + 's'
|
|
||||||
}
|
|
||||||
|
|
||||||
// 滑动结束时判断滑动的方向
|
|
||||||
function getMoveDirection(instance, ownerInstance) {
|
|
||||||
var state = instance.getState()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 移动滑动选择器内容区域,同时显示出其隐藏的菜单
|
|
||||||
function moveSwipeAction(moveX, instance, ownerInstance) {
|
|
||||||
var state = instance.getState()
|
|
||||||
// 获取所有按钮的实例,需要通过它去设置按钮的位移
|
|
||||||
var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button')
|
|
||||||
var len = buttons.length
|
|
||||||
var previewButtonsMoveX = 0
|
|
||||||
|
|
||||||
// 设置菜单内容部分的偏移
|
|
||||||
instance.requestAnimationFrame(function() {
|
|
||||||
instance.setStyle({
|
|
||||||
// 设置translateX的值
|
|
||||||
'transition': 'none',
|
|
||||||
transform: 'translateX(' + moveX + 'px)',
|
|
||||||
'-webkit-transform': 'translateX(' + moveX + 'px)'
|
|
||||||
})
|
|
||||||
// 折叠按钮动画
|
|
||||||
for (var i = len - 1; i >= 0; i--) {
|
|
||||||
// 通过比例,得出元素自身该移动的距离
|
|
||||||
var translateX = state.buttons[i].width / state.buttonsWidth * moveX
|
|
||||||
// 最终移动的距离,是通过自身比例算出的距离,再加上在它之前所有按钮移动的距离之和
|
|
||||||
var realTranslateX = translateX + previewButtonsMoveX
|
|
||||||
buttons[i].setStyle({
|
|
||||||
// 在移动期间,不能使用过渡效果,否则会造成卡顿,本质原因是每次移动一点,就要花一定时间去过渡这个过程
|
|
||||||
'transition': 'none',
|
|
||||||
'transform': 'translateX(' + realTranslateX + 'px)',
|
|
||||||
'-webkit-transform': 'translateX(' + realTranslateX + 'px)'
|
|
||||||
})
|
|
||||||
// 记录本按钮之前的所有按钮的移动距离之和
|
|
||||||
previewButtonsMoveX += translateX
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 一次性展开滑动菜单
|
|
||||||
function openSwipeAction(instance, ownerInstance) {
|
|
||||||
var state = instance.getState()
|
|
||||||
// 获取所有按钮的实例,需要通过它去设置按钮的位移
|
|
||||||
var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button')
|
|
||||||
var len = buttons.length
|
|
||||||
// 处理duration单位问题
|
|
||||||
const duration = getDuration(state.duration)
|
|
||||||
// 展开过程中,是向左移动,所以X的偏移应该为负值
|
|
||||||
var buttonsWidth = -state.buttonsWidth
|
|
||||||
var previewButtonsMoveX = 0
|
|
||||||
instance.requestAnimationFrame(function() {
|
|
||||||
// 设置菜单主体内容
|
|
||||||
instance.setStyle({
|
|
||||||
'transition': 'transform ' + duration,
|
|
||||||
'transform': 'translateX(' + buttonsWidth + 'px)',
|
|
||||||
'-webkit-transform': 'translateX(' + buttonsWidth + 'px)',
|
|
||||||
})
|
|
||||||
// 设置各个隐藏的按钮为展开的状态
|
|
||||||
for (var i = len - 1; i >= 0; i--) {
|
|
||||||
// 通过比例,得出元素自身该移动的距离
|
|
||||||
var translateX = state.buttons[i].width / state.buttonsWidth * buttonsWidth
|
|
||||||
// 最终移动的距离,是通过自身比例算出的距离,再加上在它之前所有按钮移动的距离之和
|
|
||||||
var realTranslateX = translateX + previewButtonsMoveX
|
|
||||||
buttons[i].setStyle({
|
|
||||||
// 在移动期间,需要加上动画效果
|
|
||||||
'transition': 'transform ' + duration,
|
|
||||||
'transform': 'translateX(' + realTranslateX + 'px)',
|
|
||||||
'-webkit-transform': 'translateX(' + realTranslateX + 'px)'
|
|
||||||
})
|
|
||||||
// 记录本按钮之前的所有按钮的移动距离之和
|
|
||||||
previewButtonsMoveX += translateX
|
|
||||||
}
|
|
||||||
})
|
|
||||||
setStatus('open', instance)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 标记菜单的当前状态,open-已经打开,close-已经关闭
|
|
||||||
function setStatus(status, instance) {
|
|
||||||
var state = instance.getState()
|
|
||||||
state.status = status
|
|
||||||
}
|
|
||||||
|
|
||||||
// 一次性收起滑动菜单
|
|
||||||
function closeSwipeAction(instance, ownerInstance) {
|
|
||||||
var state = instance.getState()
|
|
||||||
// 获取所有按钮的实例,需要通过它去设置按钮的位移
|
|
||||||
var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button')
|
|
||||||
var len = buttons.length
|
|
||||||
// 处理duration单位问题
|
|
||||||
const duration = getDuration(state.duration)
|
|
||||||
instance.requestAnimationFrame(function() {
|
|
||||||
// 设置菜单主体内容
|
|
||||||
instance.setStyle({
|
|
||||||
'transition': 'transform ' + duration,
|
|
||||||
'transform': 'translateX(0px)',
|
|
||||||
'-webkit-transform': 'translateX(0px)'
|
|
||||||
})
|
|
||||||
// 设置各个隐藏的按钮为收起的状态
|
|
||||||
for (var i = len - 1; i >= 0; i--) {
|
|
||||||
buttons[i].setStyle({
|
|
||||||
'transition': 'transform ' + duration,
|
|
||||||
'transform': 'translateX(0px)',
|
|
||||||
'-webkit-transform': 'translateX(0px)'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
setStatus('close', instance)
|
|
||||||
}
|
|
||||||
|
|
||||||
// show的状态发生变化
|
|
||||||
function showChange(newValue, oldValue, ownerInstance, instance) {
|
|
||||||
var state = instance.getState()
|
|
||||||
if (state.disabled) return
|
|
||||||
// 打开或关闭单元格
|
|
||||||
if (newValue) {
|
|
||||||
openSwipeAction(instance, ownerInstance)
|
|
||||||
} else {
|
|
||||||
closeSwipeAction(instance, ownerInstance)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 菜单尺寸发生变化
|
|
||||||
function sizeChange(newValue, oldValue, ownerInstance, instance) {
|
|
||||||
// wxs内的局部变量快照
|
|
||||||
var state = instance.getState()
|
|
||||||
state.disabled = newValue.disabled
|
|
||||||
state.duration = newValue.duration
|
|
||||||
state.show = newValue.show
|
|
||||||
state.threshold = newValue.threshold
|
|
||||||
state.buttons = newValue.buttons
|
|
||||||
|
|
||||||
var len = state.buttons.length
|
|
||||||
if (len) {
|
|
||||||
var buttonsWidth = 0
|
|
||||||
var buttons = newValue.buttons
|
|
||||||
for (var i = 0; i < len; i++) {
|
|
||||||
buttonsWidth += buttons[i].width
|
|
||||||
}
|
|
||||||
}
|
|
||||||
state.buttonsWidth = buttonsWidth
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
touchstart: touchstart,
|
|
||||||
touchmove: touchmove,
|
|
||||||
touchend: touchend,
|
|
||||||
sizeChange: sizeChange
|
|
||||||
}
|
|
@ -1,225 +0,0 @@
|
|||||||
/**
|
|
||||||
* 此为wxs模块,只支持APP-VUE,微信和QQ小程序以及H5平台
|
|
||||||
* wxs内部不支持es6语法,变量只能使用var定义,无法使用解构,箭头函数等特性
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 开始触摸
|
|
||||||
function touchstart(event, ownerInstance) {
|
|
||||||
// 触发事件的组件的ComponentDescriptor实例
|
|
||||||
var instance = event.instance
|
|
||||||
// wxs内的局部变量快照,此快照是属于整个组件的,在touchstart和touchmove事件中都能获取到相同的结果
|
|
||||||
var state = instance.getState()
|
|
||||||
if (state.disabled) return
|
|
||||||
var touches = event.touches
|
|
||||||
// 如果进行的是多指触控,不允许进行操作
|
|
||||||
if (touches && touches.length > 1) return
|
|
||||||
// 标识当前为滑动中状态
|
|
||||||
state.moving = true
|
|
||||||
// 记录触摸开始点的坐标值
|
|
||||||
state.startX = touches[0].pageX
|
|
||||||
state.startY = touches[0].pageY
|
|
||||||
|
|
||||||
ownerInstance.callMethod('closeOther')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 触摸滑动
|
|
||||||
function touchmove(event, ownerInstance) {
|
|
||||||
// 触发事件的组件的ComponentDescriptor实例
|
|
||||||
var instance = event.instance
|
|
||||||
// wxs内的局部变量快照
|
|
||||||
var state = instance.getState()
|
|
||||||
if (state.disabled || !state.moving) return
|
|
||||||
var touches = event.touches
|
|
||||||
var pageX = touches[0].pageX
|
|
||||||
var pageY = touches[0].pageY
|
|
||||||
var moveX = pageX - state.startX
|
|
||||||
var moveY = pageY - state.startY
|
|
||||||
var buttonsWidth = state.buttonsWidth
|
|
||||||
|
|
||||||
// 移动的X轴距离大于Y轴距离,也即终点与起点位置连线,与X轴夹角小于45度时,禁止页面滚动
|
|
||||||
if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > state.threshold) {
|
|
||||||
event.preventDefault && event.preventDefault()
|
|
||||||
event.stopPropagation && event.stopPropagation()
|
|
||||||
}
|
|
||||||
// 如果移动的X轴距离小于Y轴距离,也即终点位置与起点位置连线,与Y轴夹角小于45度时,认为是页面上下滑动,而不是左右滑动单元格
|
|
||||||
if (Math.abs(moveX) < Math.abs(moveY)) return
|
|
||||||
|
|
||||||
// 限制右滑的距离,不允许内容部分往右偏移,右滑会导致X轴偏移值大于0,以此做判断
|
|
||||||
// 此处不能直接return,因为滑动过程中会缺失某些关键点坐标,会导致错乱,最好的办法就是
|
|
||||||
// 在超出后,设置为0
|
|
||||||
if (state.status === 'open') {
|
|
||||||
// 在开启状态下,向左滑动,需忽略
|
|
||||||
if (moveX < 0) moveX = 0
|
|
||||||
// 想要收起菜单,最大能移动的距离为按钮的总宽度
|
|
||||||
if (moveX > buttonsWidth) moveX = buttonsWidth
|
|
||||||
// 如果是已经打开了的状态,向左滑动时,移动收起菜单
|
|
||||||
moveSwipeAction(-buttonsWidth + moveX, instance, ownerInstance)
|
|
||||||
} else {
|
|
||||||
// 关闭状态下,右滑动需忽略
|
|
||||||
if (moveX > 0) moveX = 0
|
|
||||||
// 滑动的距离不允许超过所有按钮的总宽度,此时只能是左滑,最终设置按钮的总宽度,同时为负数
|
|
||||||
if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth
|
|
||||||
// 只要是在滑过程中,就不断移动单元格内容部分,从而使隐藏的菜单显示出来
|
|
||||||
moveSwipeAction(moveX, instance, ownerInstance)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 触摸结束
|
|
||||||
function touchend(event, ownerInstance) {
|
|
||||||
// 触发事件的组件的ComponentDescriptor实例
|
|
||||||
var instance = event.instance
|
|
||||||
// wxs内的局部变量快照
|
|
||||||
var state = instance.getState()
|
|
||||||
if (!state.moving || state.disabled) return
|
|
||||||
var touches = event.changedTouches ? event.changedTouches[0] : {}
|
|
||||||
var pageX = touches.pageX
|
|
||||||
var pageY = touches.pageY
|
|
||||||
var moveX = pageX - state.startX
|
|
||||||
if (state.status === 'open') {
|
|
||||||
// 在展开的状态下,继续左滑,无需操作
|
|
||||||
if (moveX < 0) return
|
|
||||||
// 在开启状态下,点击一下内容区域,moveX为0,也即没有进行移动,这时执行收起菜单逻辑
|
|
||||||
if (moveX === 0) {
|
|
||||||
return closeSwipeAction(instance, ownerInstance)
|
|
||||||
}
|
|
||||||
// 在开启状态下,滑动距离小于阈值,则默认为不关闭,同时恢复原来的打开状态
|
|
||||||
if (Math.abs(moveX) < state.threshold) {
|
|
||||||
openSwipeAction(instance, ownerInstance)
|
|
||||||
} else {
|
|
||||||
// 如果滑动距离大于阈值,则执行收起逻辑
|
|
||||||
closeSwipeAction(instance, ownerInstance)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 在关闭的状态下,右滑,无需操作
|
|
||||||
if (moveX > 0) return
|
|
||||||
// 理由同上
|
|
||||||
if (Math.abs(moveX) < state.threshold) {
|
|
||||||
closeSwipeAction(instance, ownerInstance)
|
|
||||||
} else {
|
|
||||||
openSwipeAction(instance, ownerInstance)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取过渡时间
|
|
||||||
function getDuration(value) {
|
|
||||||
if (value.toString().indexOf('s') >= 0) return value
|
|
||||||
return value > 30 ? value + 'ms' : value + 's'
|
|
||||||
}
|
|
||||||
|
|
||||||
// 滑动结束时判断滑动的方向
|
|
||||||
function getMoveDirection(instance, ownerInstance) {
|
|
||||||
var state = instance.getState()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 移动滑动选择器内容区域,同时显示出其隐藏的菜单
|
|
||||||
function moveSwipeAction(moveX, instance, ownerInstance) {
|
|
||||||
var state = instance.getState()
|
|
||||||
// 获取所有按钮的实例,需要通过它去设置按钮的位移
|
|
||||||
var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button')
|
|
||||||
|
|
||||||
// 设置菜单内容部分的偏移
|
|
||||||
instance.requestAnimationFrame(function() {
|
|
||||||
instance.setStyle({
|
|
||||||
// 设置translateX的值
|
|
||||||
'transition': 'none',
|
|
||||||
transform: 'translateX(' + moveX + 'px)',
|
|
||||||
'-webkit-transform': 'translateX(' + moveX + 'px)'
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 一次性展开滑动菜单
|
|
||||||
function openSwipeAction(instance, ownerInstance) {
|
|
||||||
var state = instance.getState()
|
|
||||||
// 获取所有按钮的实例,需要通过它去设置按钮的位移
|
|
||||||
var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button')
|
|
||||||
// 处理duration单位问题
|
|
||||||
var duration = getDuration(state.duration)
|
|
||||||
// 展开过程中,是向左移动,所以X的偏移应该为负值
|
|
||||||
var buttonsWidth = -state.buttonsWidth
|
|
||||||
instance.requestAnimationFrame(function() {
|
|
||||||
// 设置菜单主体内容
|
|
||||||
instance.setStyle({
|
|
||||||
'transition': 'transform ' + duration,
|
|
||||||
'transform': 'translateX(' + buttonsWidth + 'px)',
|
|
||||||
'-webkit-transform': 'translateX(' + buttonsWidth + 'px)',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
setStatus('open', instance, ownerInstance)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 标记菜单的当前状态,open-已经打开,close-已经关闭
|
|
||||||
function setStatus(status, instance, ownerInstance) {
|
|
||||||
var state = instance.getState()
|
|
||||||
state.status = status
|
|
||||||
ownerInstance.callMethod('setState', status)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 一次性收起滑动菜单
|
|
||||||
function closeSwipeAction(instance, ownerInstance) {
|
|
||||||
var state = instance.getState()
|
|
||||||
// 获取所有按钮的实例,需要通过它去设置按钮的位移
|
|
||||||
var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button')
|
|
||||||
var len = buttons.length
|
|
||||||
// 处理duration单位问题
|
|
||||||
var duration = getDuration(state.duration)
|
|
||||||
instance.requestAnimationFrame(function() {
|
|
||||||
// 设置菜单主体内容
|
|
||||||
instance.setStyle({
|
|
||||||
'transition': 'transform ' + duration,
|
|
||||||
'transform': 'translateX(0px)',
|
|
||||||
'-webkit-transform': 'translateX(0px)'
|
|
||||||
})
|
|
||||||
// 设置各个隐藏的按钮为收起的状态
|
|
||||||
for (var i = len - 1; i >= 0; i--) {
|
|
||||||
buttons[i].setStyle({
|
|
||||||
'transition': 'transform ' + duration,
|
|
||||||
'transform': 'translateX(0px)',
|
|
||||||
'-webkit-transform': 'translateX(0px)'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
setStatus('close', instance, ownerInstance)
|
|
||||||
}
|
|
||||||
|
|
||||||
// status的状态发生变化
|
|
||||||
function statusChange(newValue, oldValue, ownerInstance, instance) {
|
|
||||||
var state = instance.getState()
|
|
||||||
if (state.disabled) return
|
|
||||||
// 打开或关闭单元格
|
|
||||||
if (newValue === 'close' && state.status === 'open') {
|
|
||||||
closeSwipeAction(instance, ownerInstance)
|
|
||||||
} else if(newValue === 'open' && state.status === 'close') {
|
|
||||||
openSwipeAction(instance, ownerInstance)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 菜单尺寸发生变化
|
|
||||||
function sizeChange(newValue, oldValue, ownerInstance, instance) {
|
|
||||||
// wxs内的局部变量快照
|
|
||||||
var state = instance.getState()
|
|
||||||
state.disabled = newValue.disabled
|
|
||||||
state.duration = newValue.duration
|
|
||||||
state.show = newValue.show
|
|
||||||
state.threshold = newValue.threshold
|
|
||||||
state.buttons = newValue.buttons
|
|
||||||
|
|
||||||
if (state.buttons) {
|
|
||||||
var len = state.buttons.length
|
|
||||||
var buttonsWidth = 0
|
|
||||||
var buttons = newValue.buttons
|
|
||||||
for (var i = 0; i < len; i++) {
|
|
||||||
buttonsWidth += buttons[i].width
|
|
||||||
}
|
|
||||||
}
|
|
||||||
state.buttonsWidth = buttonsWidth
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
touchstart: touchstart,
|
|
||||||
touchmove: touchmove,
|
|
||||||
touchend: touchend,
|
|
||||||
sizeChange: sizeChange,
|
|
||||||
statusChange: statusChange
|
|
||||||
}
|
|
@ -1,264 +0,0 @@
|
|||||||
// nvue操作dom的库,用于获取dom的尺寸信息
|
|
||||||
const dom = uni.requireNativePlugin('dom')
|
|
||||||
// nvue中用于操作元素动画的库,类似于uni.animation,只不过uni.animation不能用于nvue
|
|
||||||
const animation = uni.requireNativePlugin('animation')
|
|
||||||
import { sleep } from '@/uni_modules/uv-ui-tools/libs/function/index.js'
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// 是否滑动中
|
|
||||||
moving: false,
|
|
||||||
// 状态,open-打开状态,close-关闭状态
|
|
||||||
status: 'close',
|
|
||||||
// 开始触摸点的X和Y轴坐标
|
|
||||||
startX: 0,
|
|
||||||
startY: 0,
|
|
||||||
// 所有隐藏按钮的尺寸信息数组
|
|
||||||
buttons: [],
|
|
||||||
// 所有按钮的总宽度
|
|
||||||
buttonsWidth: 0,
|
|
||||||
// 记录上一次移动的位置值
|
|
||||||
moveX: 0,
|
|
||||||
// 记录上一次滑动的位置,用于前后两次做对比,如果移动的距离小于某一阈值,则认为前后之间没有移动,为了解决可能存在的通信阻塞问题
|
|
||||||
lastX: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
// 获取过渡时间
|
|
||||||
getDuratin() {
|
|
||||||
let duration = String(this.duration)
|
|
||||||
// 如果ms为单位,返回ms的数值部分
|
|
||||||
if (duration.indexOf('ms') >= 0) return parseInt(duration)
|
|
||||||
// 如果s为单位,为了得到ms的数值,需要乘以1000
|
|
||||||
if (duration.indexOf('s') >= 0) return parseInt(duration) * 1000
|
|
||||||
// 如果值传了数值,且小于30,认为是s单位
|
|
||||||
duration = Number(duration)
|
|
||||||
return duration < 30 ? duration * 1000 : duration
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
show: {
|
|
||||||
immediate: true,
|
|
||||||
handler(n) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
sleep(20).then(() => {
|
|
||||||
this.queryRect()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
close() {
|
|
||||||
this.closeSwipeAction()
|
|
||||||
},
|
|
||||||
// 触摸单元格
|
|
||||||
touchstart(event) {
|
|
||||||
if (this.disabled) return
|
|
||||||
this.closeOther()
|
|
||||||
const { touches } = event
|
|
||||||
// 记录触摸开始点的坐标值
|
|
||||||
this.startX = touches[0].pageX
|
|
||||||
this.startY = touches[0].pageY
|
|
||||||
},
|
|
||||||
// // 触摸滑动
|
|
||||||
touchmove(event) {
|
|
||||||
if (this.disabled) return
|
|
||||||
const { touches } = event
|
|
||||||
const { pageX } = touches[0]
|
|
||||||
const { pageY } = touches[0]
|
|
||||||
let moveX = pageX - this.startX
|
|
||||||
const moveY = pageY - this.startY
|
|
||||||
const { buttonsWidth } = this
|
|
||||||
const len = this.buttons.length
|
|
||||||
|
|
||||||
// 判断前后两次的移动距离,如果小于一定值,则不进行移动处理
|
|
||||||
if (Math.abs(pageX - this.lastX) < 0.3) return
|
|
||||||
this.lastX = pageX
|
|
||||||
|
|
||||||
// 移动的X轴距离大于Y轴距离,也即终点与起点位置连线,与X轴夹角小于45度时,禁止页面滚动
|
|
||||||
if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > this.threshold) {
|
|
||||||
event.stopPropagation()
|
|
||||||
}
|
|
||||||
// 如果移动的X轴距离小于Y轴距离,也即终点位置与起点位置连线,与Y轴夹角小于45度时,认为是页面上下滑动,而不是左右滑动单元格
|
|
||||||
if (Math.abs(moveX) < Math.abs(moveY)) return
|
|
||||||
|
|
||||||
// 限制右滑的距离,不允许内容部分往右偏移,右滑会导致X轴偏移值大于0,以此做判断
|
|
||||||
// 此处不能直接return,因为滑动过程中会缺失某些关键点坐标,会导致错乱,最好的办法就是
|
|
||||||
// 在超出后,设置为0
|
|
||||||
if (this.status === 'open') {
|
|
||||||
// 在开启状态下,向左滑动,需忽略
|
|
||||||
if (moveX < 0) moveX = 0
|
|
||||||
// 想要收起菜单,最大能移动的距离为按钮的总宽度
|
|
||||||
if (moveX > buttonsWidth) moveX = buttonsWidth
|
|
||||||
// 如果是已经打开了的状态,向左滑动时,移动收起菜单
|
|
||||||
this.moveSwipeAction(-buttonsWidth + moveX)
|
|
||||||
} else {
|
|
||||||
// 关闭状态下,右滑动需忽略
|
|
||||||
if (moveX > 0) moveX = 0
|
|
||||||
// 滑动的距离不允许超过所有按钮的总宽度,此时只能是左滑,最终设置按钮的总宽度,同时为负数
|
|
||||||
if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth
|
|
||||||
// 只要是在滑过程中,就不断移动菜单的内容部分,从而使隐藏的菜单显示出来
|
|
||||||
this.moveSwipeAction(moveX)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 单元格结束触摸
|
|
||||||
touchend(event) {
|
|
||||||
if (this.disabled) return
|
|
||||||
const touches = event.changedTouches ? event.changedTouches[0] : {}
|
|
||||||
const { pageX } = touches
|
|
||||||
const { pageY } = touches
|
|
||||||
const { buttonsWidth } = this
|
|
||||||
this.moveX = pageX - this.startX
|
|
||||||
if (this.status === 'open') {
|
|
||||||
// 在展开的状态下,继续左滑,无需操作
|
|
||||||
if (this.moveX < 0) this.moveX = 0
|
|
||||||
if (this.moveX > buttonsWidth) this.moveX = buttonsWidth
|
|
||||||
// 在开启状态下,点击一下内容区域,moveX为0,也即没有进行移动,这时执行收起菜单逻辑
|
|
||||||
if (this.moveX === 0) {
|
|
||||||
return this.closeSwipeAction()
|
|
||||||
}
|
|
||||||
// 在开启状态下,滑动距离小于阈值,则默认为不关闭,同时恢复原来的打开状态
|
|
||||||
if (Math.abs(this.moveX) < this.threshold) {
|
|
||||||
this.openSwipeAction()
|
|
||||||
} else {
|
|
||||||
// 如果滑动距离大于阈值,则执行收起逻辑
|
|
||||||
this.closeSwipeAction()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 在关闭的状态下,右滑,无需操作
|
|
||||||
if (this.moveX >= 0) this.moveX = 0
|
|
||||||
if (this.moveX <= -buttonsWidth) this.moveX = -buttonsWidth
|
|
||||||
// 理由同上
|
|
||||||
if (Math.abs(this.moveX) < this.threshold) {
|
|
||||||
this.closeSwipeAction()
|
|
||||||
} else {
|
|
||||||
this.openSwipeAction()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 移动滑动选择器内容区域,同时显示出其隐藏的菜单
|
|
||||||
moveSwipeAction(moveX) {
|
|
||||||
if (this.moving) return
|
|
||||||
this.moving = true
|
|
||||||
|
|
||||||
let previewButtonsMoveX = 0
|
|
||||||
const len = this.buttons.length
|
|
||||||
animation.transition(this.$refs['uv-swipe-action-item__content'].ref, {
|
|
||||||
styles: {
|
|
||||||
transform: `translateX(${moveX}px)`
|
|
||||||
},
|
|
||||||
timingFunction: 'linear'
|
|
||||||
}, () => {
|
|
||||||
this.moving = false
|
|
||||||
})
|
|
||||||
// 按钮的组的长度
|
|
||||||
for (let i = len - 1; i >= 0; i--) {
|
|
||||||
const buttonRef = this.$refs[`uv-swipe-action-item__right__button-${i}`][0].ref
|
|
||||||
// 通过比例,得出元素自身该移动的距离
|
|
||||||
const translateX = this.buttons[i].width / this.buttonsWidth * moveX
|
|
||||||
// 最终移动的距离,是通过自身比例算出的距离,再加上在它之前所有按钮移动的距离之和
|
|
||||||
const realTranslateX = translateX + previewButtonsMoveX
|
|
||||||
animation.transition(buttonRef, {
|
|
||||||
styles: {
|
|
||||||
transform: `translateX(${realTranslateX}px)`
|
|
||||||
},
|
|
||||||
duration: 0,
|
|
||||||
delay: 0,
|
|
||||||
timingFunction: 'linear'
|
|
||||||
}, () => {})
|
|
||||||
// 记录本按钮之前的所有按钮的移动距离之和
|
|
||||||
previewButtonsMoveX += translateX
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 关闭菜单
|
|
||||||
closeSwipeAction() {
|
|
||||||
if (this.status === 'close') return
|
|
||||||
this.moving = true
|
|
||||||
const { buttonsWidth } = this
|
|
||||||
animation.transition(this.$refs['uv-swipe-action-item__content'].ref, {
|
|
||||||
styles: {
|
|
||||||
transform: 'translateX(0px)'
|
|
||||||
},
|
|
||||||
duration: this.getDuratin,
|
|
||||||
timingFunction: 'ease-in-out'
|
|
||||||
}, () => {
|
|
||||||
this.status = 'close'
|
|
||||||
this.moving = false
|
|
||||||
this.closeHandler()
|
|
||||||
})
|
|
||||||
// 按钮的组的长度
|
|
||||||
const len = this.buttons.length
|
|
||||||
for (let i = len - 1; i >= 0; i--) {
|
|
||||||
const buttonRef = this.$refs[`uv-swipe-action-item__right__button-${i}`][0].ref
|
|
||||||
// 如果不满足边界条件,返回
|
|
||||||
if (this.buttons.length === 0 || !this.buttons[i] || !this.buttons[i].width) return
|
|
||||||
|
|
||||||
animation.transition(buttonRef, {
|
|
||||||
styles: {
|
|
||||||
transform: 'translateX(0px)'
|
|
||||||
},
|
|
||||||
duration: this.getDuratin,
|
|
||||||
timingFunction: 'ease-in-out'
|
|
||||||
}, () => {})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 打开菜单
|
|
||||||
openSwipeAction() {
|
|
||||||
if (this.status === 'open') return
|
|
||||||
this.moving = true
|
|
||||||
const buttonsWidth = -this.buttonsWidth
|
|
||||||
let previewButtonsMoveX = 0
|
|
||||||
animation.transition(this.$refs['uv-swipe-action-item__content'].ref, {
|
|
||||||
styles: {
|
|
||||||
transform: `translateX(${buttonsWidth}px)`
|
|
||||||
},
|
|
||||||
duration: this.getDuratin,
|
|
||||||
timingFunction: 'ease-in-out'
|
|
||||||
}, () => {
|
|
||||||
this.status = 'open'
|
|
||||||
this.moving = false
|
|
||||||
this.openHandler()
|
|
||||||
})
|
|
||||||
// 按钮的组的长度
|
|
||||||
const len = this.buttons.length
|
|
||||||
for (let i = len - 1; i >= 0; i--) {
|
|
||||||
const buttonRef = this.$refs[`uv-swipe-action-item__right__button-${i}`][0].ref
|
|
||||||
// 如果不满足边界条件,返回
|
|
||||||
if (this.buttons.length === 0 || !this.buttons[i] || !this.buttons[i].width) return
|
|
||||||
// 通过比例,得出元素自身该移动的距离
|
|
||||||
const translateX = this.buttons[i].width / this.buttonsWidth * buttonsWidth
|
|
||||||
// 最终移动的距离,是通过自身比例算出的距离,再加上在它之前所有按钮移动的距离之和
|
|
||||||
const realTranslateX = translateX + previewButtonsMoveX
|
|
||||||
animation.transition(buttonRef, {
|
|
||||||
styles: {
|
|
||||||
transform: `translateX(${realTranslateX}px)`
|
|
||||||
},
|
|
||||||
duration: this.getDuratin,
|
|
||||||
timingFunction: 'ease-in-out'
|
|
||||||
}, () => {})
|
|
||||||
previewButtonsMoveX += translateX
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 查询按钮节点信息
|
|
||||||
queryRect() {
|
|
||||||
// 历遍所有按钮数组,通过getRectByDom返回一个promise
|
|
||||||
const promiseAll = this.rightOptions.map((item, index) => this.getRectByDom(this.$refs[`uv-swipe-action-item__right__button-${index}`][0]))
|
|
||||||
// 通过promise.all方法,让所有按钮的查询结果返回一个数组的形式
|
|
||||||
Promise.all(promiseAll).then((sizes) => {
|
|
||||||
this.buttons = sizes
|
|
||||||
// 计算所有按钮总宽度
|
|
||||||
this.buttonsWidth = sizes.reduce((sum, cur) => sum + cur.width, 0)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 通过nvue的dom模块,查询节点信息
|
|
||||||
getRectByDom(ref) {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
dom.getComponentRect(ref, (res) => {
|
|
||||||
resolve(res.size)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,182 +0,0 @@
|
|||||||
// nvue操作dom的库,用于获取dom的尺寸信息
|
|
||||||
const dom = uni.requireNativePlugin('dom');
|
|
||||||
const bindingX = uni.requireNativePlugin('bindingx');
|
|
||||||
const animation = uni.requireNativePlugin('animation');
|
|
||||||
import { getDuration, getPx } from '@/uni_modules/uv-ui-tools/libs/function/index.js'
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// 所有按钮的总宽度
|
|
||||||
buttonsWidth: 0,
|
|
||||||
// 是否正在移动中
|
|
||||||
moving: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
// 获取过渡时间
|
|
||||||
getDuratin() {
|
|
||||||
let duration = String(this.duration)
|
|
||||||
// 如果ms为单位,返回ms的数值部分
|
|
||||||
if (duration.indexOf('ms') >= 0) return parseInt(duration)
|
|
||||||
// 如果s为单位,为了得到ms的数值,需要乘以1000
|
|
||||||
if (duration.indexOf('s') >= 0) return parseInt(duration) * 1000
|
|
||||||
// 如果值传了数值,且小于30,认为是s单位
|
|
||||||
duration = Number(duration)
|
|
||||||
return duration < 30 ? duration * 1000 : duration
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
show(n) {
|
|
||||||
if(n) {
|
|
||||||
this.moveCellByAnimation('open')
|
|
||||||
} else {
|
|
||||||
this.moveCellByAnimation('close')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
setTimeout(()=>{
|
|
||||||
this.initialize()
|
|
||||||
},20)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initialize() {
|
|
||||||
this.queryRect()
|
|
||||||
},
|
|
||||||
// 关闭单元格,用于打开一个,自动关闭其他单元格的场景
|
|
||||||
closeHandler() {
|
|
||||||
if(this.status === 'open') {
|
|
||||||
// 如果在打开状态下,进行点击的话,直接关闭单元格
|
|
||||||
return this.moveCellByAnimation('close') && this.unbindBindingX()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 点击单元格
|
|
||||||
clickHandler() {
|
|
||||||
// 如果在移动中被点击,进行忽略
|
|
||||||
if(this.moving) return
|
|
||||||
// 尝试关闭其他打开的单元格
|
|
||||||
this.parent && this.parent.closeOther(this)
|
|
||||||
if(this.status === 'open') {
|
|
||||||
// 如果在打开状态下,进行点击的话,直接关闭单元格
|
|
||||||
return this.moveCellByAnimation('close') && this.unbindBindingX()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 滑动单元格
|
|
||||||
onTouchstart(e) {
|
|
||||||
// 如果当前正在移动中,或者disabled状态,则返回
|
|
||||||
if(this.moving || this.disabled) {
|
|
||||||
return this.unbindBindingX()
|
|
||||||
}
|
|
||||||
if(this.status === 'open') {
|
|
||||||
// 如果在打开状态下,进行点击的话,直接关闭单元格
|
|
||||||
return this.moveCellByAnimation('close') && this.unbindBindingX()
|
|
||||||
}
|
|
||||||
// 特殊情况下,e可能不为一个对象
|
|
||||||
e?.stopPropagation && e.stopPropagation()
|
|
||||||
e?.preventDefault && e.preventDefault()
|
|
||||||
this.moving = true
|
|
||||||
// 获取元素ref
|
|
||||||
const content = this.getContentRef()
|
|
||||||
let expression = `min(max(${-this.buttonsWidth}, x), 0)`
|
|
||||||
// 尝试关闭其他打开的单元格
|
|
||||||
this.parent && this.parent.closeOther(this)
|
|
||||||
// 阿里为了KPI而开源的BindingX
|
|
||||||
this.panEvent = bindingX.bind({
|
|
||||||
anchor: content,
|
|
||||||
eventType: 'pan',
|
|
||||||
props: [{
|
|
||||||
element: content,
|
|
||||||
// 绑定width属性,设置其宽度值
|
|
||||||
property: 'transform.translateX',
|
|
||||||
expression
|
|
||||||
}]
|
|
||||||
}, (res) => {
|
|
||||||
this.moving = false
|
|
||||||
if (res.state === 'end' || res.state === 'exit') {
|
|
||||||
const deltaX = res.deltaX
|
|
||||||
if(deltaX <= -this.buttonsWidth || deltaX >= 0) {
|
|
||||||
// 如果触摸滑动的过程中,大于单元格的总宽度,或者大于0,意味着已经动过滑动达到了打开或者关闭的状态
|
|
||||||
// 这里直接进行状态的标记
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.status = deltaX <= -this.buttonsWidth ? 'open' : 'close'
|
|
||||||
})
|
|
||||||
} else if(Math.abs(deltaX) > getPx(this.threshold)) {
|
|
||||||
// 在移动大于阈值、并且小于总按钮宽度时,进行自动打开或者关闭
|
|
||||||
// 移动距离大于0时,意味着需要关闭状态
|
|
||||||
if(Math.abs(deltaX) < this.buttonsWidth) {
|
|
||||||
this.moveCellByAnimation(deltaX > 0 ? 'close' : 'open')
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 在小于阈值时,进行关闭操作(如果在打开状态下,将不会执行bindingX)
|
|
||||||
this.moveCellByAnimation('close')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 释放bindingX
|
|
||||||
unbindBindingX() {
|
|
||||||
// 释放上一次的资源
|
|
||||||
if (this?.panEvent?.token != 0) {
|
|
||||||
bindingX.unbind({
|
|
||||||
token: this.panEvent?.token,
|
|
||||||
// pan为手势事件
|
|
||||||
eventType: 'pan'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 查询按钮节点信息
|
|
||||||
queryRect() {
|
|
||||||
// 历遍所有按钮数组,通过getRectByDom返回一个promise
|
|
||||||
const promiseAll = this.options.map(async(item, index) => {
|
|
||||||
return await this.getRectByDom(this.$refs[`uv-swipe-action-item__right__button-${index}`][0])
|
|
||||||
})
|
|
||||||
// 通过promise.all方法,让所有按钮的查询结果返回一个数组的形式
|
|
||||||
Promise.all(promiseAll).then(sizes => {
|
|
||||||
this.buttons = sizes
|
|
||||||
// 计算所有按钮总宽度
|
|
||||||
this.buttonsWidth = sizes.reduce((sum, cur) => sum + cur.width, 0)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 通过nvue的dom模块,查询节点信息
|
|
||||||
getRectByDom(ref) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
dom.getComponentRect(ref, res => {
|
|
||||||
resolve(res.size)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 移动单元格到左边或者右边尽头
|
|
||||||
moveCellByAnimation(status = 'open') {
|
|
||||||
if(this.moving) return
|
|
||||||
// 标识当前状态
|
|
||||||
this.moveing = true
|
|
||||||
const content = this.getContentRef()
|
|
||||||
const x = status === 'open' ? -this.buttonsWidth : 0
|
|
||||||
animation.transition(content, {
|
|
||||||
styles: {
|
|
||||||
transform: `translateX(${x}px)`,
|
|
||||||
},
|
|
||||||
duration: getDuration(this.duration, false),
|
|
||||||
timingFunction: 'ease-in-out'
|
|
||||||
}, () => {
|
|
||||||
this.moving = false
|
|
||||||
this.status = status
|
|
||||||
this.unbindBindingX()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 获取元素ref
|
|
||||||
getContentRef() {
|
|
||||||
return this.$refs['uv-swipe-action-item__content'].ref
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// #ifdef VUE2
|
|
||||||
beforeDestroy() {
|
|
||||||
this.unbindBindingX()
|
|
||||||
},
|
|
||||||
// #endif
|
|
||||||
// #ifdef VUE3
|
|
||||||
unmounted() {
|
|
||||||
this.unbindBindingX()
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
export default {
|
|
||||||
props: {
|
|
||||||
// 控制打开或者关闭
|
|
||||||
show: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 标识符,如果是v-for,可用index索引值
|
|
||||||
name: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 是否禁用
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 是否自动关闭其他swipe按钮组
|
|
||||||
autoClose: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
// 滑动距离阈值,只有大于此值,才被认为是要打开菜单
|
|
||||||
threshold: {
|
|
||||||
type: Number,
|
|
||||||
default: 20
|
|
||||||
},
|
|
||||||
// 右侧按钮内容
|
|
||||||
options: {
|
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
},
|
|
||||||
// 动画过渡时间,单位ms
|
|
||||||
duration: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 300
|
|
||||||
},
|
|
||||||
...uni.$uv?.props?.swipeActionItem
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,200 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="uv-swipe-action-item" ref="uv-swipe-action-item">
|
|
||||||
<view class="uv-swipe-action-item__right">
|
|
||||||
<slot name="button">
|
|
||||||
<view v-for="(item,index) in options" :key="index" class="uv-swipe-action-item__right__button"
|
|
||||||
:ref="`uv-swipe-action-item__right__button-${index}`" :style="[{
|
|
||||||
alignItems: item.style && item.style.borderRadius ? 'center' : 'stretch'
|
|
||||||
}]" @tap="buttonClickHandler(item, index)">
|
|
||||||
<view class="uv-swipe-action-item__right__button__wrapper" :style="[{
|
|
||||||
backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
|
|
||||||
borderRadius: item.style && item.style.borderRadius ? item.style.borderRadius : '0',
|
|
||||||
padding: item.style && item.style.borderRadius ? '0' : '0 15px',
|
|
||||||
}, item.style]">
|
|
||||||
<uv-icon v-if="item.icon" :name="item.icon"
|
|
||||||
:color="item.style && item.style.color ? item.style.color : '#ffffff'"
|
|
||||||
:size="item.iconSize ? $uv.addUnit(item.iconSize) : item.style && item.style.fontSize ? $uv.getPx(item.style.fontSize) * 1.2 : 17"
|
|
||||||
:customStyle="{
|
|
||||||
marginRight: item.text ? '2px' : 0
|
|
||||||
}"></uv-icon>
|
|
||||||
<text v-if="item.text" class="uv-swipe-action-item__right__button__wrapper__text uv-line-1"
|
|
||||||
:style="[{
|
|
||||||
color: item.style && item.style.color ? item.style.color : '#ffffff',
|
|
||||||
fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px',
|
|
||||||
lineHeight: item.style && item.style.fontSize ? item.style.fontSize : '16px',
|
|
||||||
}]">{{ item.text }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</slot>
|
|
||||||
</view>
|
|
||||||
<!-- #ifndef APP-NVUE -->
|
|
||||||
<view class="uv-swipe-action-item__content" @touchstart="wxs.touchstart" @touchmove="wxs.touchmove"
|
|
||||||
@touchend="wxs.touchend" :status="status" :change:status="wxs.statusChange" :size="size"
|
|
||||||
:change:size="wxs.sizeChange">
|
|
||||||
<!-- #endif -->
|
|
||||||
<!-- #ifdef APP-NVUE -->
|
|
||||||
<view class="uv-swipe-action-item__content" ref="uv-swipe-action-item__content" @panstart="onTouchstart"
|
|
||||||
@tap="clickHandler">
|
|
||||||
<!-- #endif -->
|
|
||||||
<slot />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<!-- #ifdef APP-VUE || MP-WEIXIN || H5 || MP-QQ -->
|
|
||||||
<script src="./index.wxs" module="wxs" lang="wxs"></script>
|
|
||||||
<!-- #endif -->
|
|
||||||
<script>
|
|
||||||
import touch from '@/uni_modules/uv-ui-tools/libs/mixin/touch.js'
|
|
||||||
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
|
||||||
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
|
||||||
import props from './props.js';
|
|
||||||
// #ifdef APP-NVUE
|
|
||||||
import nvue from './nvue.js';
|
|
||||||
// #endif
|
|
||||||
// #ifdef APP-VUE || MP-WEIXIN || H5 || MP-QQ
|
|
||||||
import wxs from './wxs.js';
|
|
||||||
// #endif
|
|
||||||
/**
|
|
||||||
* SwipeActionItem 滑动单元格子组件
|
|
||||||
* @description 该组件一般用于左滑唤出操作菜单的场景,用的最多的是左滑删除操作
|
|
||||||
* @tutorial https://www.uvui.cn/components/swipeAction.html
|
|
||||||
* @property {Boolean} show 控制打开或者关闭(默认 false )
|
|
||||||
* @property {String | Number} index 标识符,如果是v-for,可用index索引
|
|
||||||
* @property {Boolean} disabled 是否禁用(默认 false )
|
|
||||||
* @property {Boolean} autoClose 是否自动关闭其他swipe按钮组(默认 true )
|
|
||||||
* @property {Number} threshold 滑动距离阈值,只有大于此值,才被认为是要打开菜单(默认 30 )
|
|
||||||
* @property {Array} options 右侧按钮内容
|
|
||||||
* @property {String | Number} duration 动画过渡时间,单位ms(默认 350 )
|
|
||||||
* @event {Function(index)} open 组件打开时触发
|
|
||||||
* @event {Function(index)} close 组件关闭时触发
|
|
||||||
* @example <uv-swipe-action><uv-swipe-action-item :options="options1" ></uv-swipe-action-item></uv-swipe-action>
|
|
||||||
*/
|
|
||||||
export default {
|
|
||||||
name: 'uv-swipe-action-item',
|
|
||||||
emits: ['click'],
|
|
||||||
// #ifndef APP-NVUE
|
|
||||||
mixins: [mpMixin, mixin, props, touch],
|
|
||||||
// #endif
|
|
||||||
// #ifdef APP-NVUE
|
|
||||||
mixins: [mpMixin, mixin, props, nvue , touch],
|
|
||||||
// #endif
|
|
||||||
// #ifdef APP-VUE || MP-WEIXIN || H5 || MP-QQ
|
|
||||||
mixins: [mpMixin, mixin, props, touch, wxs],
|
|
||||||
// #endif
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// 按钮的尺寸信息
|
|
||||||
size: {},
|
|
||||||
// 父组件uv-swipe-action的参数
|
|
||||||
parentData: {
|
|
||||||
autoClose: true,
|
|
||||||
},
|
|
||||||
// 当前状态,open-打开,close-关闭
|
|
||||||
status: 'close',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
// 由于wxs无法直接读取外部的值,需要在外部值变化时,重新执行赋值逻辑
|
|
||||||
wxsInit(newValue, oldValue) {
|
|
||||||
this.queryRect()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
wxsInit() {
|
|
||||||
return [this.disabled, this.autoClose, this.threshold, this.options, this.duration]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
// #ifdef MP-TOUTIAO
|
|
||||||
this.$uv.error('抖音小程序暂不支持wxs,故该组件暂不支持抖音小程序');
|
|
||||||
// #endif
|
|
||||||
this.init()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
init() {
|
|
||||||
// 初始化父组件数据
|
|
||||||
this.updateParentData()
|
|
||||||
// #ifndef APP-NVUE
|
|
||||||
this.$uv.sleep().then(() => {
|
|
||||||
this.queryRect()
|
|
||||||
})
|
|
||||||
// #endif
|
|
||||||
},
|
|
||||||
updateParentData() {
|
|
||||||
// 此方法在mixin中
|
|
||||||
this.getParentData('uv-swipe-action')
|
|
||||||
},
|
|
||||||
// #ifndef APP-NVUE
|
|
||||||
// 查询节点
|
|
||||||
queryRect() {
|
|
||||||
this.$uvGetRect('.uv-swipe-action-item__right__button', true).then(buttons => {
|
|
||||||
this.size = {
|
|
||||||
buttons,
|
|
||||||
show: this.show,
|
|
||||||
disabled: this.disabled,
|
|
||||||
threshold: this.threshold,
|
|
||||||
duration: this.duration
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// #endif
|
|
||||||
// 按钮被点击
|
|
||||||
buttonClickHandler(item, index) {
|
|
||||||
this.$emit('click', {
|
|
||||||
index,
|
|
||||||
name: this.name
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
$show-lines: 1;
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/variable.scss';
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
|
||||||
|
|
||||||
.uv-swipe-action-item {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
/* #ifndef APP-NVUE || MP-WEIXIN */
|
|
||||||
touch-action: pan-y;
|
|
||||||
/* #endif */
|
|
||||||
|
|
||||||
&__content {
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__right {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
@include flex;
|
|
||||||
|
|
||||||
&__button {
|
|
||||||
@include flex;
|
|
||||||
justify-content: center;
|
|
||||||
overflow: hidden;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
&__wrapper {
|
|
||||||
@include flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 0 15px;
|
|
||||||
|
|
||||||
&__text {
|
|
||||||
@include flex;
|
|
||||||
align-items: center;
|
|
||||||
color: #FFFFFF;
|
|
||||||
font-size: 15px;
|
|
||||||
text-align: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,15 +0,0 @@
|
|||||||
export default {
|
|
||||||
methods: {
|
|
||||||
// 关闭时执行
|
|
||||||
closeHandler() {
|
|
||||||
this.status = 'close'
|
|
||||||
},
|
|
||||||
setState(status) {
|
|
||||||
this.status = status
|
|
||||||
},
|
|
||||||
closeOther() {
|
|
||||||
// 尝试关闭其他打开的单元格
|
|
||||||
this.parent && this.parent.closeOther(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
export default {
|
|
||||||
props: {
|
|
||||||
// 是否自动关闭其他swipe按钮组
|
|
||||||
autoClose: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
...uni.$uv?.props?.swipeAction
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="uv-swipe-action">
|
|
||||||
<slot></slot>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
|
||||||
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
|
||||||
import props from './props.js';
|
|
||||||
/**
|
|
||||||
* SwipeAction 滑动单元格
|
|
||||||
* @description 该组件一般用于左滑唤出操作菜单的场景,用的最多的是左滑删除操作
|
|
||||||
* @tutorial https://www.uvui.cn/components/swipeAction.html
|
|
||||||
* @property {Boolean} autoClose 是否自动关闭其他swipe按钮组
|
|
||||||
* @event {Function(index)} click 点击组件时触发
|
|
||||||
* @example <uv-swipe-action><uv-swipe-action-item :rightOptions="options1" ></uv-swipe-action-item></uv-swipe-action>
|
|
||||||
*/
|
|
||||||
export default {
|
|
||||||
name: 'uv-swipe-action',
|
|
||||||
mixins: [mpMixin, mixin, props],
|
|
||||||
data() {
|
|
||||||
return {}
|
|
||||||
},
|
|
||||||
provide() {
|
|
||||||
return {
|
|
||||||
swipeAction: this
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
// 这里computed的变量,都是子组件uv-swipe-action-item需要用到的,由于头条小程序的兼容性差异,子组件无法实时监听父组件参数的变化
|
|
||||||
// 所以需要手动通知子组件,这里返回一个parentData变量,供watch监听,在其中去通知每一个子组件重新从父组件(uv-swipe-action-item)
|
|
||||||
// 拉取父组件新的变化后的参数
|
|
||||||
parentData() {
|
|
||||||
return [this.autoClose]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
// 当父组件需要子组件需要共享的参数发生了变化,手动通知子组件
|
|
||||||
parentData() {
|
|
||||||
if (this.children.length) {
|
|
||||||
this.children.map(child => {
|
|
||||||
// 判断子组件(uv-swipe-action-item)如果有updateParentData方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
|
|
||||||
typeof(child.updateParentData) === 'function' && child.updateParentData()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.children = []
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
closeOther(child) {
|
|
||||||
if (this.autoClose) {
|
|
||||||
// 历遍所有的单元格,找出非当前操作中的单元格,进行关闭
|
|
||||||
this.children.map((item, index) => {
|
|
||||||
if (child !== item) {
|
|
||||||
item.closeHandler()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
@ -1,88 +0,0 @@
|
|||||||
{
|
|
||||||
"id": "uv-swipe-action",
|
|
||||||
"displayName": "uv-swipe-action 滑动单元格 全面兼容小程序、nvue、vue2、vue3等多端",
|
|
||||||
"version": "1.0.4",
|
|
||||||
"description": "滑动单元格组件一般用于左滑唤出操作菜单的场景,用的最多的是左滑删除操作。",
|
|
||||||
"keywords": [
|
|
||||||
"uv-swipe-action",
|
|
||||||
"uvui",
|
|
||||||
"uv-ui",
|
|
||||||
"swipe-action",
|
|
||||||
"滑动单元格"
|
|
||||||
],
|
|
||||||
"repository": "",
|
|
||||||
"engines": {
|
|
||||||
"HBuilderX": "^3.1.0"
|
|
||||||
},
|
|
||||||
"dcloudext": {
|
|
||||||
"type": "component-vue",
|
|
||||||
"sale": {
|
|
||||||
"regular": {
|
|
||||||
"price": "0.00"
|
|
||||||
},
|
|
||||||
"sourcecode": {
|
|
||||||
"price": "0.00"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"contact": {
|
|
||||||
"qq": ""
|
|
||||||
},
|
|
||||||
"declaration": {
|
|
||||||
"ads": "无",
|
|
||||||
"data": "插件不采集任何数据",
|
|
||||||
"permissions": "无"
|
|
||||||
},
|
|
||||||
"npmurl": ""
|
|
||||||
},
|
|
||||||
"uni_modules": {
|
|
||||||
"dependencies": [
|
|
||||||
"uv-ui-tools",
|
|
||||||
"uv-icon"
|
|
||||||
],
|
|
||||||
"encrypt": [],
|
|
||||||
"platforms": {
|
|
||||||
"cloud": {
|
|
||||||
"tcb": "y",
|
|
||||||
"aliyun": "y"
|
|
||||||
},
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
## SwipeAction 滑动单元格
|
|
||||||
|
|
||||||
> **组件名:uv-swipe-action**
|
|
||||||
|
|
||||||
该组件一般用于左滑唤出操作菜单的场景,用的最多的是左滑删除操作。
|
|
||||||
|
|
||||||
### <a href="https://www.uvui.cn/components/swipeAction.html" target="_blank">查看文档</a>
|
|
||||||
|
|
||||||
### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
|
||||||
|
|
||||||
#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
|
@ -1,14 +0,0 @@
|
|||||||
## 1.0.5(2023-08-24)
|
|
||||||
1. 修复标题文字过多未隐藏掉的BUG
|
|
||||||
## 1.0.4(2023-07-24)
|
|
||||||
1. 增加 滑动方向是否为纵向 属性vertical
|
|
||||||
## 1.0.3(2023-06-27)
|
|
||||||
1. 增加titleStyle属性,方便修改标题样式
|
|
||||||
2. 标题上去掉是否是图片的判断,避免无后缀的图片不显示
|
|
||||||
## 1.0.2(2023-06-01)
|
|
||||||
1. 修复点击触发两次事件的BUG
|
|
||||||
## 1.0.1(2023-05-16)
|
|
||||||
1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
|
|
||||||
2. 优化部分功能
|
|
||||||
## 1.0.0(2023-05-10)
|
|
||||||
uv-swiper 轮播图,走马灯
|
|
@ -1,30 +0,0 @@
|
|||||||
export default {
|
|
||||||
props: {
|
|
||||||
// 轮播的长度
|
|
||||||
length: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
// 当前处于活动状态的轮播的索引
|
|
||||||
current: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
// 指示器非激活颜色
|
|
||||||
indicatorActiveColor: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 指示器的激活颜色
|
|
||||||
indicatorInactiveColor: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 指示器模式,line-线型,dot-点型
|
|
||||||
indicatorMode: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
...uni.$uv?.props?.swiperIndicator
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,112 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="uv-swiper-indicator">
|
|
||||||
<view
|
|
||||||
class="uv-swiper-indicator__wrapper"
|
|
||||||
v-if="indicatorMode === 'line'"
|
|
||||||
:class="[`uv-swiper-indicator__wrapper--${indicatorMode}`]"
|
|
||||||
:style="{
|
|
||||||
width: $uv.addUnit(lineWidth * length),
|
|
||||||
backgroundColor: indicatorInactiveColor
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<view
|
|
||||||
class="uv-swiper-indicator__wrapper--line__bar"
|
|
||||||
:style="[lineStyle]"
|
|
||||||
></view>
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
class="uv-swiper-indicator__wrapper"
|
|
||||||
v-if="indicatorMode === 'dot'"
|
|
||||||
>
|
|
||||||
<view
|
|
||||||
class="uv-swiper-indicator__wrapper__dot"
|
|
||||||
v-for="(item, index) in length"
|
|
||||||
:key="index"
|
|
||||||
:class="[index === current && 'uv-swiper-indicator__wrapper__dot--active']"
|
|
||||||
:style="[dotStyle(index)]"
|
|
||||||
>
|
|
||||||
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
|
||||||
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
|
||||||
import props from './props.js';
|
|
||||||
/**
|
|
||||||
* SwiperIndicator 轮播图指示器
|
|
||||||
* @description 该组件一般用于导航轮播,广告展示等场景,可开箱即用,
|
|
||||||
* @tutorial https://www.uvui.cn/components/swiper.html
|
|
||||||
* @property {String | Number} length 轮播的长度(默认 0 )
|
|
||||||
* @property {String | Number} current 当前处于活动状态的轮播的索引(默认 0 )
|
|
||||||
* @property {String} indicatorActiveColor 指示器非激活颜色
|
|
||||||
* @property {String} indicatorInactiveColor 指示器的激活颜色
|
|
||||||
* @property {String} indicatorMode 指示器模式(默认 'line' )
|
|
||||||
* @example <uv-swiper :list="list4" indicator keyName="url" :autoplay="false"></uv-swiper>
|
|
||||||
*/
|
|
||||||
export default {
|
|
||||||
name: 'uv-swiper-indicator',
|
|
||||||
mixins: [mpMixin, mixin, props],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
lineWidth: 22
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
// 指示器为线型的样式
|
|
||||||
lineStyle() {
|
|
||||||
let style = {}
|
|
||||||
style.width = this.$uv.addUnit(this.lineWidth)
|
|
||||||
style.transform = `translateX(${ this.$uv.addUnit(this.current * this.lineWidth) })`
|
|
||||||
style.backgroundColor = this.indicatorActiveColor
|
|
||||||
return style
|
|
||||||
},
|
|
||||||
// 指示器为点型的样式
|
|
||||||
dotStyle() {
|
|
||||||
return index => {
|
|
||||||
let style = {}
|
|
||||||
style.backgroundColor = index === this.current ? this.indicatorActiveColor : this.indicatorInactiveColor
|
|
||||||
return style
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
|
||||||
|
|
||||||
.uv-swiper-indicator {
|
|
||||||
|
|
||||||
&__wrapper {
|
|
||||||
@include flex;
|
|
||||||
|
|
||||||
&--line {
|
|
||||||
border-radius: 100px;
|
|
||||||
height: 4px;
|
|
||||||
|
|
||||||
&__bar {
|
|
||||||
width: 22px;
|
|
||||||
height: 4px;
|
|
||||||
border-radius: 100px;
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
transition: transform 0.3s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__dot {
|
|
||||||
width: 5px;
|
|
||||||
height: 5px;
|
|
||||||
border-radius: 100px;
|
|
||||||
margin: 0 4px;
|
|
||||||
|
|
||||||
&--active {
|
|
||||||
width: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,136 +0,0 @@
|
|||||||
export default {
|
|
||||||
props: {
|
|
||||||
// 列表数组,元素可为字符串,如为对象可通过keyName指定目标属性名
|
|
||||||
list: {
|
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
},
|
|
||||||
// 是否显示面板指示器
|
|
||||||
indicator: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 指示器非激活颜色
|
|
||||||
indicatorActiveColor: {
|
|
||||||
type: String,
|
|
||||||
default: '#fff'
|
|
||||||
},
|
|
||||||
// 指示器的激活颜色
|
|
||||||
indicatorInactiveColor: {
|
|
||||||
type: String,
|
|
||||||
default: 'rgba(255, 255, 255, 0.35)'
|
|
||||||
},
|
|
||||||
// 指示器样式,可通过bottom,left,right进行定位
|
|
||||||
indicatorStyle: {
|
|
||||||
type: [String, Object],
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 指示器模式,line-线型,dot-点型
|
|
||||||
indicatorMode: {
|
|
||||||
type: String,
|
|
||||||
default: 'line'
|
|
||||||
},
|
|
||||||
// 是否自动切换
|
|
||||||
autoplay: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
// 当前所在滑块的 index
|
|
||||||
current: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
// 当前所在滑块的 item-id ,不能与 current 被同时指定
|
|
||||||
currentItemId: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 滑块自动切换时间间隔
|
|
||||||
interval: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 3000
|
|
||||||
},
|
|
||||||
// 滑块切换过程所需时间
|
|
||||||
duration: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 300
|
|
||||||
},
|
|
||||||
// 播放到末尾后是否重新回到开头
|
|
||||||
circular: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 滑动方向是否为纵向
|
|
||||||
vertical: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 前边距,可用于露出前一项的一小部分,nvue和支付宝不支持
|
|
||||||
previousMargin: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
// 后边距,可用于露出后一项的一小部分,nvue和支付宝不支持
|
|
||||||
nextMargin: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
// 当开启时,会根据滑动速度,连续滑动多屏,支付宝不支持
|
|
||||||
acceleration: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 同时显示的滑块数量,nvue、支付宝小程序不支持
|
|
||||||
displayMultipleItems: {
|
|
||||||
type: Number,
|
|
||||||
default: 1
|
|
||||||
},
|
|
||||||
// 指定swiper切换缓动动画类型,有效值:default、linear、easeInCubic、easeOutCubic、easeInOutCubic
|
|
||||||
// 只对微信小程序有效
|
|
||||||
easingFunction: {
|
|
||||||
type: String,
|
|
||||||
default: 'default'
|
|
||||||
},
|
|
||||||
// list数组中指定对象的目标属性名
|
|
||||||
keyName: {
|
|
||||||
type: String,
|
|
||||||
default: 'url'
|
|
||||||
},
|
|
||||||
// 图片的裁剪模式
|
|
||||||
imgMode: {
|
|
||||||
type: String,
|
|
||||||
default: 'aspectFill'
|
|
||||||
},
|
|
||||||
// 组件高度
|
|
||||||
height: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 130
|
|
||||||
},
|
|
||||||
// 背景颜色
|
|
||||||
bgColor: {
|
|
||||||
type: String,
|
|
||||||
default: '#f3f4f6'
|
|
||||||
},
|
|
||||||
// 组件圆角,数值或带单位的字符串
|
|
||||||
radius: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 4
|
|
||||||
},
|
|
||||||
// 是否加载中
|
|
||||||
loading: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 是否显示标题,要求数组对象中有title属性
|
|
||||||
showTitle: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 显示的标题样式
|
|
||||||
titleStyle: {
|
|
||||||
type: Object,
|
|
||||||
default: ()=>{}
|
|
||||||
},
|
|
||||||
...uni.$uv?.props?.swiper
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,263 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view
|
|
||||||
class="uv-swiper"
|
|
||||||
:style="{
|
|
||||||
backgroundColor: bgColor,
|
|
||||||
height: $uv.addUnit(height),
|
|
||||||
borderRadius: $uv.addUnit(radius)
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<view
|
|
||||||
class="uv-swiper__loading"
|
|
||||||
v-if="loading"
|
|
||||||
>
|
|
||||||
<uv-loading-icon mode="circle"></uv-loading-icon>
|
|
||||||
</view>
|
|
||||||
<swiper
|
|
||||||
v-else
|
|
||||||
class="uv-swiper__wrapper"
|
|
||||||
:style="{
|
|
||||||
height: $uv.addUnit(height),
|
|
||||||
flex: 1
|
|
||||||
}"
|
|
||||||
@change="change"
|
|
||||||
:circular="circular"
|
|
||||||
:vertical="vertical"
|
|
||||||
:interval="interval"
|
|
||||||
:duration="duration"
|
|
||||||
:autoplay="autoplay"
|
|
||||||
:current="current"
|
|
||||||
:currentItemId="currentItemId"
|
|
||||||
:previousMargin="$uv.addUnit(previousMargin)"
|
|
||||||
:nextMargin="$uv.addUnit(nextMargin)"
|
|
||||||
:acceleration="acceleration"
|
|
||||||
:displayMultipleItems="displayMultipleItems"
|
|
||||||
:easingFunction="easingFunction"
|
|
||||||
>
|
|
||||||
<swiper-item
|
|
||||||
class="uv-swiper__wrapper__item"
|
|
||||||
v-for="(item, index) in list"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<view
|
|
||||||
class="uv-swiper__wrapper__item__wrapper"
|
|
||||||
:style="[itemStyle(index)]"
|
|
||||||
>
|
|
||||||
<!-- 在nvue中,image图片的宽度默认为屏幕宽度,需要通过flex:1撑开,另外必须设置高度才能显示图片 -->
|
|
||||||
<image
|
|
||||||
class="uv-swiper__wrapper__item__wrapper__image"
|
|
||||||
v-if="getItemType(item) === 'image'"
|
|
||||||
:src="getSource(item)"
|
|
||||||
:mode="imgMode"
|
|
||||||
@tap="clickHandler(index)"
|
|
||||||
:style="{
|
|
||||||
height: $uv.addUnit(height),
|
|
||||||
borderRadius: $uv.addUnit(radius)
|
|
||||||
}"
|
|
||||||
></image>
|
|
||||||
<video
|
|
||||||
class="uv-swiper__wrapper__item__wrapper__video"
|
|
||||||
v-if="getItemType(item) === 'video'"
|
|
||||||
:id="`video-${index}`"
|
|
||||||
:enable-progress-gesture="false"
|
|
||||||
:src="getSource(item)"
|
|
||||||
:poster="getPoster(item)"
|
|
||||||
:title="showTitle && $uv.test.object(item) && item.title ? item.title : ''"
|
|
||||||
:style="{
|
|
||||||
height: $uv.addUnit(height)
|
|
||||||
}"
|
|
||||||
controls
|
|
||||||
@tap="clickHandler(index)"
|
|
||||||
></video>
|
|
||||||
<text
|
|
||||||
v-if="showTitle && $uv.test.object(item) && item.title"
|
|
||||||
class="uv-swiper__wrapper__item__wrapper__title uv-line-1"
|
|
||||||
:style="[$uv.addStyle(titleStyle)]"
|
|
||||||
>{{ item.title }}</text>
|
|
||||||
</view>
|
|
||||||
</swiper-item>
|
|
||||||
</swiper>
|
|
||||||
<view class="uv-swiper__indicator" :style="[$uv.addStyle(indicatorStyle)]">
|
|
||||||
<slot name="indicator">
|
|
||||||
<uv-swiper-indicator
|
|
||||||
v-if="!loading && indicator && !showTitle"
|
|
||||||
:indicatorActiveColor="indicatorActiveColor"
|
|
||||||
:indicatorInactiveColor="indicatorInactiveColor"
|
|
||||||
:length="list.length"
|
|
||||||
:current="currentIndex"
|
|
||||||
:indicatorMode="indicatorMode"
|
|
||||||
></uv-swiper-indicator>
|
|
||||||
</slot>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
|
||||||
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
|
||||||
import props from './props.js';
|
|
||||||
/**
|
|
||||||
* Swiper 轮播图
|
|
||||||
* @description 该组件一般用于导航轮播,广告展示等场景,可开箱即用,
|
|
||||||
* @tutorial https://www.uvui.cn/components/swiper.html
|
|
||||||
* @property {Array} list 轮播图数据
|
|
||||||
* @property {Boolean} indicator 是否显示面板指示器(默认 false )
|
|
||||||
* @property {String} indicatorActiveColor 指示器非激活颜色(默认 '#FFFFFF' )
|
|
||||||
* @property {String} indicatorInactiveColor 指示器的激活颜色(默认 'rgba(255, 255, 255, 0.35)' )
|
|
||||||
* @property {String | Object} indicatorStyle 指示器样式,可通过bottom,left,right进行定位
|
|
||||||
* @property {String} indicatorMode 指示器模式(默认 'line' )
|
|
||||||
* @property {Boolean} autoplay 是否自动切换(默认 true )
|
|
||||||
* @property {String | Number} current 当前所在滑块的 index(默认 0 )
|
|
||||||
* @property {String} currentItemId 当前所在滑块的 item-id ,不能与 current 被同时指定
|
|
||||||
* @property {String | Number} interval 滑块自动切换时间间隔(ms)(默认 3000 )
|
|
||||||
* @property {String | Number} duration 滑块切换过程所需时间(ms)(默认 300 )
|
|
||||||
* @property {Boolean} circular 播放到末尾后是否重新回到开头(默认 false )
|
|
||||||
* @property {String | Number} previousMargin 前边距,可用于露出前一项的一小部分,nvue和支付宝不支持(默认 0 )
|
|
||||||
* @property {String | Number} nextMargin 后边距,可用于露出后一项的一小部分,nvue和支付宝不支持(默认 0 )
|
|
||||||
* @property {Boolean} acceleration 当开启时,会根据滑动速度,连续滑动多屏,支付宝不支持(默认 false )
|
|
||||||
* @property {Number} displayMultipleItems 同时显示的滑块数量,nvue、支付宝小程序不支持(默认 1 )
|
|
||||||
* @property {String} easingFunction 指定swiper切换缓动动画类型, 只对微信小程序有效(默认 'default' )
|
|
||||||
* @property {String} keyName list数组中指定对象的目标属性名(默认 'url' )
|
|
||||||
* @property {String} imgMode 图片的裁剪模式(默认 'aspectFill' )
|
|
||||||
* @property {String | Number} height 组件高度(默认 130 )
|
|
||||||
* @property {String} bgColor 背景颜色(默认 '#f3f4f6' )
|
|
||||||
* @property {String | Number} radius 组件圆角,数值或带单位的字符串(默认 4 )
|
|
||||||
* @property {Boolean} loading 是否加载中(默认 false )
|
|
||||||
* @property {Boolean} showTitle 是否显示标题,要求数组对象中有title属性(默认 false )
|
|
||||||
* @event {Function(index)} click 点击轮播图时触发 index:点击了第几张图片,从0开始
|
|
||||||
* @event {Function(index)} change 轮播图切换时触发(自动或者手动切换) index:切换到了第几张图片,从0开始
|
|
||||||
* @example <uv-swiper :list="list4" keyName="url" :autoplay="false"></uv-swiper>
|
|
||||||
*/
|
|
||||||
export default {
|
|
||||||
name: 'uv-swiper',
|
|
||||||
mixins: [mpMixin, mixin, props],
|
|
||||||
emits: ['click','change'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
currentIndex: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
current(val, preVal) {
|
|
||||||
if(val === preVal) return;
|
|
||||||
this.currentIndex = val; // 和上游数据关联上
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
itemStyle() {
|
|
||||||
return index => {
|
|
||||||
const style = {}
|
|
||||||
// #ifndef APP-NVUE || MP-TOUTIAO
|
|
||||||
// 左右流出空间的写法不支持nvue和头条
|
|
||||||
// 只有配置了此二值,才加上对应的圆角,以及缩放
|
|
||||||
if (this.nextMargin && this.previousMargin) {
|
|
||||||
style.borderRadius = this.$uv.addUnit(this.radius)
|
|
||||||
if (index !== this.currentIndex) style.transform = 'scale(0.92)'
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
return style
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getItemType(item) {
|
|
||||||
if (typeof item === 'string') return this.$uv.test.video(this.getSource(item)) ? 'video' : 'image'
|
|
||||||
if (typeof item === 'object' && this.keyName) {
|
|
||||||
if (!item.type) return this.$uv.test.video(this.getSource(item)) ? 'video' : 'image'
|
|
||||||
if (item.type === 'image') return 'image'
|
|
||||||
if (item.type === 'video') return 'video'
|
|
||||||
return 'image'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 获取目标路径,可能数组中为字符串,对象的形式,额外可指定对象的目标属性名keyName
|
|
||||||
getSource(item) {
|
|
||||||
if (typeof item === 'string') return item
|
|
||||||
if (typeof item === 'object' && this.keyName) return item[this.keyName]
|
|
||||||
else this.$uv.error('请按格式传递列表参数')
|
|
||||||
return ''
|
|
||||||
},
|
|
||||||
// 轮播切换事件
|
|
||||||
change(e) {
|
|
||||||
// 当前的激活索引
|
|
||||||
const {
|
|
||||||
current
|
|
||||||
} = e.detail
|
|
||||||
this.pauseVideo(this.currentIndex)
|
|
||||||
this.currentIndex = current
|
|
||||||
this.$emit('change', e.detail)
|
|
||||||
},
|
|
||||||
// 切换轮播时,暂停视频播放
|
|
||||||
pauseVideo(index) {
|
|
||||||
const lastItem = this.getSource(this.list[index])
|
|
||||||
if (this.$uv.test.video(lastItem)) {
|
|
||||||
// 当视频隐藏时,暂停播放
|
|
||||||
const video = uni.createVideoContext(`video-${index}`, this)
|
|
||||||
video.pause()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 当一个轮播item为视频时,获取它的视频海报
|
|
||||||
getPoster(item) {
|
|
||||||
return typeof item === 'object' && item.poster ? item.poster : ''
|
|
||||||
},
|
|
||||||
// 点击某个item
|
|
||||||
clickHandler(index) {
|
|
||||||
this.$emit('click', index)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
$show-lines: 1;
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/variable.scss';
|
|
||||||
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
|
||||||
.uv-swiper {
|
|
||||||
@include flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
&__wrapper {
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
&__item {
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
&__wrapper {
|
|
||||||
@include flex;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
transition: transform 0.3s;
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
&__image {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__video {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__title {
|
|
||||||
position: absolute;
|
|
||||||
background-color: rgba(0, 0, 0, 0.3);
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
font-size: 28rpx;
|
|
||||||
height: 60rpx;
|
|
||||||
line-height: 60rpx;
|
|
||||||
color: #FFFFFF;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__indicator {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,88 +0,0 @@
|
|||||||
{
|
|
||||||
"id": "uv-swiper",
|
|
||||||
"displayName": "uv-swiper 轮播图 全面兼容vue3+2、app、h5、小程序等多端",
|
|
||||||
"version": "1.0.5",
|
|
||||||
"description": "该组件为轮播、跑马灯,支持卡片式。一般用于导航轮播,广告展示等场景,开箱即用",
|
|
||||||
"keywords": [
|
|
||||||
"swiper",
|
|
||||||
"uvui",
|
|
||||||
"uv-ui",
|
|
||||||
"轮播图",
|
|
||||||
"走马灯"
|
|
||||||
],
|
|
||||||
"repository": "",
|
|
||||||
"engines": {
|
|
||||||
"HBuilderX": "^3.1.0"
|
|
||||||
},
|
|
||||||
"dcloudext": {
|
|
||||||
"type": "component-vue",
|
|
||||||
"sale": {
|
|
||||||
"regular": {
|
|
||||||
"price": "0.00"
|
|
||||||
},
|
|
||||||
"sourcecode": {
|
|
||||||
"price": "0.00"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"contact": {
|
|
||||||
"qq": ""
|
|
||||||
},
|
|
||||||
"declaration": {
|
|
||||||
"ads": "无",
|
|
||||||
"data": "插件不采集任何数据",
|
|
||||||
"permissions": "无"
|
|
||||||
},
|
|
||||||
"npmurl": ""
|
|
||||||
},
|
|
||||||
"uni_modules": {
|
|
||||||
"dependencies": [
|
|
||||||
"uv-ui-tools",
|
|
||||||
"uv-loading-icon"
|
|
||||||
],
|
|
||||||
"encrypt": [],
|
|
||||||
"platforms": {
|
|
||||||
"cloud": {
|
|
||||||
"tcb": "y",
|
|
||||||
"aliyun": "y"
|
|
||||||
},
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
## Swiper 轮播图
|
|
||||||
|
|
||||||
> **组件名:uv-swiper**
|
|
||||||
|
|
||||||
该组件为轮播、跑马灯,支持卡片式。一般用于导航轮播,广告展示等场景,开箱即用。
|
|
||||||
|
|
||||||
# <a href="https://www.uvui.cn/components/swiper.html" target="_blank">查看文档</a>
|
|
||||||
|
|
||||||
## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>(请不要 下载插件ZIP)</small>
|
|
||||||
|
|
||||||
### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
|
||||||
|
|
||||||
<a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank">
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
</a>
|
|
||||||
|
|
||||||
#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
|
Loading…
Reference in New Issue
Block a user