提交 b3950100 编写于 作者: DCloud_JSON's avatar DCloud_JSON

兼容vue3...待续未完成

上级 f9ef3751
...@@ -44,20 +44,4 @@ ...@@ -44,20 +44,4 @@
<style> <style>
/*每个页面公共css */ /*每个页面公共css */
/* #ifndef APP-NVUE */
view,
scroll-view,
text,
image,
switch,
navigator,
icons {
display: flex;
box-sizing: border-box;
flex-direction: column;
}
scroll-view {
-webkit-overflow-scrolling: touch;
}
/* #endif */
</style> </style>
view,
scroll-view,
text,
image,
switch,
navigator,
icons {
display: flex !important;
box-sizing: border-box;
flex-direction: column;
}
scroll-view {
-webkit-overflow-scrolling: touch;
}
...@@ -342,7 +342,8 @@ ...@@ -342,7 +342,8 @@
} }
</script> </script>
<style scoped> <style lang="scss" scoped>
@import '@/common/all-flex.css';
.quick-login-box { .quick-login-box {
flex-direction: row; flex-direction: row;
width: 750rpx; width: 750rpx;
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>
import Vue from 'vue'
import App from './App' import App from './App'
import store from './store/index.js'; import store from './store'
import openApp from './common/openApp.js';
// #ifndef VUE3
import Vue from 'vue'
Vue.config.productionTip = false Vue.config.productionTip = false
openApp(); Vue.prototype.$store = store
App.mpType = 'app' App.mpType = 'app'
const app = new Vue({ const app = new Vue({
...App, store,
store ...App
}) })
app.$mount() app.$mount()
// #endif
// #ifdef VUE3
import { createApp } from 'vue'
const app = createApp(App,{})
app.use(store)
app.mount('#app')
// #endif
\ No newline at end of file
{ {
"name": "uni-starter", "name" : "uni-starter",
"appid": "请点击重新获取", "appid" : "__UNI__03B096E",
"description": "云端一体应用快速开发模版", "description" : "云端一体应用快速开发模版",
"versionName": "1.0.0", "versionName" : "1.0.0",
"versionCode": "100", "versionCode" : "100",
"transformPx": false, "transformPx" : false,
"app-plus": { "app-plus" : {
"privacy": { "privacy" : {
"prompt": "template", "prompt" : "template",
"template": { "template" : {
"title": "服务协议和隐私政策", "title" : "服务协议和隐私政策",
"message": "  请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/>  你可阅读<a href=\"https://ask.dcloud.net.cn/protocol.html\">《服务协议》</a>和<a href=\"https://ask.dcloud.net.cn/protocol.html\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。", "message" : "  请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/>  你可阅读<a href=\"https://ask.dcloud.net.cn/protocol.html\">《服务协议》</a>和<a href=\"https://ask.dcloud.net.cn/protocol.html\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
"buttonAccept": "同意", "buttonAccept" : "同意",
"buttonRefuse": "暂不同意" "buttonRefuse" : "暂不同意"
} }
}, },
"compatible": { "compatible" : {
"ignoreVersion": true "ignoreVersion" : true
},
"usingComponents": true,
"nvueStyleCompiler": "uni-app",
"compilerVersion": 3,
"splashscreen": {
"alwaysShowBeforeRender": true,
"waiting": true,
"autoclose": true,
"delay": 0
},
"modules": {
"Fingerprint": {
},
"Share": {
},
"OAuth": {
},
"FaceID": {
},
"Push": {
}
},
"distribute": {
"android": {
"permissions": [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.USE_FINGERPRINT\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
],
"abiFilters": [
"armeabi-v7a",
"arm64-v8a",
"x86"
]
},
"ios": {
"capabilities": {
"entitlements": {
"com.apple.developer.associated-domains": [
"applinks:static-76ce2c5e-31c7-4d81-8fcf-ed1541ecbc6e.bspapp.com"
]
}
}
},
"sdkConfigs": {
"oauth": {
"apple": {
},
"weixin": {
"appid": "wxffdd8fa6ec4ef2a0",
"appsecret": "",
"UniversalLinks": "https://static-76ce2c5e-31c7-4d81-8fcf-ed1541ecbc6e.bspapp.com/uni-universallinks/__UNI__03B096E"
},
"univerify": {
}
}, },
"ad": { "usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
}, },
"share": { "modules" : {
"weixin": { "Fingerprint" : {},
"appid": "wxffdd8fa6ec4ef2a0", "Share" : {},
"UniversalLinks": "https://static-76ce2c5e-31c7-4d81-8fcf-ed1541ecbc6e.bspapp.com/uni-universallinks/__UNI__03B096E" "OAuth" : {},
} "FaceID" : {},
"Push" : {}
}, },
"geolocation": { "distribute" : {
"android" : {
"permissions" : [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.USE_FINGERPRINT\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
],
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ]
},
"ios" : {
"capabilities" : {
"entitlements" : {
"com.apple.developer.associated-domains" : [ "applinks:static-76ce2c5e-31c7-4d81-8fcf-ed1541ecbc6e.bspapp.com" ]
}
}
},
"sdkConfigs" : {
"oauth" : {
"apple" : {},
"weixin" : {
"appid" : "wxffdd8fa6ec4ef2a0",
"appsecret" : "",
"UniversalLinks" : "https://static-76ce2c5e-31c7-4d81-8fcf-ed1541ecbc6e.bspapp.com/uni-universallinks/__UNI__03B096E"
},
"univerify" : {}
},
"ad" : {},
"share" : {
"weixin" : {
"appid" : "wxffdd8fa6ec4ef2a0",
"UniversalLinks" : "https://static-76ce2c5e-31c7-4d81-8fcf-ed1541ecbc6e.bspapp.com/uni-universallinks/__UNI__03B096E"
}
},
"geolocation" : {},
"push" : {
"unipush" : {}
},
"payment" : {}
}
}, },
"push": { "nvueLaunchMode" : ""
"unipush": { },
} "quickapp" : {},
"mp-weixin" : {
"appid" : "wx81dbb061d2258234",
"setting" : {
"urlCheck" : false,
"es6" : false
}, },
"payment": { "usingComponents" : true,
} "betterScopedSlots" : true
} },
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
}, },
"nvueLaunchMode": "" "h5" : {
}, "template" : ""
"quickapp": {
},
"mp-weixin": {
"appid": "",
"setting": {
"urlCheck": false,
"es6": false
}, },
"usingComponents": true, "_spaceID" : "76ce2c5e-31c7-4d81-8fcf-ed1541ecbc6e",
"betterScopedSlots": true "vueVersion" : "3"
}, }
"mp-alipay": {
"usingComponents": true
},
"mp-baidu": {
"usingComponents": true
},
"mp-toutiao": {
"usingComponents": true
},
"uniStatistics": {
"enable": false
},
"h5": {
"template": ""
},
"_spaceID": "76ce2c5e-31c7-4d81-8fcf-ed1541ecbc6e"
}
\ No newline at end of file
...@@ -203,14 +203,14 @@ ...@@ -203,14 +203,14 @@
background-color: #fff; background-color: #fff;
} }
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE || VUE3*/
/deep/ /deep/
/* #endif */ /* #endif */
.uni-searchbar__box { .uni-searchbar__box {
border-width: 0; border-width: 0;
} }
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE || VUE3 */
/deep/ /deep/
/* #endif */ /* #endif */
.uni-input-placeholder { .uni-input-placeholder {
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
</template> </template>
<script> <script>
import uniShare from 'uni_modules/uni-share/js_sdk/uni-share.js'; import uniShare from '@/uni_modules/uni-share/js_sdk/uni-share.js';
const db = uniCloud.database(); const db = uniCloud.database();
const readNewsLog = db.collection('read-news-log') const readNewsLog = db.collection('read-news-log')
......
...@@ -4,8 +4,11 @@ ...@@ -4,8 +4,11 @@
<statusBar></statusBar> <statusBar></statusBar>
<!-- #endif --> <!-- #endif -->
<!-- 搜索功能 --> <!-- 搜索功能 -->
<uni-search-bar @click="searchClick" class="uni-search-box" v-model="keyword" ref="searchBar" radius="100" <view @click.capture="searchClick">
cancelButton="none" disabled /> <uni-search-bar class="uni-search-box" v-model="keyword" ref="searchBar" radius="100"
cancelButton="none" />
</view>
<unicloud-db ref='udb' v-slot:default="{data,pagination,hasMore, loading, error, options}" @error="onqueryerror" <unicloud-db ref='udb' v-slot:default="{data,pagination,hasMore, loading, error, options}" @error="onqueryerror"
:where="where" collection="opendb-news-articles,uni-id-users" :page-size="10" :where="where" collection="opendb-news-articles,uni-id-users" :page-size="10"
field="avatar,title,last_modify_date,user_id.username"> field="avatar,title,last_modify_date,user_id.username">
...@@ -18,18 +21,20 @@ ...@@ -18,18 +21,20 @@
<template v-slot:header> <template v-slot:header>
<image class="avatar" :src="item.avatar" mode="aspectFill"></image> <image class="avatar" :src="item.avatar" mode="aspectFill"></image>
</template> </template>
<!-- 通过body插槽定义布局 --> <!-- 通过body插槽定义布局 -->
<view slot="body" class="main"> <template v-slot:body>
<text class="title">{{ item.title }}</text> <view class="main">
<view class="info"> <text class="title">{{item.title}}</text>
<text class="author">{{item.user_id[0].username}}</text> <view class="info">
<uni-dateformat class="last_modify_date" :date="item.last_modify_date" format="yyyy-MM-dd" <text class="author">{{item.user_id[0].username}}</text>
:threshold="[60000, 2592000000]" /> <uni-dateformat class="last_modify_date" :date="item.last_modify_date" format="yyyy-MM-dd"
</view> :threshold="[60000, 2592000000]" />
</view> </view>
</view>
</template>
</uni-list-item> </uni-list-item>
<uni-list-item> <uni-list-item>
<template slot="body"> <template v-slot:body>
<uni-load-state @networkResume="refresh" :state="{data,pagination,hasMore, loading, error}"> <uni-load-state @networkResume="refresh" :state="{data,pagination,hasMore, loading, error}">
</uni-load-state> </uni-load-state>
</template> </template>
...@@ -77,18 +82,11 @@ ...@@ -77,18 +82,11 @@
cdbRef = this.$refs.udb cdbRef = this.$refs.udb
}, },
async onShow() { async onShow() {
console.log(999,getApp().globalData.searchText);
this.keyword = getApp().globalData.searchText this.keyword = getApp().globalData.searchText
getApp().globalData.searchText = '' getApp().globalData.searchText = ''
if (this.keyword) {
// #ifdef APP-PLUS
if (!currentWebview) {
let pages = getCurrentPages();
currentWebview = pages[pages.length - 1].$getAppWebview();
}
// 设置 searchInput的 text
currentWebview.setTitleNViewSearchInputText(this.keyword)
// #endif
}
//这里仅演示如何,在onShow生命周期获取设备位置,并在设备或者应用没有权限时自动引导。设置完毕自动重新获取。 //这里仅演示如何,在onShow生命周期获取设备位置,并在设备或者应用没有权限时自动引导。设置完毕自动重新获取。
...@@ -124,6 +122,9 @@ ...@@ -124,6 +122,9 @@
uni.stopPullDownRefresh() uni.stopPullDownRefresh()
}) })
console.log('refresh'); console.log('refresh');
},
onqueryerror(e){
console.log(e);
} }
}, },
onPullDownRefresh() { onPullDownRefresh() {
......
...@@ -64,10 +64,7 @@ ...@@ -64,10 +64,7 @@
<!-- 搜索联想 --> <!-- 搜索联想 -->
<view class="search-associative" :style="{marginTop:statusBarHeight}" v-if="associativeShow"> <view class="search-associative" :style="{marginTop:statusBarHeight}" v-if="associativeShow">
<uni-list> <uni-list>
<template v-for="(item,index) in associativeList"> <uni-list-item v-for="(item,index) in associativeList" :key="item._id" :ellipsis="1" :title="item.title" @click="associativeClick(item)" show-extra-icon clickable :extra-icon="{size:18,color:iconColor,type:'search'}" />
<uni-list-item :key="item._id" :ellipsis="1" :title="item.title" @click="associativeClick(item)" show-extra-icon
clickable :extra-icon="{size:18,color:iconColor,type:'search'}" />
</template>
</uni-list> </uni-list>
</view> </view>
</view> </view>
...@@ -152,10 +149,11 @@ ...@@ -152,10 +149,11 @@
this.db = uniCloud.database(); this.db = uniCloud.database();
this.searchLogDb = this.db.collection(this.searchLogDbName); this.searchLogDb = this.db.collection(this.searchLogDbName);
this.mallGoodsDb = this.db.collection(this.mallGoodsDbName); this.mallGoodsDb = this.db.collection(this.mallGoodsDbName);
// #ifndef H5
uni.onKeyboardHeightChange((res) => { uni.onKeyboardHeightChange((res) => {
this.keyBoardPopup = res.height !== 0; this.keyBoardPopup = res.height !== 0;
}) })
// #endif
this.searchText = getApp().globalData.searchText; this.searchText = getApp().globalData.searchText;
}, },
...@@ -378,7 +376,7 @@ ...@@ -378,7 +376,7 @@
} }
/* #ifdef APP-PLUS */ /* #ifdef APP-PLUS */
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE || VUE3*/
/deep/ /deep/
/* #endif */ /* #endif */
.uni-searchbar { .uni-searchbar {
...@@ -387,14 +385,14 @@ ...@@ -387,14 +385,14 @@
/* #endif */ /* #endif */
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE || VUE3*/
/deep/ /deep/
/* #endif */ /* #endif */
.uni-searchbar__box { .uni-searchbar__box {
border-width: 0; border-width: 0;
} }
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE || VUE3 */
/deep/ /deep/
/* #endif */ /* #endif */
.uni-input-placeholder { .uni-input-placeholder {
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
</view> </view>
</template> </template>
<script> <script>
import uniShare from 'uni_modules/uni-share/js_sdk/uni-share.js'; import uniShare from '@/uni_modules/uni-share/js_sdk/uni-share.js';
export default { export default {
onLoad() { onLoad() {
// #ifdef APP-PLUS // #ifdef APP-PLUS
...@@ -115,6 +115,7 @@ import uniShare from 'uni_modules/uni-share/js_sdk/uni-share.js'; ...@@ -115,6 +115,7 @@ import uniShare from 'uni_modules/uni-share/js_sdk/uni-share.js';
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import '@/common/all-flex.css';
.about { .about {
width: 750upx; width: 750upx;
flex-direction: column; flex-direction: column;
......
.content{ @import '@/common/all-flex.css';
padding:0 50rpx;
width: 750rpx; .content {
flex: 1; padding: 0 50rpx;
} width: 750rpx;
.input-box{ flex: 1;
padding:0 15px; }
margin-bottom: 10px;
background-color: #F8F8F8; .input-box {
border-radius: 6px; padding: 0 15px;
font-size: 28rpx; margin-bottom: 10px;
} background-color: #F8F8F8;
.get-code{ border-radius: 6px;
margin: 0; font-size: 28rpx;
margin-top:15px; }
background-color: #007aff;
color: #FFFFFF; .get-code {
} margin: 0;
.input-box,.get-code{ margin-top: 15px;
height: 45px; background-color: #007aff;
line-height: 45px; color: #FFFFFF;
} }
.title{
text-align: center; .input-box,
padding-bottom: 5px; .get-code {
} height: 45px;
.tip{ line-height: 45px;
color: #666666; }
font-size: 26rpx;
margin: 6px 0; .title {
} text-align: center;
.easyinput{ padding-bottom: 5px;
background-color: #F8F8F8; }
border-radius: 6rpx;
} .tip {
.send-btn{ color: #666666;
width: 100%; font-size: 26rpx;
margin-top:15px; margin: 6px 0;
border-radius: 6rpx; }
}
.link{ .easyinput {
color: #04498c; background-color: #F8F8F8;
} border-radius: 6rpx;
\ No newline at end of file }
.send-btn {
width: 100%;
margin-top: 15px;
border-radius: 6rpx;
}
.link {
color: #04498c;
}
...@@ -2,20 +2,20 @@ ...@@ -2,20 +2,20 @@
<view class="content"> <view class="content">
<!-- 顶部文字 --> <!-- 顶部文字 -->
<text class="title">登录后即可展示自己</text> <text class="title">登录后即可展示自己</text>
<!-- 登录框 --> <!-- 登录框 -->
<view v-if="['apple','weixin'].includes(type)" class="quickLogin"> <view v-if="['apple','weixin'].includes(type)" class="quickLogin">
<image @click="quickLogin" :src="imgSrc" mode="widthFix" class="quickLoginBtn"></image> <image @click="quickLogin" :src="imgSrc" mode="widthFix" class="quickLoginBtn"></image>
<uni-agreements @setAgree="agree = $event"></uni-agreements> <uni-agreements @setAgree="agree = $event"></uni-agreements>
</view> </view>
<template v-else> <template v-else>
<input type="number" class="input-box" :inputBorder="false" v-model="phone" maxlength="11" <input type="number" class="input-box" :inputBorder="false" v-model="phone" maxlength="11"
placeholder="请输入手机号" /> placeholder="请输入手机号" />
<uni-agreements @setAgree="agree = $event"></uni-agreements> <uni-agreements @setAgree="agree = $event"></uni-agreements>
<button class="get-code" :disabled="!isPhone" :type="isPhone?'primary':'default'" <button class="get-code" :disabled="!isPhone" :type="isPhone?'primary':'default'"
@click="sendShortMsg">获取短信验证码</button> @click="sendShortMsg">获取短信验证码</button>
<text class="tip">未注册的手机号验证通过后将自动注册</text> <text class="tip">未注册的手机号验证通过后将自动注册</text>
</template> </template>
<!-- 快捷登录按钮弹窗 --> <!-- 快捷登录按钮弹窗 -->
<uni-quick-login :agree="agree" ref="uniQuickLogin"></uni-quick-login> <uni-quick-login :agree="agree" ref="uniQuickLogin"></uni-quick-login>
</view> </view>
...@@ -25,26 +25,26 @@ ...@@ -25,26 +25,26 @@
let currentWebview; //是否一键登录优先 let currentWebview; //是否一键登录优先
export default { export default {
data() { data() {
return { return {
type:"", type: "",
phone: "", phone: "",
agree: false agree: false
} }
}, },
computed: { computed: {
loginConfig() { loginConfig() {
return getApp().globalData.config.router.login return getApp().globalData.config.router.login
}, },
isPhone() { isPhone() {
return /^1\d{10}$/.test(this.phone); return /^1\d{10}$/.test(this.phone);
}, },
imgSrc(){ imgSrc() {
return '/static/login-index/'+this.type+'.png' return '/static/login-index/' + this.type + '.png'
} }
}, },
onLoad(e) { onLoad(e) {
this.type = e.type this.type = e.type
//是否优先启动一键登录。即:页面一加载就启动一键登录 //是否优先启动一键登录。即:页面一加载就启动一键登录
//#ifdef APP-PLUS //#ifdef APP-PLUS
if (this.type == "univerify") { if (this.type == "univerify") {
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
}, },
onReady() { onReady() {
//#ifdef APP-PLUS //#ifdef APP-PLUS
if (this.type == "univerify") { if (this.type == "univerify") {
this.type == loginConfig[1] this.type == loginConfig[1]
// console.log('开始一键登录'); // console.log('开始一键登录');
setTimeout(() => { setTimeout(() => {
...@@ -78,9 +78,9 @@ ...@@ -78,9 +78,9 @@
} }
//#endif //#endif
}, },
methods: { methods: {
quickLogin(){ quickLogin() {
this.$refs.uniQuickLogin.login_before(this.type) this.$refs.uniQuickLogin.login_before(this.type)
}, },
sendShortMsg() { sendShortMsg() {
if (!this.agree) { if (!this.agree) {
...@@ -108,16 +108,18 @@ ...@@ -108,16 +108,18 @@
} }
</script> </script>
<style lang="scss"> <style lang="scss" scoped>
@import url("../common/login-page.css"); @import '@/common/all-flex.css';
.quickLogin{ @import url("../common/login-page.css");
width: 650rpx; .quickLogin {
height: 350px; width: 650rpx;
align-items: center; height: 350px;
justify-content: center; align-items: center;
} justify-content: center;
.quickLoginBtn{ }
margin:20px 0;
width: 450rpx; .quickLoginBtn {
margin: 20px 0;
width: 450rpx;
} }
</style> </style>
\ No newline at end of file
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
<view class="content"> <view class="content">
<!-- 顶部文字 --> <!-- 顶部文字 -->
<text class="title">用户名密码登录</text> <text class="title">用户名密码登录</text>
<input class="input-box" :inputBorder="false" v-model="username" placeholder="请输入手机号/用户名"></input> <input class="input-box" :inputBorder="false" v-model="username" placeholder="请输入手机号/用户名"/>
<input type="password" class="input-box" :inputBorder="false" v-model="password" placeholder="请输入密码"></input> <input type="password" class="input-box" :inputBorder="false" v-model="password" placeholder="请输入密码"/>
<view class="captcha-box" v-if="captchaBase64"> <view class="captcha-box" v-if="captchaBase64">
<image class="captcha-img" @click="createCaptcha" :src="captchaBase64" mode="widthFix"></image> <image class="captcha-img" @click="createCaptcha" :src="captchaBase64" mode="widthFix"></image>
<input type="text" class="input-box captcha" :inputBorder="false" v-model="captcha" placeholder="请输入验证码"></input> <input type="text" class="input-box captcha" :inputBorder="false" v-model="captcha" placeholder="请输入验证码"/>
</view> </view>
<uni-agreements @setAgree="agree = $event"></uni-agreements> <uni-agreements @setAgree="agree = $event"></uni-agreements>
<button class="send-btn" :disabled="!canLogin" :type="canLogin?'primary':'default'" <button class="send-btn" :disabled="!canLogin" :type="canLogin?'primary':'default'"
......
...@@ -5,12 +5,14 @@ ...@@ -5,12 +5,14 @@
field="title,_id" :page-size="10"> field="title,_id" :page-size="10">
<uni-list> <uni-list>
<uni-list-item v-for="(item, index) in data" :key="index" :clickable="true" <uni-list-item v-for="(item, index) in data" :key="index" :clickable="true"
@click="handleItemClick(item)"> @click="handleItemClick(item)">
<view slot="body"> <template v-slot:body>
<text>{{item.title}}</text> <view class="item">
<uni-dateformat class="article-date" :date="readNewsLog[index].last_time" format="yyyy-MM-dd hh:mm" <text>{{item.title}}</text>
:threshold="[0, 0]" /> <uni-dateformat class="article-date" :date="readNewsLog[index].last_time" format="yyyy-MM-dd hh:mm"
</view> :threshold="[0, 0]" />
</view>
</template>
</uni-list-item> </uni-list-item>
</uni-list> </uni-list>
<uni-load-state @networkResume="refreshData" :state="{data,pagination,hasMore, loading, error}"></uni-load-state> <uni-load-state @networkResume="refreshData" :state="{data,pagination,hasMore, loading, error}"></uni-load-state>
...@@ -62,7 +64,11 @@ ...@@ -62,7 +64,11 @@
} }
</script> </script>
<style> <style>
.item{
display: flex;
flex-direction: column;
}
.article-date { .article-date {
color: #C8C7CC; color: #C8C7CC;
} }
......
...@@ -109,7 +109,7 @@ function setting(){ ...@@ -109,7 +109,7 @@ function setting(){
} }
} }
module.exports = { export default {
isOn: isTurnedOnPush, isOn: isTurnedOnPush,
iosSetting: settingInIos, iosSetting: settingInIos,
on: turnOnPush, on: turnOnPush,
......
...@@ -278,13 +278,14 @@ ...@@ -278,13 +278,14 @@
.mt10 { .mt10 {
margin-top: 10px; margin-top: 10px;
} }
/* #ifndef APP-NVUE || VUE3 */
.content /deep/ .uni-list { .content /deep/ .uni-list {
background-color: #F9F9F9; background-color: #F9F9F9;
} }
.content /deep/ .uni-list-item--disabled,.list-item {
height: 50px;
margin-bottom: 1px;
}
/* #endif */
.content /deep/ .uni-list-item--disabled,.list-item {
height: 50px;
margin-bottom: 1px;
}
</style> </style>
\ No newline at end of file
<template> <template>
<view class="center"> <view class="center">
<uni-sign-in ref="signIn"></uni-sign-in> <uni-sign-in ref="signIn"></uni-sign-in>
<view class="userInfo" @click.capture="toUserInfo"> <view class="userInfo" @click.capture="toUserInfo">
<uni-file-picker v-if="userInfo.avatar_file" v-model="userInfo.avatar_file" <uni-file-picker v-if="userInfo.avatar_file" v-model="userInfo.avatar_file"
fileMediatype="image" :del-icon="false" return-type="object" :image-styles="listStyles" disablePreview fileMediatype="image" :del-icon="false" return-type="object" :image-styles="listStyles" disablePreview
disabled /> disabled />
<image v-else class="logo-img" src="/static/uni-center/defaultAvatarUrl.png"></image> <image v-else class="logo-img" src="/static/uni-center/defaultAvatarUrl.png"></image>
<view class="logo-title"> <view class="logo-title">
<text class="uer-name">{{userInfo.nickname||userInfo.username||userInfo.mobile||'未登录'}}</text> <text class="uer-name">{{userInfo.nickname||userInfo.username||userInfo.mobile||'未登录'}}</text>
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
} from 'vuex'; } from 'vuex';
import checkUpdate from '@/uni_modules/uni-upgrade-center-app/utils/check-update'; import checkUpdate from '@/uni_modules/uni-upgrade-center-app/utils/check-update';
import callCheckVersion from '@/uni_modules/uni-upgrade-center-app/utils/call-check-version'; import callCheckVersion from '@/uni_modules/uni-upgrade-center-app/utils/call-check-version';
import uniShare from 'uni_modules/uni-share/js_sdk/uni-share.js'; import uniShare from '@/uni_modules/uni-share/js_sdk/uni-share.js';
const db = uniCloud.database(); const db = uniCloud.database();
export default { export default {
...@@ -60,11 +60,11 @@ ...@@ -60,11 +60,11 @@
} }
], ],
ucenterList: [ ucenterList: [
[ [
{ {
"title": '签到有奖', "title": '签到有奖',
"event": 'signIn', "event": 'signIn',
"icon": "compose" "icon": "compose"
}, },
// #ifdef APP-PLUS // #ifdef APP-PLUS
{ {
...@@ -83,13 +83,13 @@ ...@@ -83,13 +83,13 @@
"to": '', "to": '',
"event": 'getScore', "event": 'getScore',
"icon": "paperplane" "icon": "paperplane"
} }
// #ifdef APP-PLUS // #ifdef APP-PLUS
,{ ,{
"title": '分销推荐', "title": '分销推荐',
"event": 'share', "event": 'share',
"icon": "redo" "icon": "redo"
} }
// #endif // #endif
], ],
[{ [{
...@@ -106,16 +106,16 @@ ...@@ -106,16 +106,16 @@
"to": '/pages/ucenter/about/about', "to": '/pages/ucenter/about/about',
"icon": "info" "icon": "info"
}] }]
], ],
listStyles: { listStyles: {
"height": "150rpx", // 边框高度 "height": "150rpx", // 边框高度
"width": "150rpx", // 边框宽度 "width": "150rpx", // 边框宽度
"border": { // 如果为 Boolean 值,可以控制边框显示与否 "border": { // 如果为 Boolean 值,可以控制边框显示与否
"color": "#eee", // 边框颜色 "color": "#eee", // 边框颜色
"width": "1px", // 边框宽度 "width": "1px", // 边框宽度
"style": "solid", // 边框样式 "style": "solid", // 边框样式
"radius": "100%" // 边框圆角,支持百分比 "radius": "100%" // 边框圆角,支持百分比
} }
} }
} }
}, },
...@@ -154,9 +154,9 @@ ...@@ -154,9 +154,9 @@
uni.navigateTo({ uni.navigateTo({
url: "/pages/ucenter/settings/settings" url: "/pages/ucenter/settings/settings"
}) })
}, },
signIn(){ //签到 signIn(){ //签到
this.$refs.signIn.open() this.$refs.signIn.open()
}, },
/** /**
* 个人中心项目列表点击事件 * 个人中心项目列表点击事件
...@@ -220,8 +220,8 @@ ...@@ -220,8 +220,8 @@
uni.showLoading({ uni.showLoading({
mask: true mask: true
}) })
db.collection("uni-id-scores").where('"user_id" == $env.uid').field('score,balance').get().then((res) => { db.collection("uni-id-scores").where('"user_id" == $env.uid').field('score,balance').get().then((res) => {
uni.hideLoading() uni.hideLoading()
console.log(res); console.log(res);
const data = res.result.data[0]; const data = res.result.data[0];
let msg = ''; let msg = '';
...@@ -238,7 +238,7 @@ ...@@ -238,7 +238,7 @@
data: { data: {
action: 'getUserInviteCode' action: 'getUserInviteCode'
} }
}) })
console.log(result); console.log(result);
let myInviteCode = result.myInviteCode || result.userInfo.my_invite_code let myInviteCode = result.myInviteCode || result.userInfo.my_invite_code
console.log(myInviteCode); console.log(myInviteCode);
...@@ -247,69 +247,70 @@ ...@@ -247,69 +247,70 @@
logo, logo,
company, company,
slogan slogan
} = this.appConfig.about } = this.appConfig.about
// #ifdef APP-PLUS // #ifdef APP-PLUS
uniShare({ uniShare({
content: { //公共的分享类型(type)、链接(herf)、标题(title)、summary(描述)、imageUrl(缩略图) content: { //公共的分享类型(type)、链接(herf)、标题(title)、summary(描述)、imageUrl(缩略图)
type: 0, type: 0,
href: this.appConfig.h5.url + href: this.appConfig.h5.url +
`/#/pages/ucenter/invite/invite?code=uniInvitationCode:${myInviteCode}`, `/#/pages/ucenter/invite/invite?code=uniInvitationCode:${myInviteCode}`,
title: appName, title: appName,
summary: slogan, summary: slogan,
imageUrl: logo + '?x-oss-process=image/resize,m_fill,h_100,w_100' //压缩图片解决,在ios端分享图过大导致的图片失效问题 imageUrl: logo + '?x-oss-process=image/resize,m_fill,h_100,w_100' //压缩图片解决,在ios端分享图过大导致的图片失效问题
}, },
menus: [{ menus: [{
"img": "/static/app-plus/sharemenu/wechatfriend.png", "img": "/static/app-plus/sharemenu/wechatfriend.png",
"text": "微信好友", "text": "微信好友",
"share": { "share": {
"provider": "weixin", "provider": "weixin",
"scene": "WXSceneSession" "scene": "WXSceneSession"
} }
}, },
{ {
"img": "/static/app-plus/sharemenu/wechatmoments.png", "img": "/static/app-plus/sharemenu/wechatmoments.png",
"text": "微信朋友圈", "text": "微信朋友圈",
"share": { "share": {
"provider": "weixin", "provider": "weixin",
"scene": "WXSenceTimeline" "scene": "WXSenceTimeline"
} }
}, },
{ {
"img": "/static/app-plus/sharemenu/weibo.png", "img": "/static/app-plus/sharemenu/weibo.png",
"text": "微博", "text": "微博",
"share": { "share": {
"provider": "sinaweibo" "provider": "sinaweibo"
} }
}, },
{ {
"img": "/static/app-plus/sharemenu/qq.png", "img": "/static/app-plus/sharemenu/qq.png",
"text": "QQ", "text": "QQ",
"share": { "share": {
"provider": "qq" "provider": "qq"
} }
}, },
{ {
"img": "/static/app-plus/sharemenu/copyurl.png", "img": "/static/app-plus/sharemenu/copyurl.png",
"text": "复制", "text": "复制",
"share": "copyurl" "share": "copyurl"
}, },
{ {
"img": "/static/app-plus/sharemenu/more.png", "img": "/static/app-plus/sharemenu/more.png",
"text": "更多", "text": "更多",
"share": "shareSystem" "share": "shareSystem"
} }
], ],
cancelText: "取消分享", cancelText: "取消分享",
}, e => { //callback }, e => { //callback
console.log(e); console.log(e);
}) })
// #endif // #endif
} }
} }
} }
</script> </script>
<style> <style lang="scss" scoped>
@import '@/common/all-flex.css';
/* #ifndef APP-PLUS-NVUE */ /* #ifndef APP-PLUS-NVUE */
page { page {
background-color: #f8f8f8; background-color: #f8f8f8;
...@@ -375,7 +376,7 @@ ...@@ -375,7 +376,7 @@
color: #817f82; color: #817f82;
} }
.uni-grid .item /deep/ .uni-grid-item__box { .uni-grid .item ::v-deep .uni-grid-item__box {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
...@@ -383,14 +384,14 @@ ...@@ -383,14 +384,14 @@
/*修改边线粗细示例*/ /*修改边线粗细示例*/
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
.center-list /deep/ .uni-list--border:after { .center-list ::v-deep .uni-list--border:after {
-webkit-transform: scaleY(0.2); -webkit-transform: scaleY(0.2);
transform: scaleY(0.2); transform: scaleY(0.2);
margin-left: 80rpx; margin-left: 80rpx;
} }
.center-list /deep/ .uni-list--border-top, .center-list ::v-deep .uni-list--border-top,
.center-list /deep/ .uni-list--border-bottom { .center-list ::v-deep .uni-list--border-bottom {
display: none; display: none;
} }
...@@ -417,4 +418,4 @@ ...@@ -417,4 +418,4 @@
/* #endif */ /* #endif */
background-color: #DD524D; background-color: #DD524D;
} }
</style> </style>
...@@ -81,11 +81,11 @@ ...@@ -81,11 +81,11 @@
padding: 50rpx; padding: 50rpx;
padding-top: 10px; padding-top: 10px;
} }
/* #ifndef APP-NVUE || VUE3 */
.box /deep/ .uni-easyinput__content { .box /deep/ .uni-easyinput__content {
height: 50px; height: 50px;
} }
/* #endif */
.input-box { .input-box {
width: 100%; width: 100%;
margin-top: 16px; margin-top: 16px;
......
...@@ -30,11 +30,11 @@ ...@@ -30,11 +30,11 @@
</view> </view>
<view v-if="isShowPhotoBtn" @tap="uploadImage"> <view v-if="isShowPhotoBtn" @tap="uploadImage">
<slot name="photo" v-if="$slots.photo" /> <slot name="photo" v-if="$slots.photo" />
<image v-else :src="require('./images/photo.svg')" /> <image v-else src="@/static/limeClipper/photo.svg" />
</view> </view>
<view v-if="isShowRotateBtn" @tap="rotate"> <view v-if="isShowRotateBtn" @tap="rotate">
<slot name="rotate" v-if="$slots.rotate" /> <slot name="rotate" v-if="$slots.rotate" />
<image v-else :src="require('./images/rotate.svg')" data-type="inverse" /> <image v-else src="@/static/limeClipper/rotate.svg" data-type="inverse" />
</view> </view>
<view v-if="isShowConfirmBtn" @tap="confirm"> <view v-if="isShowConfirmBtn" @tap="confirm">
<slot name="confirm" v-if="$slots.confirm" /> <slot name="confirm" v-if="$slots.confirm" />
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
</template> </template>
<script> <script>
import { pathToBase64, determineDirection, calcImageOffset, calcImageScale, calcImageSize, calcPythagoreanTheorem, clipTouchMoveOfCalculate, imageTouchMoveOfCalcOffset } from './utils'; import { determineDirection, calcImageOffset, calcImageScale, calcImageSize, calcPythagoreanTheorem, clipTouchMoveOfCalculate, imageTouchMoveOfCalcOffset } from './utils';
const cache = {} const cache = {}
export default { export default {
// version: '0.6.3', // version: '0.6.3',
......
<template> <template>
<view> <view>
<uni-list> <uni-list>
<uni-list-item class="item"> <uni-list-item class="item">
<view slot="body" class="item"> <template v-slot:body>
<text>头像</text> <view class="item">
<uni-file-picker @click.native="uploadAvatarImg" @delete="removeAvatar" v-model="avatar_file" <text>头像</text>
fileMediatype="image" return-type="object" :image-styles="listStyles" <uni-file-picker @click.native="uploadAvatarImg" @delete="removeAvatar" v-model="avatar_file"
disabled /> fileMediatype="image" return-type="object" :image-styles="listStyles" disabled />
</view> </view>
</template>
</uni-list-item> </uni-list-item>
<uni-list-item class="item" @click="setNickname('')" title="昵称" :rightText="userInfo.nickname||'未设置'" link> <uni-list-item class="item" @click="setNickname('')" title="昵称" :rightText="userInfo.nickname||'未设置'" link>
</uni-list-item> </uni-list-item>
...@@ -56,8 +57,8 @@ ...@@ -56,8 +57,8 @@
userInfo: 'user/info', userInfo: 'user/info',
login: 'user/hasLogin' login: 'user/hasLogin'
}), }),
avatar_file(){ avatar_file() {
if(this.userInfo.avatar_file&&this.userInfo.avatar_file.url){ if (this.userInfo.avatar_file && this.userInfo.avatar_file.url) {
return this.userInfo.avatar_file return this.userInfo.avatar_file
} }
} }
...@@ -156,7 +157,7 @@ ...@@ -156,7 +157,7 @@
this.$refs.dialog.open() this.$refs.dialog.open()
} }
}, },
removeAvatar(){ removeAvatar() {
this.setAvatarFile({ this.setAvatarFile({
"extname": "jpg", "extname": "jpg",
"fileType": "image", "fileType": "image",
...@@ -165,7 +166,7 @@ ...@@ -165,7 +166,7 @@
"url": "" "url": ""
}) })
}, },
setAvatarFile(avatar_file){ setAvatarFile(avatar_file) {
uni.showLoading({ uni.showLoading({
title: '设置中', title: '设置中',
mask: true mask: true
...@@ -175,12 +176,12 @@ ...@@ -175,12 +176,12 @@
avatar_file avatar_file
}).then((res) => { }).then((res) => {
console.log(res); console.log(res);
if(avatar_file){ if (avatar_file) {
uni.showToast({ uni.showToast({
icon: 'none', icon: 'none',
title: '设置成功' title: '设置成功'
}) })
}else{ } else {
uni.showToast({ uni.showToast({
icon: 'none', icon: 'none',
title: '删除成功' title: '删除成功'
...@@ -207,19 +208,20 @@ ...@@ -207,19 +208,20 @@
resize: true resize: true
}; };
uni.chooseImage({ uni.chooseImage({
count: 1,crop, count: 1,
crop,
success: async (res) => { success: async (res) => {
console.log(res); console.log(res);
let tempFile = res.tempFiles[0], let tempFile = res.tempFiles[0],
avatar_file = { avatar_file = {
// #ifdef H5 // #ifdef H5
extname:tempFile.name.split('.')[tempFile.name.split('.').length-1], extname: tempFile.name.split('.')[tempFile.name.split('.').length - 1],
// #endif // #endif
// #ifndef H5 // #ifndef H5
extname:tempFile.path.split('.')[tempFile.path.split('.').length-1] extname: tempFile.path.split('.')[tempFile.path.split('.').length - 1]
// #endif // #endif
}, },
filePath = res.tempFilePaths[0] filePath = res.tempFilePaths[0]
// #ifndef APP-PLUS // #ifndef APP-PLUS
//非app端用前端组件剪裁头像,app端用内置的原生裁剪 //非app端用前端组件剪裁头像,app端用内置的原生裁剪
filePath = await new Promise((callback) => { filePath = await new Promise((callback) => {
...@@ -228,7 +230,7 @@ ...@@ -228,7 +230,7 @@
`&options=${JSON.stringify(crop)}`, `&options=${JSON.stringify(crop)}`,
animationType: "fade-in", animationType: "fade-in",
events: { events: {
success: url=> { success: url => {
callback(url) callback(url)
} }
} }
...@@ -236,21 +238,26 @@ ...@@ -236,21 +238,26 @@
}) })
// #endif // #endif
console.log(this.userInfo); console.log(this.userInfo);
let cloudPath = this.userInfo._id+''+Date.now() let cloudPath = this.userInfo._id + '' + Date.now()
avatar_file.name = cloudPath avatar_file.name = cloudPath
uni.showLoading({ uni.showLoading({
title: '正在上传', title: '正在上传',
mask: true mask: true
}); });
let {fileID} = await uniCloud.uploadFile({ let {
filePath,cloudPath, fileID
fileType:"image" } = await uniCloud.uploadFile({
filePath,
cloudPath,
fileType: "image"
}); });
// console.log(result) // console.log(result)
avatar_file.url = fileID avatar_file.url = fileID
console.log({avatar_file}); console.log({
avatar_file
});
uni.hideLoading() uni.hideLoading()
this.setAvatarFile(avatar_file) this.setAvatarFile(avatar_file)
} }
}) })
...@@ -258,7 +265,8 @@ ...@@ -258,7 +265,8 @@
} }
} }
</script> </script>
<style> <style lang="scss" scoped>
@import '@/common/all-flex.css';
.item { .item {
width: 750rpx; width: 750rpx;
flex-direction: row; flex-direction: row;
...@@ -279,4 +287,4 @@ ...@@ -279,4 +287,4 @@
height: 130rpx; height: 130rpx;
line-height: 130rpx; line-height: 130rpx;
} }
</style> </style>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;" xml:space="preserve">
<style type="text/css">
.st0{fill:#606060;}
.st1{fill:none;stroke:#FFFFFF;stroke-width:2.4306;stroke-miterlimit:10;}
.st2{fill:#FFFFFF;}
</style>
<g>
<path class="st2" d="M11.6,11c0.4,0.4,0.6,0.9,0.6,1.5c0,0.6-0.2,1.1-0.6,1.4c-0.4,0.4-0.9,0.6-1.5,0.6c-0.6,0-1.1-0.2-1.5-0.6
c-0.4-0.4-0.6-0.9-0.6-1.4s0.2-1.1,0.6-1.5c0.4-0.4,0.9-0.6,1.5-0.6C10.8,10.4,11.2,10.6,11.6,11z M24.6,18.4V6.7H5.4v12l1.8-1.8
c0.3-0.3,0.6-0.4,1-0.4c0.4,0,0.7,0.1,1,0.4l1.8,1.8l5.8-7c0.3-0.3,0.6-0.5,1.1-0.5c0.4,0,0.8,0.2,1.1,0.5
C18.8,11.6,24.6,18.4,24.6,18.4z M25.6,5.7C25.9,6,26,6.3,26,6.7v16.1c0,0.4-0.1,0.7-0.4,1c-0.3,0.3-0.6,0.4-1,0.4H5.4
c-0.4,0-0.7-0.1-1-0.4c-0.3-0.3-0.4-0.6-0.4-1V6.7c0-0.4,0.1-0.7,0.4-1c0.3-0.3,0.6-0.4,1-0.4h19.3C25,5.3,25.3,5.4,25.6,5.7z"/>
<path class="st1" d="M24.3,21.5H5.7c-0.2,0-0.3-0.2-0.3-0.3V7c0-0.2,0.2-0.3,0.3-0.3h18.6c0.2,0,0.3,0.2,0.3,0.3v14.2
C24.6,21.3,24.5,21.5,24.3,21.5z"/>
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="30px" height="30px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#FFFFFF;stroke-width:2.4306;stroke-miterlimit:10;}
.st1{fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M17.1,24.2h-12c-0.2,0-0.3-0.2-0.3-0.3v-9.3c0-0.2,0.2-0.3,0.3-0.3h12c0.2,0,0.3,0.2,0.3,0.3v9.3
C17.5,24.1,17.3,24.2,17.1,24.2z"/>
<path class="st0" d="M16.6,5.4c4.8,0,8.7,3.9,8.7,8.7"/>
<polyline class="st0" points="19.3,10.1 14.9,5.6 19.3,1.2 "/>
</g>
</svg>
import Vue from 'vue' import user from '@/store/modules/user.js'
import Vuex from 'vuex'
// #ifndef VUE3
const modulesFiles = require.context('./modules', false, /\.js$/) import Vue from 'vue'
import Vuex from 'vuex'
const modules = modulesFiles.keys().reduce((modules, modulePath) => { Vue.use(Vuex)
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1') const store = new Vuex.Store({
const value = modulesFiles(modulePath) modules: {
modules[moduleName] = value.default user
modules[moduleName]['namespaced'] = true; },
return modules strict: true
}, {}) })
Vue.use(Vuex) // #endif
const store = new Vuex.Store({ // #ifdef VUE3
modules, import {createStore} from 'vuex'
strict: true const store = createStore({
}) modules: {
user
}
})
// #endif
export default store export default store
\ No newline at end of file
...@@ -40,6 +40,7 @@ let state = { ...@@ -40,6 +40,7 @@ let state = {
} }
export default { export default {
namespaced: true,
state, state,
getters, getters,
mutations, mutations,
......
//这是应用的配置页面,App.vue挂载到getApp().globalData.config //这是应用的配置页面,App.vue挂载到getApp().globalData.config
module.exports = { export default {
"h5": { "h5": {
"url": "https://uni-starter.dcloud.net.cn", // 前端网页托管的域名 "url": "https://uni-starter.dcloud.net.cn", // 前端网页托管的域名
// 在h5端全局悬浮引导用户下载app的功能 更多自定义要求在/common/openApp.js中修改 // 在h5端全局悬浮引导用户下载app的功能 更多自定义要求在/common/openApp.js中修改
......
{ {
"bsonType": "object", "bsonType": "object",
"permission":{ "permission":{
"update":"doc.uid==auth.uid" "update":"doc._id == auth.uid"
}, },
"required": [], "required": [],
"properties": { "properties": {
......
## 1.0.6(2021-02-04) ## 1.1.3(2021-06-24)
- 调整为uni_modules目录规范 - 优化 示例项目
## 1.1.1(2021-05-12)
- 新增 组件示例地址
## 1.1.0(2021-05-12)
- 新增 uni-badge 的 absolute 属性,支持定位
- 新增 uni-badge 的 offset 属性,支持定位偏移
- 新增 uni-badge 的 is-dot 属性,支持仅显示有一个小点
- 新增 uni-badge 的 max-num 属性,支持自定义封顶的数字值,超过 99 显示99+
- 优化 uni-badge 属性 custom-style, 支持以对象形式自定义样式
## 1.0.7(2021-05-07)
- 修复 uni-badge 在 App 端,数字小于10时不是圆形的bug
- 修复 uni-badge 在父元素不是 flex 布局时,宽度缩小的bug
- 新增 uni-badge 属性 custom-style, 支持自定义样式
## 1.0.6(2021-02-04)
- 调整为uni_modules目录规范
<template> <template>
<text v-if="text" :class="inverted ? 'uni-badge--' + type + ' uni-badge--' + size + ' uni-badge--' + type + '-inverted' : 'uni-badge--' + type + ' uni-badge--' + size" <view class="uni-badge--x">
:style="badgeStyle" class="uni-badge" @click="onClick()">{{ text }}</text> <slot />
<text v-if="text" :class="classNames" :style="[badgeWidth, positionStyle, customStyle, dotStyle]"
class="uni-badge"
@click="onClick()">{{displayValue}}</text>
</view>
</template> </template>
<script> <script>
...@@ -33,6 +37,24 @@ ...@@ -33,6 +37,24 @@
type: Boolean, type: Boolean,
default: false default: false
}, },
isDot: {
type: Boolean,
default: false
},
maxNum: {
type: Number,
default: 99
},
absolute: {
type: String,
default: ''
},
offset: {
type: Array,
default () {
return [0, 0]
}
},
text: { text: {
type: [String, Number], type: [String, Number],
default: '' default: ''
...@@ -40,25 +62,86 @@ ...@@ -40,25 +62,86 @@
size: { size: {
type: String, type: String,
default: 'normal' default: 'normal'
},
customStyle: {
type: Object,
default () {
return {}
}
} }
}, },
data() { data() {
return { return {};
badgeStyle: ''
};
}, },
watch: { computed: {
text() { width() {
this.setStyle() return String(this.text).length * 8 + 12
},
classNames() {
const {
inverted,
type,
size,
absolute
} = this
return [
inverted ? 'uni-badge--' + type + '-inverted' : '',
'uni-badge--' + type,
'uni-badge--' + size,
absolute ? 'uni-badge--absolute' : ''
]
},
positionStyle() {
if (!this.absolute) return {}
let w = this.width / 2,
h = 10
if (this.isDot) {
w = 5
h = 5
}
const x = `${- w + this.offset[0]}px`
const y = `${- h + this.offset[1]}px`
const whiteList = {
rightTop: {
right: x,
top: y
},
rightBottom: {
right: x,
bottom: y
},
leftBottom: {
left: x,
bottom: y
},
leftTop: {
left: x,
top: y
}
}
const match = whiteList[this.absolute]
return match ? match : whiteList['rightTop']
},
badgeWidth() {
return {
width: `${this.width}px`
}
},
dotStyle() {
if (!this.isDot) return {}
return {
width: '10px',
height: '10px',
borderRadius: '10px'
}
},
displayValue() {
const { isDot, text, maxNum } = this
return isDot ? '' : (Number(text) > maxNum ? `${maxNum}+` : text)
} }
}, },
mounted() {
this.setStyle()
},
methods: { methods: {
setStyle() {
this.badgeStyle = `width: ${String(this.text).length * 8 + 12}px`
},
onClick() { onClick() {
this.$emit('click'); this.$emit('click');
} }
...@@ -71,11 +154,25 @@ ...@@ -71,11 +154,25 @@
$bage-small: scale(0.8); $bage-small: scale(0.8);
$bage-height: 20px; $bage-height: 20px;
.uni-badge--x {
/* #ifdef APP-NVUE */
align-self: flex-start;
/* #endif */
/* #ifndef APP-NVUE */
display: inline-block;
/* #endif */
position: relative;
}
.uni-badge--absolute {
position: absolute;
}
.uni-badge { .uni-badge {
/* #ifndef APP-PLUS */ /* #ifndef APP-NVUE */
display: flex; display: flex;
box-sizing: border-box;
overflow: hidden; overflow: hidden;
box-sizing: border-box;
/* #endif */ /* #endif */
justify-content: center; justify-content: center;
flex-direction: row; flex-direction: row;
...@@ -88,9 +185,8 @@ ...@@ -88,9 +185,8 @@
text-align: center; text-align: center;
font-family: 'Helvetica Neue', Helvetica, sans-serif; font-family: 'Helvetica Neue', Helvetica, sans-serif;
font-size: $bage-size; font-size: $bage-size;
padding: 0px 6px; /* #ifdef H5 */
/* #ifdef H5 */ cursor: pointer;
cursor: pointer;
/* #endif */ /* #endif */
} }
......
{ {
"id": "uni-badge", "id": "uni-badge",
"displayName": "Badge 数字角标", "displayName": "uni-badge 数字角标",
"version": "1.0.6", "version": "1.1.3",
"description": "数字角标(徽章)组件,在元素周围展示消息提醒,一般用于列表、九宫格、按钮等地方。", "description": "数字角标(徽章)组件,在元素周围展示消息提醒,一般用于列表、九宫格、按钮等地方。",
"keywords": [ "keywords": [
"", "",
"badge", "badge",
"uni-ui", "uni-ui",
"数字角标", "uniui",
"徽章" "数字角标",
], "徽章"
"repository": "https://github.com/dcloudio/uni-ui", ],
"engines": { "repository": "https://github.com/dcloudio/uni-ui",
"HBuilderX": "" "engines": {
}, "HBuilderX": ""
"directories": { },
"example": "../../temps/example" "directories": {
}, "example": "../../temps/example"
"dcloudext": { },
"category": [ "dcloudext": {
"前端组件", "category": [
"通用组件" "前端组件",
], "通用组件"
"sale": { ],
"regular": { "sale": {
"price": "0.00" "regular": {
}, "price": "0.00"
"sourcecode": { },
"price": "0.00" "sourcecode": {
} "price": "0.00"
}, }
"contact": { },
"qq": "" "contact": {
}, "qq": ""
"declaration": { },
"ads": "无", "declaration": {
"data": "无", "ads": "无",
"permissions": "无" "data": "无",
}, "permissions": "无"
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" },
}, "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
"uni_modules": { },
"dependencies": [], "uni_modules": {
"encrypt": [], "dependencies": [],
"platforms": { "encrypt": [],
"cloud": { "platforms": {
"tcb": "y", "cloud": {
"aliyun": "y" "tcb": "y",
}, "aliyun": "y"
"client": { },
"App": { "client": {
"app-vue": "u", "App": {
"app-nvue": "u" "app-vue": "y",
}, "app-nvue": "y"
"H5-mobile": { },
"Safari": "u", "H5-mobile": {
"Android Browser": "u", "Safari": "y",
"微信浏览器(Android)": "u", "Android Browser": "y",
"QQ浏览器(Android)": "u" "微信浏览器(Android)": "y",
}, "QQ浏览器(Android)": "y"
"H5-pc": { },
"Chrome": "u", "H5-pc": {
"IE": "u", "Chrome": "y",
"Edge": "u", "IE": "y",
"Firefox": "u", "Edge": "y",
"Safari": "u" "Firefox": "y",
}, "Safari": "y"
"小程序": { },
"微信": "u", "小程序": {
"阿里": "u", "微信": "y",
"百度": "u", "阿里": "y",
"字节跳动": "u", "百度": "y",
"QQ": "u" "字节跳动": "y",
}, "QQ": "y"
"快应用": { },
"华为": "u", "快应用": {
"联盟": "u" "华为": "y",
} "联盟": "y"
} }
} }
} }
}
} }
\ No newline at end of file
## Badge 数字角标 ## Badge 数字角标
> **组件名:uni-badge**
> 代码块: `uBadge` > 代码块: `uBadge`
...@@ -17,9 +18,13 @@ ...@@ -17,9 +18,13 @@
``template`` 中使用组件 ``template`` 中使用组件
```html ```html
<uni-badge size="small" :text="100" absolute="rightBottom" type="primary">
<button type="default">右上</button>
</uni-badge>
<uni-badge text="1"></uni-badge> <uni-badge text="1"></uni-badge>
<uni-badge text="2" type="purple" @click="bindClick"></uni-badge> <uni-badge text="2" type="purple" @click="bindClick"></uni-badge>
<uni-badge text="3" type="primary" :inverted="true"></uni-badge> <uni-badge text="3" type="primary" :inverted="true"></uni-badge>
``` ```
...@@ -27,12 +32,17 @@ ...@@ -27,12 +32,17 @@
### Badge Props ### Badge Props
|属性名 |类型 |默认值 |说明 | |属性名 |类型 |默认值 |说明 |
|:-: |:-: |:-: |:-: | |:-: |:-: |:-: |:-: |
|text |String |- |角标内容 | |text |String |- |角标内容 |
|type |String |default|颜色类型,可选值:default(灰色)、primary(蓝色)、success(绿色)、warning(黄色)、error(红色)| |type |String |default|颜色类型,可选值:default(灰色)、primary(蓝色)、success(绿色)、warning(黄色)、error(红色)|
|size |String |normal|Badge 大小,可取值:normal、small| |size |String |normal |Badge 大小,可取值:normal、small |
|inverted |Boolean |false |是否无需背景颜色,为 true 时,背景颜色将变为文字的字体颜色 | |is-dot |Boolean|false |不展示数字,只有一个小点 |
|max-num |String/Numbuer|99 |展示封顶的数字值,超过 99 显示99+ |
|custom-style |Object | {} |自定义 Badge 样式, 样式对象语法 |
|inverted |Boolean|false |是否无需背景颜色,为 true 时,背景颜色将变为文字的字体颜色 |
|absolute |String| rightTop|开启绝对定位, 角标将定位到其包裹的标签的四个角上,可选值: rightTop(右上角)、rightBottom(右下角)、leftBottom(左下角) 、leftTop(左上角) |
|offset |Array[number]| [0, 0]|距定位角中心点的偏移量,[-10, -10] 表示向 absolute 指定的方向偏移 10px,[10, 10] 表示向 absolute 指定的反方向偏移 10px,只有存在 absolute 属性时有效,与absolute 的值一一对应(例如:值为rightTop, 对应 offset 为 [right, Top])|
### Badge Events ### Badge Events
...@@ -41,3 +51,8 @@ ...@@ -41,3 +51,8 @@
|@click |点击 Badge 触发事件| - | |@click |点击 Badge 触发事件| - |
## 组件示例
点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/badge/badge](https://hellouniapp.dcloud.net.cn/pages/extUI/badge/badge)
\ No newline at end of file
## 1.1.6(2021-02-04) ## 1.2.0(2021-07-13)
- 调整为uni_modules目录规范 - 组件兼容 vue3,如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.8(2021-07-01)
- 优化 图文卡片无图片加载时,提供占位图标
- 新增 header 插槽,自定义卡片头部( 图文卡片 mode="style" 时,不支持)
- 修复 thumbnail 不存在仍然占位的 bug
## 1.1.7(2021-05-12)
- 新增 组件示例地址
## 1.1.6(2021-02-04)
- 调整为uni_modules目录规范
<template> <template>
<view class="uni-card uni-border" :class="{ 'uni-card--full': isFull === true || isFull === 'true', 'uni-card--shadow': isShadow === true || isShadow === 'true'}"> <view class="uni-card uni-border"
<!-- 基础 --> :class="{ 'uni-card--full': isFull === true || isFull === 'true', 'uni-card--shadow': isShadow === true || isShadow === 'true'}">
<view v-if="mode === 'basic' && title" class="uni-card__header uni-border-bottom" @click.stop="onClick"> <!-- 基础 -->
<view v-if="thumbnail" class="uni-card__header-extra-img-view"> <view v-if="mode === 'basic' && title" @click.stop="onClick" class="uni-card__head-padding">
<image :src="thumbnail" class="uni-card__header-extra-img" /> <view class="uni-card__header uni-border-bottom">
<slot name="header">
<view v-if="thumbnail" class="uni-card__header-extra-img-view">
<image :src="thumbnail" class="uni-card__header-extra-img" />
</view>
<text class="uni-card__header-title-text">{{ title }}</text>
<text v-if="extra" class="uni-card__header-extra-text">{{ extra }}</text>
</slot>
</view>
</view>
<!-- 标题 -->
<view v-if="mode === 'title'" @click.stop="onClick" class="uni-card__head-padding">
<view class="uni-card__title uni-border-bottom">
<slot name="header">
<view class="uni-card__title-box">
<view v-if="thumbnail" class="uni-card__title-header">
<image class="uni-card__title-header-image" :src="thumbnail" mode="scaleToFill" />
</view>
<view class="uni-card__title-content">
<text class="uni-card__title-content-title uni-ellipsis">{{ title }}</text>
<text class="uni-card__title-content-extra uni-ellipsis">{{ subTitle }}</text>
</view>
</view>
<view v-if="extra">
<text class="uni-card__header-extra-text">{{ extra }}</text>
</view>
</slot>
</view>
</view>
<!-- 图文 -->
<view v-if="mode === 'style'" class="uni-card__thumbnailimage" @click.stop="onClick">
<view class="uni-card__thumbnailimage-box">
<image v-if="thumbnail" class="uni-card__thumbnailimage-image" :src="thumbnail" mode="aspectFill" />
<uni-icons v-if="!thumbnail" type="image" size="30" color="#999" />
</view> </view>
<text class="uni-card__header-title-text">{{ title }}</text> <view v-if="title" class="uni-card__thumbnailimage-title">
<text v-if="extra" class="uni-card__header-extra-text">{{ extra }}</text> <text class="uni-card__thumbnailimage-title-text">{{ title }}</text>
</view> </view>
<!-- 标题 --> </view>
<view v-if="mode === 'title'" class="uni-card__title uni-border-bottom" @click.stop="onClick"> <!-- 内容 -->
<view class="uni-card__title-box"> <view class="uni-card__content uni-card__content--pd" @click.stop="onClick">
<view class="uni-card__title-header"> <view v-if="mode === 'style' && extra" class=""><text class="uni-card__content-extra">{{ extra }}</text>
<image class="uni-card__title-header-image" :src="thumbnail" mode="scaleToFill" /> </view>
</view> <slot />
<view class="uni-card__title-content"> </view>
<text class="uni-card__title-content-title uni-ellipsis">{{ title }}</text> <!-- 底部 -->
<text class="uni-card__title-content-extra uni-ellipsis">{{ subTitle }}</text> <view v-if="note" class="uni-card__footer uni-border-top">
</view> <slot name="footer">
</view> <text class="uni-card__footer-text">{{ note }}</text>
<view v-if="extra"> </slot>
<text class="uni-card__header-extra-text">{{ extra }}</text> </view>
</view> </view>
</view> </template>
<!-- 图文 -->
<view v-if="mode === 'style'" class="uni-card__thumbnailimage" @click.stop="onClick"> <script>
<view class="uni-card__thumbnailimage-box"> /**
<image class="uni-card__thumbnailimage-image" :src="thumbnail" mode="aspectFill" /> * Card 卡片
</view> * @description 卡片视图组件
<view v-if="title" class="uni-card__thumbnailimage-title"><text class="uni-card__thumbnailimage-title-text">{{ title }}</text></view> * @tutorial https://ext.dcloud.net.cn/plugin?id=22
</view> * @property {String} title 标题文字
<!-- 内容 --> * @property {String} subTitle 副标题(仅仅mode=title下生效)
<view class="uni-card__content uni-card__content--pd" @click.stop="onClick"> * @property {String} extra 标题额外信息
<view v-if="mode === 'style' && extra" class=""><text class="uni-card__content-extra">{{ extra }}</text></view> * @property {String} note 底部信息
<slot /> * @property {String} thumbnail 标题左侧缩略图
</view> * @property {String} mode = [basic|style|title] 卡片模式
<!-- 底部 --> * @value basic 基础卡片
<view v-if="note" class="uni-card__footer uni-border-top"> * @value style 图文卡片
<slot name="footer"> * @value title 标题卡片
<text class="uni-card__footer-text">{{ note }}</text> * @property {Boolean} isFull = [true | false] 卡片内容是否通栏,为 true 时将去除padding值
</slot> * @property {Boolean} isShadow = [true | false] 卡片内容是否开启阴影
</view> * @event {Function} click 点击 Card 触发事件
</view> * @example <uni-card title="标题文字" thumbnail="xxx.jpg" extra="额外信息" note="Tips">内容主体,可自定义内容及样式</uni-card>
</template> */
export default {
<script> name: 'UniCard',
/** props: {
* Card 卡片 title: {
* @description 卡片视图组件 type: String,
* @tutorial https://ext.dcloud.net.cn/plugin?id=22 default: ''
* @property {String} title 标题文字 },
* @property {String} subTitle 副标题(仅仅mode=title下生效) subTitle: {
* @property {String} extra 标题额外信息 type: String,
* @property {String} note 标题左侧缩略图 default: ''
* @property {String} thumbnail 底部信息 },
* @property {String} mode = [basic|style|title] 卡片模式 extra: {
* @value basic 基础卡片 type: String,
* @value style 图文卡片 default: ''
* @value title 标题卡片 },
* @property {Boolean} isFull = [true | false] 卡片内容是否通栏,为 true 时将去除padding值 note: {
* @property {Boolean} isShadow = [true | false] 卡片内容是否开启阴影 type: String,
* @event {Function} click 点击 Card 触发事件 default: ''
* @example <uni-card title="标题文字" thumbnail="xxx.jpg" extra="额外信息" note="Tips">内容主体,可自定义内容及样式</uni-card> },
*/ thumbnail: {
export default { type: String,
name: 'UniCard', default: ''
props: { },
title: { mode: {
type: String, type: String,
default: '' default: 'basic'
}, },
subTitle: { isFull: {
type: String, // 内容区域是否通栏
default: '' type: Boolean,
}, default: false
extra: { },
type: String, isShadow: {
default: '' // 是否开启阴影
}, type: [Boolean, String],
note: { default: false
type: String, }
default: '' },
}, methods: {
thumbnail: { onClick() {
type: String, this.$emit('click')
default: '' }
}, }
mode: { }
type: String, </script>
default: 'basic'
}, <style lang="scss" scoped>
isFull: { .uni-card {
// 内容区域是否通栏 /* #ifndef APP-NVUE */
type: Boolean, display: flex;
default: false flex: 1;
}, box-shadow: 0 0 0 rgba(0, 0, 0, 0);
isShadow: { /* #endif */
// 是否开启阴影 margin: $uni-spacing-col-lg $uni-spacing-row-lg;
type: [Boolean, String], background-color: $uni-bg-color;
default: false position: relative;
} flex-direction: column;
}, border-radius: 5px;
methods: { overflow: hidden;
onClick() { /* #ifdef H5 */
this.$emit('click') cursor: pointer;
} /* #endif */
} }
}
</script>
<style lang="scss" scoped> .uni-border {
.uni-card { position: relative;
/* #ifndef APP-NVUE */ /* #ifdef APP-NVUE */
display: flex; border-color: $uni-border-color;
flex: 1; border-style: solid;
box-shadow: 0 0 0 rgba(0, 0, 0, 0); border-width: 0.5px;
/* #endif */ /* #endif */
margin: $uni-spacing-col-lg $uni-spacing-row-lg; z-index: 1;
background-color: $uni-bg-color; }
/* #ifndef APP-NVUE */
.uni-border:after {
content: '';
position: absolute;
bottom: 0;
left: 0;
top: 0;
right: 0;
border: 1px solid $uni-border-color;
border-radius: 10px;
box-sizing: border-box;
width: 200%;
height: 200%;
transform: scale(0.5);
transform-origin: left top;
z-index: -1;
}
/* #endif */
.uni-border-bottom {
position: relative;
/* #ifdef APP-NVUE */
border-bottom-color: $uni-border-color;
border-bottom-style: solid;
border-bottom-width: 0.5px;
/* #endif */
z-index: 1;
}
/* #ifndef APP-NVUE */
.uni-border-bottom:after {
content: '';
position: absolute;
bottom: 0;
left: 0;
top: 0;
right: 0;
border-bottom: 1px solid $uni-border-color;
box-sizing: border-box;
width: 200%;
height: 200%;
transform: scale(0.5);
transform-origin: left top;
z-index: -1;
}
/* #endif */
.uni-border-top {
position: relative;
/* #ifdef APP-NVUE */
border-top-color: $uni-border-color;
border-top-style: solid;
border-top-width: 0.5px;
/* #endif */
z-index: 1;
}
/* #ifndef APP-NVUE */
.uni-border-top:after {
content: '';
position: absolute;
bottom: 0;
left: 0;
top: 0;
right: 0;
border-top: 1px solid $uni-border-color;
box-sizing: border-box;
width: 200%;
height: 200%;
transform: scale(0.5);
transform-origin: left top;
z-index: -1;
}
/* #endif */
.uni-card__thumbnailimage {
position: relative; position: relative;
flex-direction: column; /* #ifndef APP-NVUE */
border-radius: 5px; // display: flex;
overflow: hidden;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-border {
position: relative;
/* #ifdef APP-NVUE */
border-color: $uni-border-color;
border-style: solid;
border-width: 0.5px;
/* #endif */
z-index: 1;
}
/* #ifndef APP-NVUE */
.uni-border:after {
content: '';
position: absolute;
bottom: 0;
left: 0;
top: 0;
right: 0;
border: 1px solid $uni-border-color;
border-radius: 10px;
box-sizing: border-box;
width: 200%;
height: 200%;
transform: scale(0.5);
transform-origin: left top;
z-index: -1;
}
/* #endif */
.uni-border-bottom {
position: relative;
/* #ifdef APP-NVUE */
border-bottom-color: $uni-border-color;
border-bottom-style: solid;
border-bottom-width: 0.5px;
/* #endif */
z-index: 1;
}
/* #ifndef APP-NVUE */
.uni-border-bottom:after {
content: '';
position: absolute;
bottom: 0;
left: 0;
top: 0;
right: 0;
border-bottom: 1px solid $uni-border-color;
box-sizing: border-box;
width: 200%;
height: 200%;
transform: scale(0.5);
transform-origin: left top;
z-index: -1;
}
/* #endif */
.uni-border-top {
position: relative;
/* #ifdef APP-NVUE */
border-top-color: $uni-border-color;
border-top-style: solid;
border-top-width: 0.5px;
/* #endif */ /* #endif */
z-index: 1; flex-direction: column;
}
/* #ifndef APP-NVUE */
.uni-border-top:after {
content: '';
position: absolute;
bottom: 0;
left: 0;
top: 0;
right: 0;
border-top: 1px solid $uni-border-color;
box-sizing: border-box;
width: 200%;
height: 200%;
transform: scale(0.5);
transform-origin: left top;
z-index: -1;
}
/* #endif */
.uni-card__thumbnailimage {
position: relative;
flex-direction: column;
justify-content: center; justify-content: center;
height: 150px; height: 150px;
overflow: hidden; background-color: #F1F1F1;
} overflow: hidden;
}
.uni-card__thumbnailimage-box {
/* #ifndef APP-NVUE */ .uni-card__thumbnailimage-box {
display: flex; /* #ifndef APP-NVUE */
/* #endif */ display: flex;
flex: 1; /* #endif */
flex-direction: row;
overflow: hidden;
}
.uni-card__thumbnailimage-image {
flex: 1; flex: 1;
} height: 150px;
.uni-card__thumbnailimage-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
position: absolute;
bottom: 0;
left: 0;
right: 0;
flex-direction: row; flex-direction: row;
padding: $uni-spacing-col-base $uni-spacing-col-lg; justify-content: center;
background-color: $uni-bg-color-mask; align-items: center;
}
.uni-card__thumbnailimage-title-text {
flex: 1;
font-size: $uni-font-size-base;
color: #fff;
}
.uni-card__title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
padding: 10px;
}
.uni-card__title-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
align-items: center;
overflow: hidden;
}
.uni-card__title-header {
width: 40px;
height: 40px;
overflow: hidden; overflow: hidden;
}
.uni-card__thumbnailimage-image {
flex: 1;
}
.uni-card__thumbnailimage-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
position: absolute;
bottom: 0;
left: 0;
right: 0;
flex-direction: row;
padding: $uni-spacing-col-base $uni-spacing-col-lg;
background-color: $uni-bg-color-mask;
}
.uni-card__thumbnailimage-title-text {
flex: 1;
font-size: $uni-font-size-base;
color: #fff;
}
.uni-card__title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
padding: 10px;
}
.uni-card__title-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
align-items: center;
overflow: hidden;
}
.uni-card__title-header {
width: 40px;
height: 40px;
overflow: hidden;
border-radius: 5px; border-radius: 5px;
} padding-right: 10px;
}
.uni-card__title-header-image {
width: 40px; .uni-card__title-header-image {
height: 40px; width: 40px;
}
.uni-card__title-content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
flex: 1;
padding-left: 10px;
height: 40px; height: 40px;
overflow: hidden; }
}
.uni-card__title-content {
.uni-card__title-content-title { /* #ifndef APP-NVUE */
font-size: $uni-font-size-base; display: flex;
line-height: 22px; /* #endif */
} flex-direction: column;
justify-content: center;
.uni-card__title-content-extra { flex: 1;
font-size: $uni-font-size-sm; height: 40px;
line-height: 27px; overflow: hidden;
color: $uni-text-color-grey; }
}
.uni-card__title-content-title {
.uni-card__header { font-size: $uni-font-size-base;
/* #ifndef APP-NVUE */ line-height: 22px;
display: flex; }
/* #endif */
position: relative; .uni-card__title-content-extra {
flex-direction: row; font-size: $uni-font-size-sm;
padding: $uni-spacing-col-lg; line-height: 27px;
align-items: center; color: $uni-text-color-grey;
} }
.uni-card__header-title { .uni-card__header {
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
display: flex; display: flex;
/* #endif */ /* #endif */
flex-direction: row; position: relative;
margin-right: $uni-spacing-col-base; flex-direction: row;
justify-content: flex-start; padding: $uni-spacing-col-lg;
align-items: center; align-items: center;
} }
.uni-card__header-title-text { .uni-card__header-title {
font-size: $uni-font-size-lg; /* #ifndef APP-NVUE */
flex: 1; display: flex;
color: #333; /* #endif */
} flex-direction: row;
margin-right: $uni-spacing-col-base;
.uni-card__header-extra-img { justify-content: flex-start;
height: $uni-img-size-sm; align-items: center;
width: $uni-img-size-sm; }
margin-right: $uni-spacing-col-base;
} .uni-card__header-title-text {
font-size: $uni-font-size-lg;
.uni-card__header-extra-text { flex: 1;
flex: 1; color: #333;
margin-left: $uni-spacing-col-base; }
font-size: $uni-font-size-sm;
text-align: right; .uni-card__header-extra-img {
color: $uni-text-color-grey; height: $uni-img-size-sm;
} width: $uni-img-size-sm;
margin-right: $uni-spacing-col-base;
.uni-card__content { }
color: $uni-text-color;
} .uni-card__header-extra-text {
flex: 1;
.uni-card__content--pd { margin-left: $uni-spacing-col-base;
padding: $uni-spacing-col-lg; font-size: $uni-font-size-sm;
} text-align: right;
color: $uni-text-color-grey;
.uni-card__content-extra { }
font-size: $uni-font-size-base;
padding-bottom: 10px; .uni-card__content {
color: $uni-text-color-grey; color: $uni-text-color;
} }
.uni-card__footer { .uni-card__content--pd {
justify-content: space-between; padding: $uni-spacing-col-lg;
padding: $uni-spacing-col-lg; }
}
.uni-card__content-extra {
.uni-card__footer-text { font-size: $uni-font-size-base;
color: $uni-text-color-grey; padding-bottom: 10px;
font-size: $uni-font-size-sm; color: $uni-text-color-grey;
} }
.uni-card--shadow { .uni-card__footer {
position: relative; justify-content: space-between;
/* #ifndef APP-NVUE */ padding: $uni-spacing-col-lg;
box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.1); }
/* #endif */
} .uni-card__footer-text {
color: $uni-text-color-grey;
.uni-card--full { font-size: $uni-font-size-sm;
margin: 0; }
border-radius: 0;
} .uni-card--shadow {
position: relative;
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
.uni-card--full:after { box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.1);
border-radius: 0; /* #endif */
} }
/* #endif */ .uni-card--full {
.uni-ellipsis { margin: 0;
/* #ifndef APP-NVUE */ border-radius: 0;
overflow: hidden; }
white-space: nowrap;
text-overflow: ellipsis; /* #ifndef APP-NVUE */
/* #endif */ .uni-card--full:after {
/* #ifdef APP-NVUE */ border-radius: 0;
lines: 1; }
/* #endif */
} /* #endif */
.uni-ellipsis {
/* #ifndef APP-NVUE */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
/* #endif */
/* #ifdef APP-NVUE */
lines: 1;
/* #endif */
}
.uni-card__head-padding {
// mar: 12px;
}
</style> </style>
{ {
"id": "uni-card", "id": "uni-card",
"displayName": "Card 卡片", "displayName": "uni-card 卡片",
"version": "1.1.6", "version": "1.2.0",
"description": "Card 组件,提供常见的卡片样式。", "description": "Card 组件,提供常见的卡片样式。",
"keywords": [ "keywords": [
"card", "uni-ui",
"uni-ui", "uniui",
"卡片" "card",
], "",
"repository": "https://github.com/dcloudio/uni-ui", "卡片"
"engines": { ],
"HBuilderX": "" "repository": "https://github.com/dcloudio/uni-ui",
}, "engines": {
"directories": { "HBuilderX": ""
"example": "../../temps/example_temps" },
}, "directories": {
"dcloudext": { "example": "../../temps/example_temps"
"category": [ },
"前端组件", "dcloudext": {
"通用组件" "category": [
], "前端组件",
"sale": { "通用组件"
"regular": { ],
"price": "0.00" "sale": {
}, "regular": {
"sourcecode": { "price": "0.00"
"price": "0.00" },
} "sourcecode": {
}, "price": "0.00"
"contact": { }
"qq": "" },
}, "contact": {
"declaration": { "qq": ""
"ads": "无", },
"data": "无", "declaration": {
"permissions": "无" "ads": "无",
}, "data": "无",
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" "permissions": "无"
}, },
"uni_modules": { "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
"dependencies": [], },
"encrypt": [], "uni_modules": {
"platforms": { "dependencies": [
"cloud": { "uni-icons"
"tcb": "y", ],
"aliyun": "y" "encrypt": [],
}, "platforms": {
"client": { "cloud": {
"App": { "tcb": "y",
"app-vue": "y", "aliyun": "y"
"app-nvue": "y" },
}, "client": {
"H5-mobile": { "App": {
"Safari": "y", "app-vue": "y",
"Android Browser": "y", "app-nvue": "y"
"微信浏览器(Android)": "y", },
"QQ浏览器(Android)": "y" "H5-mobile": {
}, "Safari": "y",
"H5-pc": { "Android Browser": "y",
"Chrome": "y", "微信浏览器(Android)": "y",
"IE": "y", "QQ浏览器(Android)": "y"
"Edge": "y", },
"Firefox": "y", "H5-pc": {
"Safari": "y" "Chrome": "y",
}, "IE": "y",
"小程序": { "Edge": "y",
"微信": "y", "Firefox": "y",
"阿里": "y", "Safari": "y"
"百度": "y", },
"字节跳动": "y", "小程序": {
"QQ": "y" "微信": "y",
}, "阿里": "y",
"快应用": { "百度": "y",
"华为": "u", "字节跳动": "y",
"联盟": "u" "QQ": "y"
} },
} "快应用": {
} "华为": "u",
} "联盟": "u"
} }
\ No newline at end of file }
}
}
}
## Card 卡片 ## Card 卡片
> **组件名:uni-card**
> 代码块: `uCard` > 代码块: `uCard`
...@@ -12,6 +13,7 @@ ...@@ -12,6 +13,7 @@
如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55) 如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
> **注意事项**
> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。 > 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。
> - 因为平台兼容问题 , 目前 APP-NVUE 安卓平台下不支持阴影 > - 因为平台兼容问题 , 目前 APP-NVUE 安卓平台下不支持阴影
...@@ -94,4 +96,9 @@ ...@@ -94,4 +96,9 @@
|插槽称名 |说明 | |插槽称名 |说明 |
|:-: |:-: | |:-: |:-: |
|footer |卡片底部插槽 | |header |卡片头部插槽( 图文卡片 mode="style" 时,不支持)|
\ No newline at end of file |footer |卡片底部插槽 |
## 组件示例
点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/card/card](https://hellouniapp.dcloud.net.cn/pages/extUI/card/card)
\ No newline at end of file
## 1.1.6(2021-02-05) ## 1.2.2(2021-07-21)
- 优化 组件引用关系,通过uni_modules引用组件 - 修复 由1.2.0版本引起的 change 事件返回 undefined 的Bug
## 1.1.5(2021-02-05) ## 1.2.1(2021-07-21)
- 优化 组件示例
## 1.2.0(2021-07-21)
- 新增 组件折叠动画
- 新增 value\v-model 属性 ,动态修改面板折叠状态
- 新增 title 插槽 ,可定义面板标题
- 新增 border 属性 ,显示隐藏面板内容分隔线
- 新增 title-border 属性 ,显示隐藏面板标题分隔线
- 修复 resize 方法失效的Bug
- 修复 change 事件返回参数不正确的Bug
- 优化 H5、App 平台自动更具内容更新高度,无需调用 reszie() 方法
## 1.1.7(2021-05-12)
- 新增 组件示例地址
## 1.1.6(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.1.5(2021-02-05)
- 调整为uni_modules目录规范 - 调整为uni_modules目录规范
\ No newline at end of file
<template> <template>
<view :class="{ 'uni-collapse-cell--disabled': disabled,'uni-collapse-cell--notdisabled': !disabled, 'uni-collapse-cell--open': isOpen,'uni-collapse-cell--hide':!isOpen }" <view class="uni-collapse-item">
class="uni-collapse-cell"> <!-- onClick(!isOpen) -->
<view :class="{ 'uni-collapse-cell--disabled': disabled}" class="uni-collapse-cell__title" @click="onClick"> <view @click="onClick(!isOpen)" class="uni-collapse-item__title"
<image v-if="thumb" :src="thumb" class="uni-collapse-cell__title-img" /> :class="{'is-open':isOpen &&titleBorder === 'auto' ,'uni-collapse-item-border':titleBorder !== 'none'}">
<text class="uni-collapse-cell__title-text">{{ title }}</text> <view class="uni-collapse-item__title-wrap">
<!-- #ifdef MP-ALIPAY --> <slot name="title">
<view :class="{ 'uni-collapse-cell__title-arrow-active': isOpen, 'uni-collapse-cell--animation': showAnimation === true }" <view class="uni-collapse-item__title-box" :class="{'is-disabled':disabled}">
class="uni-collapse-cell__title-arrow"> <image v-if="thumb" :src="thumb" class="uni-collapse-item__title-img" />
<uni-icons color="#bbb" size="20" type="arrowdown" /> <text class="uni-collapse-item__title-text">{{ title }}</text>
</view> </view>
<!-- #endif --> </slot>
<!-- #ifndef MP-ALIPAY --> </view>
<uni-icons :class="{ 'uni-collapse-cell__title-arrow-active': isOpen, 'uni-collapse-cell--animation': showAnimation === true }" <view
class="uni-collapse-cell__title-arrow" color="#bbb" size="20" type="arrowdown" /> :class="{ 'uni-collapse-item__title-arrow-active': isOpen, 'uni-collapse-item--animation': showAnimation === true }"
<!-- #endif --> class="uni-collapse-item__title-arrow">
</view> <uni-icons :color="disabled?'#ddd':'#bbb'" size="14" type="arrowdown" />
<view :class="{'uni-collapse-cell__content--hide':!isOpen}" class="uni-collapse-cell__content"> </view>
<view :class="{ 'uni-collapse-cell--animation': showAnimation === true }" class="uni-collapse-cell__wrapper" :style="{'transform':isOpen?'translateY(0)':'translateY(-50%)','-webkit-transform':isOpen?'translateY(0)':'translateY(-50%)'}"> </view>
<slot /> <view class="uni-collapse-item__wrap" :class="{'is--transition':showAnimation}"
</view> :style="{height: (isOpen?height:0) +'px'}">
</view> <view :id="elId" ref="collapse--hook" class="uni-collapse-item__wrap-content"
</view> :class="{open:isheight,'uni-collapse-item--border':border&&isOpen}">
</template> <slot></slot>
</view>
<script> </view>
/**
* CollapseItem 折叠面板子组件 </view>
* @description 折叠面板子组件 </template>
* @property {String} title 标题文字
* @property {String} thumb 标题左侧缩略图 <script>
* @property {Boolean} disabled = [true|false] 是否展开面板 // #ifdef APP-NVUE
* @property {Boolean} showAnimation = [true|false] 开启动画 const dom = weex.requireModule('dom')
*/ // #endif
export default { /**
name: 'UniCollapseItem', * CollapseItem 折叠面板子组件
props: { * @description 折叠面板子组件
title: { * @property {String} title 标题文字
// 列表标题 * @property {String} thumb 标题左侧缩略图
type: String, * @property {String} name 唯一标志符
default: '' * @property {Boolean} disabled = [true|false] 是否展开面板
}, * @property {Boolean} showAnimation = [true|false] 开启动画
name: { */
// 唯一标识符 export default {
type: [Number, String], name: 'uniCollapseItem',
default: 0 props: {
}, // 列表标题
disabled: { title: {
// 是否禁用 type: String,
type: Boolean, default: ''
default: false },
}, name: {
showAnimation: { type: [Number, String],
// 是否显示动画 default: ''
type: Boolean, },
default: false // 是否禁用
}, disabled: {
open: { type: Boolean,
// 是否展开 default: false
type: Boolean, },
default: false // #ifdef APP-PLUS
}, // 是否显示动画,app 端默认不开启动画,卡顿严重
thumb: { showAnimation: {
// 缩略图 type: Boolean,
type: String, default: false
default: '' },
} // #endif
}, // #ifndef APP-PLUS
data() { // 是否显示动画
return { showAnimation: {
isOpen: false type: Boolean,
} default: true
}, },
watch: { // #endif
open(val) { // 是否展开
this.isOpen = val open: {
} type: Boolean,
}, default: false
inject: ['collapse'], },
created() { // 缩略图
this.isOpen = this.open thumb: {
this.nameSync = this.name ? this.name : this.collapse.childrens.length type: String,
this.collapse.childrens.push(this) default: ''
if (String(this.collapse.accordion) === 'true') { },
if (this.isOpen) { // 标题分隔线显示类型
let lastEl = this.collapse.childrens[this.collapse.childrens.length - 2] titleBorder: {
if (lastEl) { type: String,
this.collapse.childrens[this.collapse.childrens.length - 2].isOpen = false default: 'auto'
} },
} // 是否显示分隔线
} border: {
}, type: Boolean,
methods: { default: true
onClick() { }
if (this.disabled) { },
return data() {
} // TODO 随机生生元素ID,解决百度小程序获取同一个元素位置信息的bug
if (String(this.collapse.accordion) === 'true') { const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
this.collapse.childrens.forEach(vm => { return {
if (vm === this) { isOpen: false,
return isheight: null,
} height: 0,
vm.isOpen = false elId,
}) nameSync: 0
} }
this.isOpen = !this.isOpen },
this.collapse.onChange && this.collapse.onChange() watch: {
this.$forceUpdate() open(val) {
} this.isOpen = val
} this.onClick(val,'init')
} }
</script> },
updated(e) {
<style lang="scss" scoped> this.$nextTick(()=> {
.uni-collapse-cell { this.init(true)
flex-direction: column; })
border-color: $uni-border-color; },
border-bottom-width: 1px; created(){
border-bottom-style: solid; this.collapse = this.getCollapse()
} this.oldHeight = 0
},
// TODO vue2
.uni-collapse-cell--hover { destroyed() {
background-color: $uni-bg-color-hover; if (this.__isUnmounted) return
} this.uninstall()
},
.uni-collapse-cell--open { // TODO vue3
background-color: $uni-bg-color-hover; unmounted() {
} this.__isUnmounted = true
this.uninstall()
.uni-collapse-cell--disabled { },
background-color: $uni-bg-color-hover; mounted() {
/* #ifdef H5 */
cursor: not-allowed !important; if (!this.collapse) return
/* #endif */ if (this.name !== '') {
// opacity: 0.3; this.nameSync = this.name
} } else {
this.nameSync = this.collapse.childrens.length + ''
}
.uni-collapse-cell--hide { if (this.collapse.names.indexOf(this.nameSync) === -1) {
height: 48px; this.collapse.names.push(this.nameSync)
} } else {
console.warn(`name 值 ${this.nameSync} 重复`);
.uni-collapse-cell--animation { }
// transition: transform 0.3s ease; if (this.collapse.childrens.indexOf(this) === -1) {
transition-property: transform; this.collapse.childrens.push(this)
transition-duration: 0.3s; }
transition-timing-function: ease; this.init()
} },
methods: {
.uni-collapse-cell__title { init(type) {
padding: 12px 12px; // #ifndef APP-NVUE
position: relative; this.getCollapseHeight(type)
/* #ifndef APP-NVUE */ // #endif
display: flex; // #ifdef APP-NVUE
width: 100%; this.getNvueHwight(type)
box-sizing: border-box; // #endif
/* #endif */ },
height: 48px; uninstall() {
line-height: 24px; if (this.collapse) {
flex-direction: row; this.collapse.childrens.forEach((item, index) => {
justify-content: space-between; if (item === this) {
align-items: center; this.collapse.childrens.splice(index, 1)
/* #ifdef H5 */ }
cursor: pointer; })
/* #endif */ this.collapse.names.forEach((item, index) => {
} if (item === this.nameSync) {
this.collapse.names.splice(index, 1)
.uni-collapse-cell__title:active { }
background-color: $uni-bg-color-hover; })
} }
},
.uni-collapse-cell__title-img { onClick(isOpen,type) {
height: $uni-img-size-base; if (this.disabled) return
width: $uni-img-size-base; this.isOpen = isOpen
margin-right: 10px; if (this.isOpen && this.collapse) {
} this.collapse.setAccordion(this)
}
.uni-collapse-cell__title-arrow { if(type !== 'init'){
width: 20px; this.collapse.onChange(isOpen,this)
height: 20px; }
transform: rotate(0deg); },
transform-origin: center center; getCollapseHeight(type, index = 0) {
const views = uni.createSelectorQuery().in(this)
} views
.select(`#${this.elId}`)
.uni-collapse-cell__title-arrow-active { .fields({
transform: rotate(180deg); size: true
} }, data => {
// TODO 百度中可能获取不到节点信息 ,需要循环获取
.uni-collapse-cell__title-text { if (index >= 10) return
flex: 1; if (!data) {
font-size: $uni-font-size-base; index++
/* #ifndef APP-NVUE */ this.getCollapseHeight(false, index)
white-space: nowrap; return
color: inherit; }
/* #endif */ // #ifdef APP-NVUE
/* #ifdef APP-NVUE */ this.height = data.height + 1
lines: 1; // #endif
/* #endif */ // #ifndef APP-NVUE
overflow: hidden; this.height = data.height
text-overflow: ellipsis; // #endif
} this.isheight = true
if (type) return
.uni-collapse-cell__content { this.onClick(this.open,'init')
overflow: hidden; })
} .exec()
},
.uni-collapse-cell__wrapper { getNvueHwight(type) {
/* #ifndef APP-NVUE */ const result = dom.getComponentRect(this.$refs['collapse--hook'], option => {
display: flex; if (option && option.result && option.size) {
/* #endif */ // #ifdef APP-NVUE
flex-direction: column; this.height = option.size.height + 1
} // #endif
// #ifndef APP-NVUE
.uni-collapse-cell__content--hide { this.height = option.size.height
height: 0px; // #endif
line-height: 0px; this.isheight = true
} if (type) return
this.onClick(this.open,'init')
}
})
},
/**
* 获取父元素实例
*/
getCollapse(name = 'uniCollapse') {
let parent = this.$parent;
let parentName = parent.$options.name;
while (parentName !== name) {
parent = parent.$parent;
if (!parent) return false;
parentName = parent.$options.name;
}
return parent;
}
}
}
</script>
<style lang="scss" scoped>
.uni-collapse-item {
/* #ifndef APP-NVUE */
box-sizing: border-box;
/* #endif */
&__title {
/* #ifndef APP-NVUE */
display: flex;
width: 100%;
box-sizing: border-box;
/* #endif */
flex-direction: row;
align-items: center;
transition: border-bottom-color .3s;
// transition-property: border-bottom-color;
// transition-duration: 5s;
&-wrap {
width: 100%;
flex: 1;
}
&-box {
padding: 0 15px;
/* #ifndef APP-NVUE */
display: flex;
width: 100%;
box-sizing: border-box;
/* #endif */
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 48px;
line-height: 48px;
background-color: #fff;
color: #303133;
font-size: 13px;
font-weight: 500;
/* #ifdef H5 */
cursor: pointer;
outline: none;
/* #endif */
&.is-disabled {
.uni-collapse-item__title-text {
color: $uni-text-color-disable;
}
}
}
&.uni-collapse-item-border {
border-bottom: 1px solid #ebeef5;
}
&.is-open {
border-bottom-color: transparent;
}
&-img {
height: $uni-img-size-base;
width: $uni-img-size-base;
margin-right: 10px;
}
&-text {
flex: 1;
font-size: $uni-font-size-base;
/* #ifndef APP-NVUE */
white-space: nowrap;
color: inherit;
/* #endif */
/* #ifdef APP-NVUE */
lines: 1;
/* #endif */
overflow: hidden;
text-overflow: ellipsis;
}
&-arrow {
/* #ifndef APP-NVUE */
display: flex;
box-sizing: border-box;
/* #endif */
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
margin-right: 10px;
transform: rotate(0deg);
&-active {
transform: rotate(180deg);
}
}
}
&__wrap {
/* #ifndef APP-NVUE */
will-change: height;
box-sizing: border-box;
/* #endif */
background-color: #fff;
overflow: hidden;
position: relative;
height: 0;
&.is--transition {
// transition: all 0.3s;
transition-property: height, border-bottom-width;
transition-duration: 0.3s;
/* #ifndef APP-NVUE */
will-change: height;
/* #endif */
}
&-content {
position: absolute;
font-size: 13px;
color: #303133;
// transition: height 0.3s;
border-bottom-color: transparent;
border-bottom-style: solid;
border-bottom-width: 0;
&.uni-collapse-item--border {
border-bottom-width: 1px;
border-bottom-color: red;
border-bottom-color: #ebeef5;
}
&.open {
position: relative;
}
}
}
&--animation {
transition-property: transform;
transition-duration: 0.3s;
transition-timing-function: ease;
}
}
</style> </style>
<template> <template>
<view class="uni-collapse"> <view class="uni-collapse">
<slot /> <slot />
</view> </view>
</template> </template>
<script> <script>
/** /**
* Collapse 折叠面板 * Collapse 折叠面板
* @description 展示可以折叠 / 展开的内容区域 * @description 展示可以折叠 / 展开的内容区域
* @tutorial https://ext.dcloud.net.cn/plugin?id=23 * @tutorial https://ext.dcloud.net.cn/plugin?id=23
* @property {Boolean} accordion = [true|false] 是否开启手风琴效果是否开启手风琴效果 * @property {String|Array} value 当前激活面板改变时触发(如果是手风琴模式,参数类型为string,否则为array)
* @event {Function} change 切换面板时触发,activeNames(Array):展开状态的uniCollapseItem的 name 值 * @property {Boolean} accordion = [true|false] 是否开启手风琴效果是否开启手风琴效果
*/ * @event {Function} change 切换面板时触发,如果是手风琴模式,返回类型为string,否则为array
export default { */
name: 'UniCollapse', export default {
props: { name: 'uniCollapse',
accordion: { props: {
// 是否开启手风琴效果 value: {
type: [Boolean, String], type: [String, Array],
default: false default: ''
} },
}, modelValue: {
data() { type: [String, Array],
return {} default: ''
}, },
provide() { accordion: {
return { // 是否开启手风琴效果
collapse: this type: [Boolean, String],
} default: false
}, },
created() { },
this.childrens = [] data() {
}, return {}
methods: { },
onChange() { computed: {
let activeItem = [] // TODO 兼容 vue2 和 vue3
this.childrens.forEach((vm, index) => { dataValue() {
if (vm.isOpen) { let value = (typeof this.value === 'string' && this.value === '') ||
activeItem.push(vm.nameSync) (Array.isArray(this.value) && this.value.length === 0)
} let modelValue = (typeof this.modelValue === 'string' && this.modelValue === '') ||
}) (Array.isArray(this.modelValue) && this.modelValue.length === 0)
this.$emit('change', activeItem) if (value) {
} return this.modelValue
} }
} if (modelValue) {
</script> return this.value
<style lang="scss" scoped> }
.uni-collapse {
/* #ifndef APP-NVUE */ return this.value
width: 100%; }
display: flex; },
/* #endif */ watch: {
/* #ifdef APP-NVUE */ dataValue(val) {
flex: 1; this.setOpen(val)
/* #endif */ }
flex-direction: column; },
background-color: $uni-bg-color; created() {
} this.childrens = []
this.names = []
},
mounted() {
this.setOpen(this.dataValue)
},
methods: {
setOpen(val) {
let str = typeof val === 'string'
let arr = Array.isArray(val)
this.childrens.forEach((vm, index) => {
if (str) {
if (val === vm.nameSync) {
if (!this.accordion) {
console.warn('accordion 属性为 false ,v-model 类型应该为 array')
return
}
vm.isOpen = true
}
}
if (arr) {
val.forEach(v => {
if (v === vm.nameSync) {
if (this.accordion) {
console.warn('accordion 属性为 true ,v-model 类型应该为 string')
return
}
vm.isOpen = true
}
})
}
})
this.emit(val)
},
setAccordion(self) {
if (!this.accordion) return
this.childrens.forEach((vm, index) => {
if (self !== vm) {
vm.isOpen = false
}
})
},
resize() {
this.childrens.forEach((vm, index) => {
// #ifndef APP-NVUE
vm.getCollapseHeight()
// #endif
// #ifdef APP-NVUE
vm.getNvueHwight()
// #endif
})
},
onChange(isOpen, self) {
let activeItem = []
if (this.accordion) {
activeItem = isOpen ? self.nameSync : ''
} else {
this.childrens.forEach((vm, index) => {
if (vm.isOpen) {
activeItem.push(vm.nameSync)
}
})
}
this.$emit('change', activeItem)
this.emit(activeItem)
},
emit(val){
this.$emit('input', val)
this.$emit('update:modelValue', val)
}
}
}
</script>
<style lang="scss" scoped>
.uni-collapse {
/* #ifndef APP-NVUE */
width: 100%;
display: flex;
/* #endif */
/* #ifdef APP-NVUE */
flex: 1;
/* #endif */
flex-direction: column;
background-color: $uni-bg-color;
}
</style> </style>
{ {
"id": "uni-collapse", "id": "uni-collapse",
"displayName": "Collapse 折叠面板", "displayName": "uni-collapse 折叠面板",
"version": "1.1.6", "version": "1.2.2",
"description": " collapse uni-ui 折叠面板 手风琴", "description": "Collapse 组件,可以折叠 / 展开的内容区域。",
"keywords": [ "keywords": [
"Collapse", "uni-ui",
"组件,可以折叠", "折叠",
"/", "折叠面板",
"展开的内容区域。" "手风琴"
], ],
"repository": "https://github.com/dcloudio/uni-ui", "repository": "https://github.com/dcloudio/uni-ui",
"engines": { "engines": {
"HBuilderX": "" "HBuilderX": ""
}, },
"directories": { "directories": {
"example": "../../temps/example_temps" "example": "../../temps/example_temps"
}, },
"dcloudext": { "dcloudext": {
"category": [ "category": [
"前端组件", "前端组件",
"通用组件" "通用组件"
], ],
"sale": { "sale": {
"regular": { "regular": {
"price": "0.00" "price": "0.00"
}, },
"sourcecode": { "sourcecode": {
"price": "0.00" "price": "0.00"
} }
}, },
"contact": { "contact": {
"qq": "" "qq": ""
}, },
"declaration": { "declaration": {
"ads": "无", "ads": "无",
"data": "无", "data": "无",
"permissions": "无" "permissions": "无"
}, },
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
}, },
"uni_modules": { "uni_modules": {
"dependencies": [ "dependencies": [
"uni-icons" "uni-icons"
], ],
"encrypt": [], "encrypt": [],
"platforms": { "platforms": {
"cloud": { "cloud": {
"tcb": "y", "tcb": "y",
"aliyun": "y" "aliyun": "y"
}, },
"client": { "client": {
"App": { "App": {
"app-vue": "y", "app-vue": "y",
"app-nvue": "y" "app-nvue": "y"
}, },
"H5-mobile": { "H5-mobile": {
"Safari": "y", "Safari": "y",
"Android Browser": "y", "Android Browser": "y",
"微信浏览器(Android)": "y", "微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y" "QQ浏览器(Android)": "y"
}, },
"H5-pc": { "H5-pc": {
"Chrome": "y", "Chrome": "y",
"IE": "y", "IE": "y",
"Edge": "y", "Edge": "y",
"Firefox": "y", "Firefox": "y",
"Safari": "y" "Safari": "y"
}, },
"小程序": { "小程序": {
"微信": "y", "微信": "y",
"阿里": "y", "阿里": "y",
"百度": "y", "百度": "y",
"字节跳动": "y", "字节跳动": "y",
"QQ": "y" "QQ": "y"
}, },
"快应用": { "快应用": {
"华为": "u", "华为": "u",
"联盟": "u" "联盟": "u"
} }
} }
} }
} }
} }
\ No newline at end of file
## Collapse 折叠面板 ## Collapse 折叠面板
> **组件名:uni-collapse**
> 代码块: `uCollapse` > 代码块: `uCollapse`
> 关联组件:`uni-collapse-item`、`uni-icons`。 > 关联组件:`uni-collapse-item`、`uni-icons`。
展示可以折叠 / 展开的内容区域。 折叠面板用来折叠/显示过长的内容或者是列表。通常是在多内容分类项使用,折叠不重要的内容,显示重要内容。点击可以展开折叠部分。
> **注意事项**
> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。
> - 组件需要依赖 `sass` 插件 ,请自行手动安装
> - `App` 端默认关闭组件动画 ,因为 `height` 动画开销比较大,会导致页面卡顿,请酌情使用动画
> - 如在使用组件过程从发现卡顿严重,请尝试停用组件动画,问题原因如上
> - 在小程序端组件内容发生变化,需要手动调用 resize() 方法,手动更新几点信息,避免出现内容错位
> - 如需自定义组件默认边框颜色等,请使用插槽自定义内容并合理使用 `border ` 和 `title-border` 属性
> - 折叠面板仅支持嵌套使用,请勿单独使用
> - 组件支持 nvue ,需要在 `manifest.json > app-plus` 节点下配置 `"nvueStyleCompiler" : "uni-app"`
> - 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
### 安装方式 ### 安装方式
...@@ -13,95 +26,250 @@ ...@@ -13,95 +26,250 @@
如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55) 如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
### 基本用法 ### 基本用法
``template`` 中引用组件 使用 `title` 属性指定面板显示内容
使用 `open` 属性默认打开当前面板
使用 `disabled` 属性禁用面板
```html
<uni-collapse>
<uni-collapse-item title="默认开启" :open="true">
<text>折叠内容</text>
</uni-collapse-item>
<uni-collapse-item title="折叠内容">
<text>折叠内容</text>
</uni-collapse-item>
<uni-collapse-item title="禁用状态" disabled>
<text>折叠内容</text>
</uni-collapse-item>
</uni-collapse>
```
### 手风琴效果
使用 `accordion` 属性,可以仅打开一个面板并关闭其他已经打开的面板,效果类似手风琴
设置 `accordion` 属性时,`open` 属性则生效在最后一个组件
```html
<uni-collapse accordion>
<uni-collapse-item title="手风琴效果">
<text>折叠内容</text>
</uni-collapse-item>
<uni-collapse-item title="手风琴效果">
<text>折叠内容</text>
</uni-collapse-item>
<uni-collapse-item title="禁用状态" disabled>
<text>折叠内容</text>
</uni-collapse-item>
</uni-collapse>
```
### 动态设置折叠面板打开状态
使用 `v-model` 属性,动态设置面板的显示状态
使用 `name` 属性设置每个面板的唯一标识,如不设置使用默认索引,从字符串 `"0"` 开始记数
**注意**
- 如果 `accordion` 属性为 `true``v-model` 类型为 `String`
- 如果 `accordion` 属性为 `false``v-model` 类型为 `Array`
- 请注意 `v-model` 属性与 `open` 属性请勿一起使用 ,建议只使用 `v-model`
```html
<uni-collapse v-model="value">
<uni-collapse-item name="key1" title="默认开启">
<text>折叠内容</text>
</uni-collapse-item>
<uni-collapse-item name="key2" title="默认开启">
<text>折叠内容</text>
</uni-collapse-item>
<uni-collapse-item name="key3" title="默认不开启">
<text>折叠内容</text>
</uni-collapse-item>
</uni-collapse>
```
```javascript
export default {
data(){
return {
value:['key1','key2'],
// 如果设置了 accordion 属性,则使用 string 类型
// value:'key1'
}
}
}
```
### 使用动画
使用 `show-animation` 属性开启或关闭面板折叠动画,默认动画开启
**注意**
- `App` 端默认关闭组件动画 ,因为 height 动画开销比较大,会导致页面卡顿,请酌情使用动画,如出现明显卡顿,尝试关闭动画
```html ```html
<!-- 一般用法 --> <uni-collapse>
<uni-collapse @change="change"> <uni-collapse-item :show-animation="true" title="开启动画">
<uni-collapse-item title="标题文字"> <text>折叠内容</text>
<uni-list> </uni-collapse-item>
<uni-list-item title="标题文字" thumb="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png"></uni-list-item> <uni-collapse-item :show-animation="true" title="开启动画">
<uni-list-item title="标题文字" note="描述信息" thumb="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png"></uni-list-item> <text>折叠内容</text>
<uni-list-item title="标题文字" note="描述信息" show-extra-icon="true" :extra-icon="{color: '#4cd964',size: '22',type: 'spinner'}"></uni-list-item> </uni-collapse-item>
</uni-list> <uni-collapse-item :show-animation="false" title="不开启动画">
</uni-collapse-item> <text>折叠内容</text>
<uni-collapse-item title="默认开启" open="true"> </uni-collapse-item>
<view style="padding: 30rpx;"> 折叠内容主体,可自定义内容及样式 </view>
</uni-collapse-item>
<uni-collapse-item title="禁用状态" disabled="true">
<view style="padding: 30rpx;"> 禁用状态 </view>
</uni-collapse-item>
</uni-collapse> </uni-collapse>
```
### 配置图片
使用 `thumb` 配置图片地址, 可在面板左侧显示一个图片
如需显示更多内容,如图标等,请见下方自定义插槽的说明
<!-- 手风琴效果 --> ```html
<uni-collapse accordion="true"> <uni-collapse>
<uni-collapse-item title="标题文字"> <uni-collapse-item title="标题文字"
<view style="padding: 30rpx;"> thumb="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png">
手风琴效果 <view class="content">
</view> <text class="text">折叠内容主体,可自定义内容及样式</text>
</uni-collapse-item> </view>
<uni-collapse-item title="标题文字"> </uni-collapse-item>
<view style="padding: 30rpx;">
手风琴效果
</view>
</uni-collapse-item>
<uni-collapse-item title="标题文字">
<view style="padding: 30rpx;">
手风琴效果
</view>
</uni-collapse-item>
</uni-collapse> </uni-collapse>
```
<!-- 带图标 --> ### 自定义插槽
如果需要自定义面板显示,可以使用 `title` 插槽达成完全自定义。下面是一个使用 `uni-list` 的列表示例,需要引入 `uni-list` 组件
```html
<uni-collapse> <uni-collapse>
<uni-collapse-item title="标题文字" thumb="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png"> <!-- 因为list默认带一条分隔线,所以使用 titleBorder="none" 取消面板的分隔线 -->
<view style="padding: 30rpx;"> <uni-collapse-item title-border="none" :border="false">
折叠内容主体,可自定义内容及样式 <template v-slot:title>
</view> <uni-list>
</uni-collapse-item> <uni-list-item title="标题使用自定义标题插槽" :show-extra-icon="true" :extra-icon="extraIcon">
<uni-collapse-item title="标题文字" thumb="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png"> </uni-list-item>
<view style="padding: 30rpx;"> </uni-list>
折叠内容主体,可自定义内容及样式 </template>
</view> <view class="content">
</uni-collapse-item> <text class="text">折叠内容主体,可自定义内容及样式</text>
</view>
</uni-collapse-item>
</uni-collapse> </uni-collapse>
``` ```
**注意**
- 在折叠面板组件中使用list时,在 App-Nvue 下请勿单独使用 uni-list-item,会导致组件无法正常显示,其他平台不做限制
- 在默认插槽里使用 uni-list 组件与上方示例一样,直接写在默认插槽里即可
## API ## API
### Collapse Props ### Collapse Props
|属性名 |类型 |默认值 |说明 | |属性名|类型|默认值|说明|
|:-: |:-: |:-: |:-: | |:-:|:-:|:-:|:-:|
|accordion |Boolean|false |是否开启手风琴效果 | |value/v-model|String/Array|-|当前激活面板改变时触发(如果是手风琴模式,参数类型为string,否则为array)|
|accordion|Boolean|false|是否开启手风琴效果 |
### Collapse Event ### Collapse Event
|事件称名 |说明 |返回值 | |事件称名|说明|返回值|
|:-: |:-: :-: | |:-:|:-:|:-:|
|@change |切换面板时触发 |activeNames(Array):展开状态的uniCollapseItem的name值| |@change|切换面板时触发 |切换面板时触发,如果是手风琴模式,返回类型为string,否则为array|
### Collapse Methods ### Collapse Methods
|方法名称 |说明 | |方法名称|说明|
|:-: |:-: | |:-:|:-:|
|resize |更新当前列表高度,只有 `animation:true` 下生效| |resize |更新当前列表高度|
> **提示**
> - resize 方法解决动态添加数据,带动画的折叠面板高度不更新的问题 > - resize 方法解决动态添加数据,带动画的折叠面板高度不更新的问题
> - 需要在数据渲染完毕之后使用 `resize` 方法。推荐在 `this.nextTick()` 中使用 > - 需要在数据渲染完毕之后使用 `resize` 方法。推荐在 `this.$nextTick()` 中使用
> - 当前只有小程序端需要调用此方法,H5\App 端已经做了处理,不需要手动更新高度
> ```html
> <view>
> <uni-collapse ref="collapse" v-model="value">
> <uni-collapse-item title="默认开启" >
> <view class="content">
> <text class="text">{{content}}</text>
> </view>
> </uni-collapse-item>
> <uni-collapse-item title="折叠内容">
> <view class="content">
> <text class="text">折叠内容主体,这是一段比较长内容。默认折叠主要内容,只显示当前项标题。点击标题展开,才能看到这段文字。再次点击标题,折叠内容。</text>
> </view>
> </uni-collapse-item>
> </uni-collapse>
> <button class="button" type="primary" @click="add">动态修改内容</button>
> </view>
> ```
> ```javascript
> export default {
> data() {
> return {
> value:['0'],
> content: '折叠内容主体,可自定义内容及样式,点击按钮修改内容使高度发生变化。',
> }
> },
> methods: {
> add() {
> if (this.content.length > 35) {
> this.content = '折叠内容主体,可自定义内容及样式,点击按钮修改内容使高度发生变化。'
> } else {
> this.content = '折叠内容主体,这是一段比较长内容。通过点击按钮修改后内容后,使组件高度发生变化,在次点击按钮恢复之前的内容和高度。'
> }
> // TODO 小程序中不支持自动更新 ,需要手动resize 更新组件高度
> // #ifdef MP
> this.$nextTick(() => {
> this.$refs.collapse.resize()
> })
> // #endif
> }
> }
> }
> ```
### CollapseItem Props ### CollapseItem Props
|属性名 |类型 |默认值 |说明 | |属性名|类型|默认值|说明|
|:-: |:-: |:-: |:-: | |:-:|:-:|:-:|:-:|
|title |String |- |标题文字 | |title|String|-|标题文字|
|thumb |String |- |标题左侧缩略图 | |thumb|String|-|标题左侧缩略图|
|disabled |Boolean|false |是否禁用 | |disabled|Boolean|false|是否禁用|
|open |Boolean|false |是否展开面板 | |open|Boolean|false|是否展开面板|
|showAnimation |Boolean |false |开启动画 | |show-animation|Boolean|false|开启动画|
\ No newline at end of file |border|Boolean|true|折叠面板内容分隔线|
|title-border|String|auto|折叠面板标题分隔线可选值见下方 **TitleBorder Params**|
#### TitleBorder Params
|参数名|说明|
|:-:|:-:|
|auto|分隔线自动显示|
|none|不显示分隔线|
|show|一直显示分隔线|
### Collapse Slots
| 插槽名 | 说明 |
| :-: | :-: |
| default |默认插槽|
| title |面板标题插槽,如使用此插槽禁用样式效果将失效|
## 组件示例
点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/collapse/collapse](https://hellouniapp.dcloud.net.cn/pages/extUI/collapse/collapse)
\ No newline at end of file
## 0.0.4(2021-02-05) ## 0.0.6(2021-05-12)
- 优化 组件引用关系,通过uni_modules引用组件 - 新增 组件示例地址
## 0.0.3(2021-02-04) ## 0.0.5(2021-04-21)
- 调整为uni_modules目录规范 - 优化 添加依赖 uni-icons, 导入后自动下载依赖
## 0.0.4(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 0.0.3(2021-02-04)
- 调整为uni_modules目录规范
<template> <template>
<view class="uni-combox"> <view class="uni-combox">
<view v-if="label" class="uni-combox__label" :style="labelStyle"> <view v-if="label" class="uni-combox__label" :style="labelStyle">
<text>{{label}}</text> <text>{{label}}</text>
</view> </view>
<view class="uni-combox__input-box"> <view class="uni-combox__input-box">
<input class="uni-combox__input" type="text" :placeholder="placeholder" v-model="inputVal" @input="onInput" <input class="uni-combox__input" type="text" :placeholder="placeholder" v-model="inputVal" @input="onInput"
@focus="onFocus" @blur="onBlur" /> @focus="onFocus" @blur="onBlur" />
<uni-icons class="uni-combox__input-arrow" type="arrowdown" size="14" @click="toggleSelector"></uni-icons> <uni-icons class="uni-combox__input-arrow" type="arrowdown" size="14" @click="toggleSelector"></uni-icons>
<view class="uni-combox__selector" v-if="showSelector"> <view class="uni-combox__selector" v-if="showSelector">
<scroll-view scroll-y="true" class="uni-combox__selector-scroll"> <scroll-view scroll-y="true" class="uni-combox__selector-scroll">
<view class="uni-combox__selector-empty" v-if="filterCandidatesLength === 0"> <view class="uni-combox__selector-empty" v-if="filterCandidatesLength === 0">
<text>{{emptyTips}}</text> <text>{{emptyTips}}</text>
</view> </view>
<view class="uni-combox__selector-item" v-for="(item,index) in filterCandidates" :key="index" @click="onSelectorClick(index)"> <view class="uni-combox__selector-item" v-for="(item,index) in filterCandidates" :key="index" @click="onSelectorClick(index)">
<text>{{item}}</text> <text>{{item}}</text>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
/** /**
* Combox 组合输入框 * Combox 组合输入框
* @description 组合输入框一般用于既可以输入也可以选择的场景 * @description 组合输入框一般用于既可以输入也可以选择的场景
* @tutorial https://ext.dcloud.net.cn/plugin?id=1261 * @tutorial https://ext.dcloud.net.cn/plugin?id=1261
* @property {String} label 左侧文字 * @property {String} label 左侧文字
* @property {String} labelWidth 左侧内容宽度 * @property {String} labelWidth 左侧内容宽度
* @property {String} placeholder 输入框占位符 * @property {String} placeholder 输入框占位符
* @property {Array} candidates 候选项列表 * @property {Array} candidates 候选项列表
* @property {String} emptyTips 筛选结果为空时显示的文字 * @property {String} emptyTips 筛选结果为空时显示的文字
* @property {String} value 组合框的值 * @property {String} value 组合框的值
*/ */
export default { export default {
name: 'uniCombox', name: 'uniCombox',
props: { props: {
label: { label: {
type: String, type: String,
default: '' default: ''
}, },
labelWidth: { labelWidth: {
type: String, type: String,
default: 'auto' default: 'auto'
}, },
placeholder: { placeholder: {
type: String, type: String,
default: '' default: ''
}, },
candidates: { candidates: {
type: Array, type: Array,
default () { default () {
return [] return []
} }
}, },
emptyTips: { emptyTips: {
type: String, type: String,
default: '无匹配项' default: '无匹配项'
}, },
value: { value: {
type: [String, Number], type: [String, Number],
default: '' default: ''
} }
}, },
data() { data() {
return { return {
showSelector: false, showSelector: false,
inputVal: '' inputVal: ''
} }
}, },
computed: { computed: {
labelStyle() { labelStyle() {
if (this.labelWidth === 'auto') { if (this.labelWidth === 'auto') {
return {} return {}
} }
return { return {
width: this.labelWidth width: this.labelWidth
} }
}, },
filterCandidates() { filterCandidates() {
return this.candidates.filter((item) => { return this.candidates.filter((item) => {
return item.toString().indexOf(this.inputVal) > -1 return item.toString().indexOf(this.inputVal) > -1
}) })
}, },
filterCandidatesLength() { filterCandidatesLength() {
return this.filterCandidates.length return this.filterCandidates.length
} }
}, },
watch: { watch: {
value: { value: {
handler(newVal) { handler(newVal) {
this.inputVal = newVal this.inputVal = newVal
}, },
immediate: true immediate: true
} }
}, },
methods: { methods: {
toggleSelector() { toggleSelector() {
this.showSelector = !this.showSelector this.showSelector = !this.showSelector
}, },
onFocus() { onFocus() {
this.showSelector = true this.showSelector = true
}, },
onBlur() { onBlur() {
setTimeout(() => { setTimeout(() => {
this.showSelector = false this.showSelector = false
}, 153) }, 153)
}, },
onSelectorClick(index) { onSelectorClick(index) {
this.inputVal = this.filterCandidates[index] this.inputVal = this.filterCandidates[index]
this.showSelector = false this.showSelector = false
this.$emit('input', this.inputVal) this.$emit('input', this.inputVal)
}, },
onInput() { onInput() {
setTimeout(() => { setTimeout(() => {
this.$emit('input', this.inputVal) this.$emit('input', this.inputVal)
}) })
} }
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.uni-combox { .uni-combox {
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
display: flex; display: flex;
/* #endif */ /* #endif */
height: 40px; height: 40px;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
// border-bottom: solid 1px #DDDDDD; // border-bottom: solid 1px #DDDDDD;
} }
.uni-combox__label { .uni-combox__label {
font-size: 16px; font-size: 16px;
line-height: 22px; line-height: 22px;
padding-right: 10px; padding-right: 10px;
color: #999999; color: #999999;
} }
.uni-combox__input-box { .uni-combox__input-box {
position: relative; position: relative;
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
display: flex; display: flex;
/* #endif */ /* #endif */
flex: 1; flex: 1;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
} }
.uni-combox__input { .uni-combox__input {
flex: 1; flex: 1;
font-size: 16px; font-size: 16px;
height: 22px; height: 22px;
line-height: 22px; line-height: 22px;
} }
.uni-combox__input-arrow { .uni-combox__input-arrow {
padding: 10px; padding: 10px;
} }
.uni-combox__selector { .uni-combox__selector {
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
box-sizing: border-box; box-sizing: border-box;
/* #endif */ /* #endif */
position: absolute; position: absolute;
top: 42px; top: 42px;
left: 0; left: 0;
width: 100%; width: 100%;
background-color: #FFFFFF; background-color: #FFFFFF;
border-radius: 6px; border-radius: 6px;
box-shadow: #DDDDDD 4px 4px 8px, #DDDDDD -4px -4px 8px; box-shadow: #DDDDDD 4px 4px 8px, #DDDDDD -4px -4px 8px;
z-index: 2; z-index: 2;
} }
.uni-combox__selector-scroll { .uni-combox__selector-scroll {
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
max-height: 200px; max-height: 200px;
box-sizing: border-box; box-sizing: border-box;
/* #endif */ /* #endif */
} }
.uni-combox__selector::before { .uni-combox__selector::before {
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
content: ''; content: '';
/* #endif */ /* #endif */
position: absolute; position: absolute;
width: 0; width: 0;
height: 0; height: 0;
border-bottom: solid 6px #FFFFFF; border-bottom: solid 6px #FFFFFF;
border-right: solid 6px transparent; border-right: solid 6px transparent;
border-left: solid 6px transparent; border-left: solid 6px transparent;
left: 50%; left: 50%;
top: -6px; top: -6px;
margin-left: -6px; margin-left: -6px;
} }
.uni-combox__selector-empty, .uni-combox__selector-empty,
.uni-combox__selector-item { .uni-combox__selector-item {
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
display: flex; display: flex;
cursor: pointer; cursor: pointer;
/* #endif */ /* #endif */
line-height: 36px; line-height: 36px;
font-size: 14px; font-size: 14px;
text-align: center; text-align: center;
border-bottom: solid 1px #DDDDDD; border-bottom: solid 1px #DDDDDD;
margin: 0px 10px; margin: 0px 10px;
} }
.uni-combox__selector-empty:last-child, .uni-combox__selector-empty:last-child,
.uni-combox__selector-item:last-child { .uni-combox__selector-item:last-child {
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
border-bottom: none; border-bottom: none;
/* #endif */ /* #endif */
} }
</style> </style>
{ {
"id": "uni-combox", "id": "uni-combox",
"displayName": "Combox 组合框", "displayName": "uni-combox 组合框",
"version": "0.0.4", "version": "0.0.6",
"description": "可以选择也可以输入的表单项 ", "description": "可以选择也可以输入的表单项 ",
"keywords": [ "keywords": [
"combox", "uni-ui",
"组合框", "uniui",
"可下拉输入框", "combox",
"select" "组合框",
], "select"
"repository": "https://github.com/dcloudio/uni-ui", ],
"engines": { "repository": "https://github.com/dcloudio/uni-ui",
"HBuilderX": "" "engines": {
}, "HBuilderX": ""
"directories": { },
"example": "../../temps/example_temps" "directories": {
}, "example": "../../temps/example_temps"
"dcloudext": { },
"category": [ "dcloudext": {
"前端组件", "category": [
"通用组件" "前端组件",
], "通用组件"
"sale": { ],
"regular": { "sale": {
"price": "0.00" "regular": {
}, "price": "0.00"
"sourcecode": { },
"price": "0.00" "sourcecode": {
} "price": "0.00"
}, }
"contact": { },
"qq": "" "contact": {
}, "qq": ""
"declaration": { },
"ads": "无", "declaration": {
"data": "无", "ads": "无",
"permissions": "无" "data": "无",
}, "permissions": "无"
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" },
}, "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
"uni_modules": { },
"dependencies": [], "uni_modules": {
"encrypt": [], "dependencies": [
"platforms": { "uni-icons"
"cloud": { ],
"tcb": "y", "encrypt": [],
"aliyun": "y" "platforms": {
}, "cloud": {
"client": { "tcb": "y",
"App": { "aliyun": "y"
"app-vue": "y", },
"app-nvue": "n" "client": {
}, "App": {
"H5-mobile": { "app-vue": "y",
"Safari": "y", "app-nvue": "n"
"Android Browser": "y", },
"微信浏览器(Android)": "y", "H5-mobile": {
"QQ浏览器(Android)": "y" "Safari": "y",
}, "Android Browser": "y",
"H5-pc": { "微信浏览器(Android)": "y",
"Chrome": "y", "QQ浏览器(Android)": "y"
"IE": "y", },
"Edge": "y", "H5-pc": {
"Firefox": "y", "Chrome": "y",
"Safari": "y" "IE": "y",
}, "Edge": "y",
"小程序": { "Firefox": "y",
"微信": "y", "Safari": "y"
"阿里": "y", },
"百度": "y", "小程序": {
"字节跳动": "y", "微信": "y",
"QQ": "y" "阿里": "y",
}, "百度": "y",
"快应用": { "字节跳动": "y",
"华为": "u", "QQ": "y"
"联盟": "u" },
} "快应用": {
} "华为": "u",
} "联盟": "u"
} }
}
}
}
} }
\ No newline at end of file
## Combox 组合框 ## Combox 组合框
> **组件名:uni-combox**
> 代码块: `uCombox` > 代码块: `uCombox`
...@@ -44,3 +45,8 @@ ...@@ -44,3 +45,8 @@
## 组件示例
点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/combox/combox](https://hellouniapp.dcloud.net.cn/pages/extUI/combox/combox)
\ No newline at end of file
{ {
"passwordSecret": "passwordSecret-demo", "passwordSecret": "passwordSecret-demo",
"tokenSecret": "tokenSecret-demo", "tokenSecret": "tokenSecret-demo",
"tokenExpiresIn": 7200, "tokenExpiresIn": 7200,
"tokenExpiresThreshold": 600, "tokenExpiresThreshold": 600,
"passwordErrorLimit": 6, "passwordErrorLimit": 6,
"bindTokenToDevice": false, "bindTokenToDevice": false,
"passwordErrorRetryTime": 3600, "passwordErrorRetryTime": 3600,
"autoSetInviteCode": false, "autoSetInviteCode": false,
"forceInviteCode": false, "forceInviteCode": false,
"app-plus": { "app-plus": {
"tokenExpiresIn": 2592000, "tokenExpiresIn": 2592000,
"oauth": { "oauth": {
"weixin": { "weixin": {
"appid": "填写来源微信开放平台https://open.weixin.qq.com/创建的应用的appid", "appid": "wxffdd8fa6ec4ef2a0",
"appsecret": "填写来源微信开放平台https://open.weixin.qq.com/创建的应用的appsecret" "appsecret": "6c9119430d7be0a147bcbbb73ef33acf"
}, },
"apple": { "apple": {
"bundleId": "苹果开发者后台获取的bundleId" "bundleId": "苹果开发者后台获取的bundleId"
} }
} }
}, },
"mp-weixin": { "mp-weixin": {
"oauth": { "oauth": {
"weixin": { "weixin": {
"appid": "微信小程序登录所用的appid、appsecret需要在对应的小程序管理控制台获取", "appid": "wx81dbb061d2258234",
"appsecret": "微信小程序后台获取的appsecret" "appsecret": "51977820eb14cd71377d4048a1b4754e"
} }
} }
}, },
"mp-alipay": { "mp-alipay": {
"oauth": { "oauth": {
"alipay": { "alipay": {
"appid": "支付宝小程序登录用到的appid、privateKey请参考支付宝小程序的文档进行设置或者获取,https://opendocs.alipay.com/open/291/105971#LDsXr", "appid": "支付宝小程序登录用到的appid、privateKey请参考支付宝小程序的文档进行设置或者获取,https://opendocs.alipay.com/open/291/105971#LDsXr",
"privateKey": "支付宝小程序登录用到的appid、privateKey请参考支付宝小程序的文档进行设置或者获取,https://opendocs.alipay.com/open/291/105971#LDsXr" "privateKey": "支付宝小程序登录用到的appid、privateKey请参考支付宝小程序的文档进行设置或者获取,https://opendocs.alipay.com/open/291/105971#LDsXr"
} }
} }
}, },
"service": { "service": {
"sms": { "sms": {
"name": "应用名称,对应短信模版的name", "name": "应用名称,对应短信模版的name",
"codeExpiresIn": 300, "codeExpiresIn": 300,
"smsKey": "短信密钥key,开通短信服务处可以看到", "smsKey": "短信密钥key,开通短信服务处可以看到",
"smsSecret": "短信密钥secret,开通短信服务处可以看到" "smsSecret": "短信密钥secret,开通短信服务处可以看到"
}, },
"univerify": { "univerify": {
"appid": "当前应用的appid,使用云函数URL化,此项必须配置", "appid": "__UNI__03B096E",
"apiKey": "apiKey 和 apiSecret 在开发者中心获取,开发者中心:https://dev.dcloud.net.cn/uniLogin/index?type=0,文档:https://ask.dcloud.net.cn/article/37965", "apiKey": "3fc28519d90d74173bcecf2daf4ffcc4",
"apiSecret": "" "apiSecret": "dd793e5bc4b372ce932f35bbb4c5d61b"
} }
} }
} }
\ No newline at end of file
## 1.0.5(2021-06-18)
- 修复 uni-countdown 重复赋值跳两秒的 bug
## 1.0.4(2021-05-12)
- 新增 组件示例地址
## 1.0.3(2021-05-08)
- 修复 uni-countdown 不能控制倒计时的 bug
## 1.0.2(2021-02-04) ## 1.0.2(2021-02-04)
- 调整为uni_modules目录规范 - 调整为uni_modules目录规范
{ {
"id": "uni-countdown", "id": "uni-countdown",
"displayName": "Countdown 倒计时", "displayName": "uni-countdown 倒计时",
"version": "1.0.2", "version": "1.0.5",
"description": "CountDown 倒计时组件", "description": "CountDown 倒计时组件",
"keywords": [ "keywords": [
"countdown",
"uni-ui", "uni-ui",
"uniui",
"countdown",
"倒计时" "倒计时"
], ],
"repository": "https://github.com/dcloudio/uni-ui", "repository": "https://github.com/dcloudio/uni-ui",
......
## CountDown 倒计时 ## CountDown 倒计时
> **组件名:uni-countdown**
> 代码块: `uCountDown` > 代码块: `uCountDown`
...@@ -42,9 +43,15 @@ ...@@ -42,9 +43,15 @@
|second |Number |0 |秒 | |second |Number |0 |秒 |
|showDay |Boolean|true |是否显示天数 | |showDay |Boolean|true |是否显示天数 |
|showColon |Boolean|true |是否以冒号为分隔符 | |showColon |Boolean|true |是否以冒号为分隔符 |
|start |Boolean|true |是否初始化组件后就开始倒计时|
### Countdown Events ### Countdown Events
|事件称名 |说明 |返回值 | |事件称名 |说明 |返回值 |
|:-: |:-: |:-: | |:-: |:-: |:-: |
|@timeup|倒计时时间到触发事件 |- | |@timeup|倒计时时间到触发事件 |- |
## 组件示例
点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/countdown/countdown](https://hellouniapp.dcloud.net.cn/pages/extUI/countdown/countdown)
\ No newline at end of file
## 0.1.4(2021-04-09) ## 0.2.0(2021-07-13)
- 修复 nvue 下无法选中的问题 - 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 0.1.3(2021-03-22) ## 0.1.11(2021-07-06)
- 新增 disabled属性 - 优化 删除无用日志
## 0.1.2(2021-02-24) ## 0.1.10(2021-07-05)
- 优化 默认颜色显示 - 修复 由 0.1.9 引起的非 nvue 端图标不显示的问题
## 0.1.1(2021-02-24) ## 0.1.9(2021-07-05)
- 新增 支持nvue - 修复 nvue 黑框样式问题
## 0.1.0(2021-02-18) ## 0.1.8(2021-06-28)
- “暂无数据”显示居中 - 修复 selectedTextColor 属性不生效的Bug
## 0.1.7(2021-06-02)
- 新增 map 属性,可以方便映射text/value属性
## 0.1.6(2021-05-26)
- 修复 不关联服务空间的情况下组件报错的Bug
## 0.1.5(2021-05-12)
- 新增 组件示例地址
## 0.1.4(2021-04-09)
- 修复 nvue 下无法选中的问题
## 0.1.3(2021-03-22)
- 新增 disabled属性
## 0.1.2(2021-02-24)
- 优化 默认颜色显示
## 0.1.1(2021-02-24)
- 新增 支持nvue
## 0.1.0(2021-02-18)
- “暂无数据”显示居中
...@@ -263,6 +263,7 @@ export default { ...@@ -263,6 +263,7 @@ export default {
|selectedColor|String |- |#007aff|选中颜色| |selectedColor|String |- |#007aff|选中颜色|
|selectedTextColor|String |- |#333 |选中文本颜色,如不填写则自动显示| |selectedTextColor|String |- |#333 |选中文本颜色,如不填写则自动显示|
|emptyText |String |- |暂无数据 |没有数据时显示的文字 ,本地数据无效| |emptyText |String |- |暂无数据 |没有数据时显示的文字 ,本地数据无效|
|map |Object |- |{text:'text',value:'value'} |字段映射,将text/value映射到数据中的其他字段|
#### Localdata Options #### Localdata Options
...@@ -288,6 +289,11 @@ export default { ...@@ -288,6 +289,11 @@ export default {
| 事件名 | 事件说明 | 返回参数| | 事件名 | 事件说明 | 返回参数|
| :-: | :-: | :-: | | :-: | :-: | :-: |
| @chage| 选中状态改变时触发事件 | - | | @change| 选中状态改变时触发事件 | - |
## 组件示例
点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/data-checkbox/data-checkbox](https://hellouniapp.dcloud.net.cn/pages/extUI/data-checkbox/data-checkbox)
\ No newline at end of file
## 0.3.1(2021-04-15) ## 0.4.0(2021-07-13)
- 修复 本地数据概率无法回显时问题 - 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 0.3.0(2021-04-07) ## 0.3.5(2021-06-04)
- 新增 支持云端非树形表结构数据 - 修复 无法加载云端数据的问题
- 修复 根节点 parent_field 字段等于null时选择界面错乱问题 ## 0.3.4(2021-05-28)
## 0.2.0(2021-03-15) - 修复 v-model无效问题
- 修复 nodeclick、popupopened、popupclosed事件无法触发的问题 - 修复 loaddata 为空数据组时加载时间过长问题
## 0.1.9(2021-03-09) - 修复 上个版本引出的本地数据无法选择带有children的2级节点
- 修复 微信小程序某些情况下无法选择的问题 ## 0.3.3(2021-05-12)
## 0.1.8(2021-02-05) - 新增 组件示例地址
- 优化 部分样式在nvue上的兼容表现 ## 0.3.2(2021-04-22)
## 0.1.7(2021-02-05) - 修复 非树形数据有 where 属性查询报错的问题
- 调整为uni_modules目录规范 ## 0.3.1(2021-04-15)
- 修复 本地数据概率无法回显时问题
## 0.3.0(2021-04-07)
- 新增 支持云端非树形表结构数据
- 修复 根节点 parent_field 字段等于null时选择界面错乱问题
## 0.2.0(2021-03-15)
- 修复 nodeclick、popupopened、popupclosed事件无法触发的问题
## 0.1.9(2021-03-09)
- 修复 微信小程序某些情况下无法选择的问题
## 0.1.8(2021-02-05)
- 优化 部分样式在nvue上的兼容表现
## 0.1.7(2021-02-05)
- 调整为uni_modules目录规范
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册