@ -0,0 +1,132 @@ | |||
<template> | |||
<uv-popup ref="popup" z-index="99999" :closeOnClickOverlay="false" :customStyle="{ backgroundColor: 'transparent' }"> | |||
<view class="privacyPopup"> | |||
<view class="title"> | |||
<view>协议与隐私政策</view> | |||
</view> | |||
<view class="content_pri"> | |||
<view class="text"> | |||
欢迎来到xx报修!我们根据最新的法律法规、监管政策要求,更新了《用户协议》和《隐私政策》,请您认真阅读。 | |||
</view> | |||
</view> | |||
<view class="config"> | |||
<uv-checkbox-group v-model="checkboxValue" shape="circle"> | |||
<view class="content"> | |||
<view style="display: flex;"> | |||
<uv-checkbox size="30rpx" :name="1"></uv-checkbox> | |||
同意<text>《xx报修隐私政策》</text> | |||
</view> | |||
<view class=""> | |||
以及<text>《用户协议》</text> | |||
</view> | |||
</view> | |||
</uv-checkbox-group> | |||
</view> | |||
<view class="pri_btn"> | |||
<!-- <button class="confuse_btn" @click="confusePrivacy">拒绝</button> --> | |||
<button class="confirm_btn" id="agree-btn" open-type="agreePrivacyAuthorization" | |||
@agreeprivacyauthorization="handleAgreePrivacyAuthorization">同意</button> | |||
</view> | |||
</view> | |||
</uv-popup> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'PrivacyAgreementPoup', | |||
data() { | |||
return { | |||
resolvePrivacyAuthorization: {}, | |||
checkboxValue : false | |||
} | |||
}, | |||
methods: { | |||
//初始化 | |||
init(resolve) { | |||
this.$refs.popup.open('center') | |||
this.resolvePrivacyAuthorization = resolve | |||
}, | |||
// 打开隐私协议 | |||
goToPrivacy() { | |||
wx.openPrivacyContract({ | |||
success: () => { | |||
console.log('打开成功'); | |||
}, // 打开成功 | |||
fail: () => { | |||
uni.showToast({ | |||
title: '打开失败,稍后重试', | |||
icon: 'none' | |||
}) | |||
} // 打开失败 | |||
}) | |||
}, | |||
// 拒绝 | |||
confusePrivacy() { | |||
this.$refs.popup.close() | |||
this.resolvePrivacyAuthorization({ | |||
event: 'disagree' | |||
}) | |||
}, | |||
// 同意 | |||
handleAgreePrivacyAuthorization() { | |||
// 告知平台用户已经同意,参数传同意按钮的id | |||
this.resolvePrivacyAuthorization({ | |||
buttonId: 'agree-btn', | |||
event: 'agree' | |||
}) | |||
this.$refs.popup.close() | |||
} | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.privacyPopup { | |||
width: 90%; | |||
margin: 0rpx auto; | |||
background: white; | |||
border-radius: 20rpx; | |||
box-sizing: border-box; | |||
padding: 40rpx 30rpx; | |||
.title { | |||
text-align: center; | |||
font-size: 36rpx; | |||
} | |||
.content_pri { | |||
padding: 30rpx 0rpx; | |||
font-size: 28rpx; | |||
} | |||
.config { | |||
font-size: 28rpx; | |||
text-align: center; | |||
line-height: 40rpx; | |||
margin-bottom: 30rpx; | |||
text { | |||
color: #00aaff; | |||
} | |||
.content{ | |||
display: flex; | |||
} | |||
} | |||
.pri_btn { | |||
button { | |||
background: #00aaff; | |||
outline: none; | |||
color: white; | |||
font-size: 30rpx; | |||
} | |||
} | |||
} | |||
</style> |
@ -0,0 +1,47 @@ | |||
<template> | |||
<view class="configPopup"> | |||
<uv-popup ref="popup" :round="30" :customStyle="{height: '50vh'}"> | |||
<view class="content"> | |||
<uv-parse :content="content"></uv-parse> | |||
</view> | |||
</uv-popup> | |||
</view> | |||
</template> | |||
<script> | |||
import { mapGetters } from 'vuex' | |||
export default { | |||
name: 'configPoup', | |||
data() { | |||
return { | |||
content : '' | |||
} | |||
}, | |||
onShow(){ | |||
console.log(this.getConfig); | |||
}, | |||
methods: { | |||
//打开配置信息菜单 | |||
open(key){ | |||
console.log(key); | |||
this.content = this.getConfig[key] | |||
this.$refs.popup.open('bottom'); | |||
} | |||
}, | |||
computed : { | |||
...mapGetters(['getConfig']) | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.configPopup { | |||
.content{ | |||
padding: 30rpx 20rpx; | |||
} | |||
} | |||
</style> |
@ -0,0 +1,167 @@ | |||
<template> | |||
<view class=""> | |||
<uni-nav-bar dark :fixed="true" background-color="#00aaff" :border="false" status-bar title="个人中心" /> | |||
<view class="content"> | |||
<view class="topBox"> | |||
<view class="users"> | |||
<view class="u-top" v-if="userInfo.appletOpenid"> | |||
<image class="img" :src="userInfo.headImage" mode="widthFix"></image> | |||
<view class="tit"> | |||
{{ userInfo.nickName }} | |||
</view> | |||
</view> | |||
<view class="u-top" v-else> | |||
<image class="img" | |||
src="https://img2.baidu.com/it/u=2953585264,744730101&fm=253&fmt=auto&app=138&f=JPEG?w=360&h=360" | |||
mode="widthFix"></image> | |||
<view class="tit"> | |||
登录 / 注册 | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="lists"> | |||
<uni-list> | |||
<uni-list-item :show-extra-icon="true" :extra-icon="extraIcon1" showArrow title="我的报修" clickable | |||
@click="clickList" /> | |||
</uni-list> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
import { | |||
mapState, | |||
} from 'vuex' | |||
export default { | |||
name: 'Center', | |||
computed: { | |||
...mapState(['userInfo']), | |||
}, | |||
data() { | |||
return { | |||
queryParams: { | |||
pageNo: 1, | |||
pageSize: 10 | |||
}, | |||
orderList: [], | |||
extraIcon1: { | |||
color: '#666666', | |||
size: '22', | |||
type: 'auth' | |||
} | |||
} | |||
}, | |||
onShow() { | |||
// if (uni.getStorageSync('token')) { | |||
// this.$store.commit('getUserInfo') | |||
// } | |||
}, | |||
methods: { | |||
clickList() { | |||
uni.navigateTo({ | |||
url: '/pages/repairList/repairList' | |||
}) | |||
} | |||
} | |||
} | |||
</script> | |||
<style scoped> | |||
.content { | |||
background: #F1F5F8; | |||
min-height: 100vh; | |||
} | |||
/* 弧形背景 */ | |||
.topBox { | |||
width: 100%; | |||
position: relative; | |||
z-index: 1; | |||
overflow: hidden; | |||
padding: 60rpx 20rpx 20rpx; | |||
box-sizing: border-box; | |||
} | |||
.topBox::after { | |||
content: ""; | |||
width: 140%; | |||
height: 100px; | |||
position: absolute; | |||
left: -20%; | |||
top: 0; | |||
z-index: -1; | |||
border-radius: 0 0 30% 50%; | |||
background: #00aaff; | |||
} | |||
.txt { | |||
color: #fff; | |||
font-size: 30rpx; | |||
} | |||
.set-right .uni-icons { | |||
margin-right: 10rpx; | |||
} | |||
.users { | |||
display: flex; | |||
align-items: center; | |||
margin-top: 0rpx; | |||
padding: 0rpx 30rpx; | |||
box-sizing: border-box; | |||
height: 200rpx; | |||
background-color: #fff; | |||
box-shadow: 1px 10rpx 20rpx #ececec; | |||
border-radius: 12rpx; | |||
} | |||
.u-top { | |||
display: flex; | |||
justify-content: flex-start; | |||
align-items: center; | |||
} | |||
.users .u-top .img { | |||
width: 130rpx; | |||
height: 130rpx; | |||
border-radius: 50%; | |||
margin-right: 20rpx; | |||
} | |||
.u-top .tit { | |||
font-size: 30rpx; | |||
font-weight: 700; | |||
color: #333; | |||
} | |||
.u-item { | |||
text-align: center; | |||
} | |||
.u-item .u-tit { | |||
color: #757575; | |||
font-size: 26rpx; | |||
margin-top: 10rpx; | |||
} | |||
.u-item .num { | |||
color: #000000; | |||
font-size: 33rpx; | |||
font-weight: 700; | |||
} | |||
.bottomBox { | |||
padding: 20rpx; | |||
box-sizing: border-box; | |||
} | |||
.listBox { | |||
margin: -10rpx auto 0; | |||
padding: 20rpx; | |||
box-sizing: border-box; | |||
border-radius: 20rpx; | |||
} | |||
</style> |
@ -1,195 +1,149 @@ | |||
<template> | |||
<view class="content"> | |||
<!-- app和小程序使用以下svg会报错 h5正常 --> | |||
<!-- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | |||
width="100%" height="100%" viewBox="0 0 1600 900" preserveAspectRatio="xMidYMax slice"> | |||
<defs> | |||
<linearGradient id="bg"> | |||
<stop offset="0%" style="stop-color:rgba(130, 158, 249, 0.06)"></stop> | |||
<stop offset="50%" style="stop-color:rgba(76, 190, 255, 0.6)"></stop> | |||
<stop offset="100%" style="stop-color:rgba(115, 209, 72, 0.2)"></stop> | |||
</linearGradient> | |||
<path id="wave" fill="url(#bg)" | |||
d="M-363.852,502.589c0,0,236.988-41.997,505.475,0 | |||
s371.981,38.998,575.971,0s293.985-39.278,505.474,5.859s493.475,48.368,716.963-4.995v560.106H-363.852V502.589z" /> | |||
</defs> | |||
<g> | |||
<use xlink:href='#wave' opacity=".3"> | |||
<animateTransform attributeName="transform" attributeType="XML" type="translate" dur="10s" | |||
calcMode="spline" values="270 230; -334 180; 270 230" keyTimes="0; .5; 1" | |||
keySplines="0.42, 0, 0.58, 1.0;0.42, 0, 0.58, 1.0" repeatCount="indefinite" /> | |||
</use> | |||
<use xlink:href='#wave' opacity=".6"> | |||
<animateTransform attributeName="transform" attributeType="XML" type="translate" dur="8s" | |||
calcMode="spline" values="-270 230;243 220;-270 230" keyTimes="0; .6; 1" | |||
keySplines="0.42, 0, 0.58, 1.0;0.42, 0, 0.58, 1.0" repeatCount="indefinite" /> | |||
</use> | |||
<use xlink:href='#wave' opacty=".9"> | |||
<animateTransform attributeName="transform" attributeType="XML" type="translate" dur="6s" | |||
calcMode="spline" values="0 230;-140 200;0 230" keyTimes="0; .4; 1" | |||
keySplines="0.42, 0, 0.58, 1.0;0.42, 0, 0.58, 1.0" repeatCount="indefinite" /> | |||
</use> | |||
</g> | |||
</svg> --> | |||
<view class="loginBox"> | |||
<h3 style="text-align: center;margin-bottom:120rpx;">欢迎登录</h3> | |||
<view class="inputBox"> | |||
<view class="ipt"> | |||
<uni-icons type="contact" size="24" color="rgb(66,157,250)"></uni-icons> | |||
<input type="text" value="" placeholder="请输入手机号"/> | |||
</view> | |||
<view class="ipt"> | |||
<uni-icons type="eye" size="24" color="rgb(66,157,250)"></uni-icons> | |||
<input type="passsword" value="" placeholder="请输入密码"/> | |||
</view> | |||
<view class="ipt"> | |||
<uni-icons type="checkmarkempty" size="24" color="rgb(66,157,250)"></uni-icons> | |||
<input type="text" value="" placeholder="请输入验证码"/> | |||
<view class="yzm"> | |||
验证码 | |||
</view> | |||
</view> | |||
<button @click="login">登录</button> | |||
<view class="forgetPwd"> | |||
<!-- <span>忘记密码</span> --> | |||
<!-- <span>没有账号,去注册</span> --> | |||
</view> | |||
</view> | |||
<view class="tipbox"> | |||
<view class="txt"> | |||
—— 其他账号登录 —— | |||
</view> | |||
<view class="otherUser"> | |||
<uni-icons type="weixin" size="40" color="rgb(2,187,17)"></uni-icons> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="login"> | |||
<view class="logo"> | |||
<!-- <image src="/static/image/login/logo.png" mode=""></image> --> | |||
</view> | |||
<view class="title"> | |||
欢迎使用xx报修 | |||
</view> | |||
<view class="btn mt"> | |||
<view class="icon"> | |||
<!-- <image src="/static/image/login/wx.png" mode=""></image> --> | |||
</view> | |||
<view class="" | |||
@click="wxLogin"> | |||
微信授权登录 | |||
</view> | |||
</view> | |||
<!-- <view class="btn b2"> | |||
使用短信验证登录 | |||
</view> --> | |||
<view class="config"> | |||
<uv-checkbox-group | |||
v-model="checkboxValue" | |||
shape="circle"> | |||
<view class="content"> | |||
<view | |||
style="display: flex;"> | |||
<uv-checkbox | |||
size="30rpx" | |||
:name="1" | |||
></uv-checkbox> | |||
阅读并同意我们的<text @click="openConfigDetail('privacyAgreement')">“服务协议与隐私条款”</text> | |||
</view> | |||
<view class=""> | |||
以及<text @click="openConfigDetail('userAgreement')">个人信息保护指引</text> | |||
</view> | |||
</view> | |||
</uv-checkbox-group> | |||
</view> | |||
<configPopup ref="popup"></configPopup> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
data() { | |||
return { | |||
} | |||
}, | |||
methods: { | |||
//登录 | |||
login(){ | |||
uni.switchTab({ | |||
url: '/pages/repair/repair' | |||
}) | |||
import configPopup from '../../components/config/configPopup.vue'; | |||
export default { | |||
name : 'Login', | |||
data() { | |||
return { | |||
checkboxValue : [] | |||
} | |||
}, | |||
methods: { | |||
wxLogin(){ | |||
// this.$store.commit('login') | |||
uni.switchTab({ | |||
url: '/pages/repair/repair' | |||
}) | |||
}, | |||
//打开应用配置 | |||
openConfigDetail(key){ | |||
this.$refs.popup.open(key) | |||
} | |||
} | |||
} | |||
} | |||
} | |||
</script> | |||
<style scoped> | |||
svg { | |||
position: absolute; | |||
bottom: 0; | |||
left: 0; | |||
width: 100%; | |||
height:40%; | |||
box-sizing: border-box; | |||
display: block; | |||
background-color: #ffffff; | |||
} | |||
.loginBox{ | |||
position: absolute; | |||
top: 50%; | |||
left: 50%; | |||
transform: translate(-50%,-60%); | |||
width: 90%; | |||
border-radius: 20rpx; | |||
padding: 60rpx; | |||
box-sizing: border-box; | |||
} | |||
h3{ | |||
color:rgb(66,157,250); | |||
font-size: 40rpx; | |||
letter-spacing: 10rpx; | |||
margin-bottom: 40rpx; | |||
} | |||
.inputBox{ | |||
} | |||
.ipt{ | |||
height: 86rpx; | |||
display: flex; | |||
justify-content: flex-start; | |||
align-items: center; | |||
margin-bottom: 40rpx; | |||
background-color: #f5f5f5; | |||
border-radius: 10rpx; | |||
padding-left: 10rpx; | |||
} | |||
.ipt input{ | |||
margin-left: 20rpx; | |||
font-size: 28rpx; | |||
} | |||
.ipt input{ | |||
margin-left: 20rpx; | |||
} | |||
.forgetPwd{ | |||
margin-top: 30rpx; | |||
font-size: 26rpx; | |||
color: #b5b5b5; | |||
text-align: end; | |||
padding:0 10rpx; | |||
display: flex; | |||
justify-content: space-between; | |||
} | |||
button{ | |||
margin-top: 20rpx; | |||
line-height: 85rpx; | |||
text-align: center; | |||
background: rgb(66,157,250); | |||
border-radius: 40rpx; | |||
color: #fff; | |||
margin-top: 40rpx; | |||
} | |||
.tip{ | |||
text-align: center; | |||
font-size: 28rpx; | |||
position: fixed; | |||
bottom: 50rpx; | |||
left: 50%; | |||
transform: translate(-50%,-50%); | |||
color: #f4f4f4; | |||
} | |||
.tipbox { | |||
text-align: center; | |||
margin-top: 100rpx; | |||
} | |||
.otherUser { | |||
margin-top: 30rpx; | |||
display: flex; | |||
justify-content: center; | |||
} | |||
.txt { | |||
font-size: 28rpx; | |||
color: #cbcbcb; | |||
} | |||
.otherUser .uni-icons { | |||
margin-left: 20rpx; | |||
} | |||
.yzm{ | |||
text-align: end; | |||
font-size: 24rpx; | |||
background: linear-gradient(to right,rgb(66,157,250),rgb(0, 170, 127)); | |||
height: 60rpx; | |||
width: 150rpx; | |||
line-height: 60rpx; | |||
text-align: center; | |||
border-radius: 10rpx; | |||
color: #fff; | |||
} | |||
</style> | |||
<style scoped lang="scss"> | |||
.login{ | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
height: 80vh; | |||
flex-direction: column; | |||
position: relative; | |||
.logo{ | |||
height: 80rpx; | |||
width: 80rpx; | |||
padding: 40rpx 30rpx; | |||
background-color: #ddd; | |||
border-radius: 70rpx; | |||
image{ | |||
width: 80rpx; | |||
height: 80rpx; | |||
} | |||
margin-bottom: 20rpx; | |||
} | |||
.title{ | |||
position: relative; | |||
font-weight: 900; | |||
font-size: 45rpx; | |||
&::after{ | |||
content: ''; | |||
position: absolute; | |||
left: 0; | |||
top: 100%; | |||
display: block; | |||
height: 8rpx; | |||
width: 210rpx; | |||
background: linear-gradient(to right,#00aaff, #fff); | |||
} | |||
} | |||
.btn{ | |||
width: 80%; | |||
height: 100rpx; | |||
background-color: #00aaff; | |||
color: #fff; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
margin: 20rpx 0; | |||
border-radius: 20rpx; | |||
.icon{ | |||
margin-right: 10rpx; | |||
image{ | |||
width: 40rpx; | |||
height: 35rpx; | |||
} | |||
} | |||
} | |||
.b2{ | |||
background-color: #3c69f122; | |||
color: #3c69f1; | |||
} | |||
.mt{ | |||
margin-top: 200rpx; | |||
} | |||
.config{ | |||
position: absolute; | |||
bottom: 0; | |||
font-size: 22rpx; | |||
text-align: center; | |||
line-height: 40rpx; | |||
text{ | |||
color: #00aaff; | |||
} | |||
} | |||
} | |||
</style> |
@ -0,0 +1,131 @@ | |||
<template> | |||
<view class="login"> | |||
<view class="title"> | |||
帧视界 | |||
</view> | |||
<view class="title"> | |||
申请获取你的头像、昵称 | |||
</view> | |||
<button class="chooseAvatar" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"> | |||
<view class="line"> | |||
<view class=""> | |||
头像 | |||
</view> | |||
<view class=""> | |||
<image :src="userInfo.headImage" v-if="userInfo.headImage" style="width: 60rpx;height: 60rpx;" | |||
mode=""></image> | |||
<image src="/static/login/6.png" v-else style="width: 50rpx;height: 50rpx;" mode=""></image> | |||
</view> | |||
</view> | |||
</button> | |||
<view class="line"> | |||
<view class=""> | |||
昵称 | |||
</view> | |||
<view class=""> | |||
<input type="nickname" placeholder="请输入昵称" style="text-align: right;" id="nickName" | |||
v-model="userInfo.nickName" /> | |||
</view> | |||
</view> | |||
<view class="btn" @click="submit"> | |||
确认 | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
data() { | |||
return { | |||
userInfo: { | |||
headImage: '', | |||
nickName: '', | |||
} | |||
}; | |||
}, | |||
onShow() {}, | |||
computed: {}, | |||
methods: { | |||
onChooseAvatar(res) { | |||
let self = this | |||
self.$Oss.ossUpload(res.target.avatarUrl) | |||
.then(url => { | |||
self.userInfo.headImage = url | |||
}) | |||
}, | |||
submit() { | |||
let self = this | |||
uni.createSelectorQuery().in(this) | |||
.select("#nickName") | |||
.fields({ | |||
properties: ["value"], | |||
}) | |||
.exec((res) => { | |||
const nickName = res?.[0]?.value | |||
self.userInfo.nickName = nickName | |||
if (self.$utils.verificationAll(self.userInfo, { | |||
headImage: '请选择头像', | |||
nickName: '请填写昵称', | |||
})) { | |||
return | |||
} | |||
self.$api('infoUpdateInfo', self.userInfo, res => { | |||
if (res.code == 200) { | |||
uni.navigateBack(-1) | |||
} | |||
}) | |||
}) | |||
}, | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.login { | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: center; | |||
align-items: center; | |||
height: 80vh; | |||
.title { | |||
line-height: 45rpx; | |||
font-weight: 900; | |||
} | |||
.line { | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
width: 80%; | |||
border-bottom: 1px solid #00000023; | |||
padding: 30rpx 0; | |||
margin: 0 auto; | |||
} | |||
.chooseAvatar { | |||
width: 100%; | |||
padding: 0; | |||
margin: 0; | |||
margin-top: 10vh; | |||
border: none; | |||
} | |||
.btn { | |||
// background: $uni-linear-gradient-btn-color; | |||
background: #00aaff; | |||
color: #fff; | |||
width: 80%; | |||
padding: 20rpx 0; | |||
text-align: center; | |||
border-radius: 15rpx; | |||
margin-top: 10vh; | |||
} | |||
} | |||
</style> |
@ -0,0 +1,33 @@ | |||
## 1.2.2(2023-01-28) | |||
- 修复 运行/打包 控制台警告问题 | |||
## 1.2.1(2022-09-05) | |||
- 修复 当 text 超过 max-num 时,badge 的宽度计算是根据 text 的长度计算,更改为 css 计算实际展示宽度,详见:[https://ask.dcloud.net.cn/question/150473](https://ask.dcloud.net.cn/question/150473) | |||
## 1.2.0(2021-11-19) | |||
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) | |||
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-badge](https://uniapp.dcloud.io/component/uniui/uni-badge) | |||
## 1.1.7(2021-11-08) | |||
- 优化 升级ui | |||
- 修改 size 属性默认值调整为 small | |||
- 修改 type 属性,默认值调整为 error,info 替换 default | |||
## 1.1.6(2021-09-22) | |||
- 修复 在字节小程序上样式不生效的 bug | |||
## 1.1.5(2021-07-30) | |||
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) | |||
## 1.1.4(2021-07-29) | |||
- 修复 去掉 nvue 不支持css 的 align-self 属性,nvue 下不暂支持 absolute 属性 | |||
## 1.1.3(2021-06-24) | |||
- 优化 示例项目 | |||
## 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目录规范 |
@ -0,0 +1,268 @@ | |||
<template> | |||
<view class="uni-badge--x"> | |||
<slot /> | |||
<text v-if="text" :class="classNames" :style="[positionStyle, customStyle, dotStyle]" | |||
class="uni-badge" @click="onClick()">{{displayValue}}</text> | |||
</view> | |||
</template> | |||
<script> | |||
/** | |||
* Badge 数字角标 | |||
* @description 数字角标一般和其它控件(列表、9宫格等)配合使用,用于进行数量提示,默认为实心灰色背景 | |||
* @tutorial https://ext.dcloud.net.cn/plugin?id=21 | |||
* @property {String} text 角标内容 | |||
* @property {String} size = [normal|small] 角标内容 | |||
* @property {String} type = [info|primary|success|warning|error] 颜色类型 | |||
* @value info 灰色 | |||
* @value primary 蓝色 | |||
* @value success 绿色 | |||
* @value warning 黄色 | |||
* @value error 红色 | |||
* @property {String} inverted = [true|false] 是否无需背景颜色 | |||
* @property {Number} maxNum 展示封顶的数字值,超过 99 显示 99+ | |||
* @property {String} absolute = [rightTop|rightBottom|leftBottom|leftTop] 开启绝对定位, 角标将定位到其包裹的标签的四角上 | |||
* @value rightTop 右上 | |||
* @value rightBottom 右下 | |||
* @value leftTop 左上 | |||
* @value leftBottom 左下 | |||
* @property {Array[number]} offset 距定位角中心点的偏移量,只有存在 absolute 属性时有效,例如:[-10, -10] 表示向外偏移 10px,[10, 10] 表示向 absolute 指定的内偏移 10px | |||
* @property {String} isDot = [true|false] 是否显示为一个小点 | |||
* @event {Function} click 点击 Badge 触发事件 | |||
* @example <uni-badge text="1"></uni-badge> | |||
*/ | |||
export default { | |||
name: 'UniBadge', | |||
emits: ['click'], | |||
props: { | |||
type: { | |||
type: String, | |||
default: 'error' | |||
}, | |||
inverted: { | |||
type: Boolean, | |||
default: false | |||
}, | |||
isDot: { | |||
type: Boolean, | |||
default: false | |||
}, | |||
maxNum: { | |||
type: Number, | |||
default: 99 | |||
}, | |||
absolute: { | |||
type: String, | |||
default: '' | |||
}, | |||
offset: { | |||
type: Array, | |||
default () { | |||
return [0, 0] | |||
} | |||
}, | |||
text: { | |||
type: [String, Number], | |||
default: '' | |||
}, | |||
size: { | |||
type: String, | |||
default: 'small' | |||
}, | |||
customStyle: { | |||
type: Object, | |||
default () { | |||
return {} | |||
} | |||
} | |||
}, | |||
data() { | |||
return {}; | |||
}, | |||
computed: { | |||
width() { | |||
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' : '' | |||
].join(' ') | |||
}, | |||
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'] | |||
}, | |||
dotStyle() { | |||
if (!this.isDot) return {} | |||
return { | |||
width: '10px', | |||
minWidth: '0', | |||
height: '10px', | |||
padding: '0', | |||
borderRadius: '10px' | |||
} | |||
}, | |||
displayValue() { | |||
const { | |||
isDot, | |||
text, | |||
maxNum | |||
} = this | |||
return isDot ? '' : (Number(text) > maxNum ? `${maxNum}+` : text) | |||
} | |||
}, | |||
methods: { | |||
onClick() { | |||
this.$emit('click'); | |||
} | |||
} | |||
}; | |||
</script> | |||
<style lang="scss" > | |||
$uni-primary: #2979ff !default; | |||
$uni-success: #4cd964 !default; | |||
$uni-warning: #f0ad4e !default; | |||
$uni-error: #dd524d !default; | |||
$uni-info: #909399 !default; | |||
$bage-size: 12px; | |||
$bage-small: scale(0.8); | |||
.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--small { | |||
transform: $bage-small; | |||
transform-origin: center center; | |||
} | |||
.uni-badge { | |||
/* #ifndef APP-NVUE */ | |||
display: flex; | |||
overflow: hidden; | |||
box-sizing: border-box; | |||
font-feature-settings: "tnum"; | |||
min-width: 20px; | |||
/* #endif */ | |||
justify-content: center; | |||
flex-direction: row; | |||
height: 20px; | |||
padding: 0 4px; | |||
line-height: 18px; | |||
color: #fff; | |||
border-radius: 100px; | |||
background-color: $uni-info; | |||
background-color: transparent; | |||
border: 1px solid #fff; | |||
text-align: center; | |||
font-family: 'Helvetica Neue', Helvetica, sans-serif; | |||
font-size: $bage-size; | |||
/* #ifdef H5 */ | |||
z-index: 999; | |||
cursor: pointer; | |||
/* #endif */ | |||
&--info { | |||
color: #fff; | |||
background-color: $uni-info; | |||
} | |||
&--primary { | |||
background-color: $uni-primary; | |||
} | |||
&--success { | |||
background-color: $uni-success; | |||
} | |||
&--warning { | |||
background-color: $uni-warning; | |||
} | |||
&--error { | |||
background-color: $uni-error; | |||
} | |||
&--inverted { | |||
padding: 0 5px 0 0; | |||
color: $uni-info; | |||
} | |||
&--info-inverted { | |||
color: $uni-info; | |||
background-color: transparent; | |||
} | |||
&--primary-inverted { | |||
color: $uni-primary; | |||
background-color: transparent; | |||
} | |||
&--success-inverted { | |||
color: $uni-success; | |||
background-color: transparent; | |||
} | |||
&--warning-inverted { | |||
color: $uni-warning; | |||
background-color: transparent; | |||
} | |||
&--error-inverted { | |||
color: $uni-error; | |||
background-color: transparent; | |||
} | |||
} | |||
</style> |
@ -0,0 +1,85 @@ | |||
{ | |||
"id": "uni-badge", | |||
"displayName": "uni-badge 数字角标", | |||
"version": "1.2.2", | |||
"description": "数字角标(徽章)组件,在元素周围展示消息提醒,一般用于列表、九宫格、按钮等地方。", | |||
"keywords": [ | |||
"", | |||
"badge", | |||
"uni-ui", | |||
"uniui", | |||
"数字角标", | |||
"徽章" | |||
], | |||
"repository": "https://github.com/dcloudio/uni-ui", | |||
"engines": { | |||
"HBuilderX": "" | |||
}, | |||
"directories": { | |||
"example": "../../temps/example_temps" | |||
}, | |||
"dcloudext": { | |||
"sale": { | |||
"regular": { | |||
"price": "0.00" | |||
}, | |||
"sourcecode": { | |||
"price": "0.00" | |||
} | |||
}, | |||
"contact": { | |||
"qq": "" | |||
}, | |||
"declaration": { | |||
"ads": "无", | |||
"data": "无", | |||
"permissions": "无" | |||
}, | |||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", | |||
"type": "component-vue" | |||
}, | |||
"uni_modules": { | |||
"dependencies": ["uni-scss"], | |||
"encrypt": [], | |||
"platforms": { | |||
"cloud": { | |||
"tcb": "y", | |||
"aliyun": "y" | |||
}, | |||
"client": { | |||
"App": { | |||
"app-vue": "y", | |||
"app-nvue": "y" | |||
}, | |||
"H5-mobile": { | |||
"Safari": "y", | |||
"Android Browser": "y", | |||
"微信浏览器(Android)": "y", | |||
"QQ浏览器(Android)": "y" | |||
}, | |||
"H5-pc": { | |||
"Chrome": "y", | |||
"IE": "y", | |||
"Edge": "y", | |||
"Firefox": "y", | |||
"Safari": "y" | |||
}, | |||
"小程序": { | |||
"微信": "y", | |||
"阿里": "y", | |||
"百度": "y", | |||
"字节跳动": "y", | |||
"QQ": "y" | |||
}, | |||
"快应用": { | |||
"华为": "y", | |||
"联盟": "y" | |||
}, | |||
"Vue": { | |||
"vue2": "y", | |||
"vue3": "y" | |||
} | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,10 @@ | |||
## Badge 数字角标 | |||
> **组件名:uni-badge** | |||
> 代码块: `uBadge` | |||
数字角标一般和其它控件(列表、9宫格等)配合使用,用于进行数量提示,默认为实心灰色背景, | |||
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-badge) | |||
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 | |||
@ -0,0 +1,46 @@ | |||
## 1.2.14(2023-04-14) | |||
- 优化 uni-list-chat 具名插槽`header` 非app端套一层元素,方便使用时通过外层元素定位实现样式修改 | |||
## 1.2.13(2023-03-03) | |||
- uni-list-chat 新增 支持具名插槽`header` | |||
## 1.2.12(2023-02-01) | |||
- 新增 列表图标新增 customPrefix 属性 ,用法 [详见](https://uniapp.dcloud.net.cn/component/uniui/uni-icons.html#icons-props) | |||
## 1.2.11(2023-01-31) | |||
- 修复 无反馈效果呈现的bug | |||
## 1.2.9(2022-11-22) | |||
- 修复 uni-list-chat 在vue3下跳转报错的bug | |||
## 1.2.8(2022-11-21) | |||
- 修复 uni-list-chat avatar属性 值为本地路径时错误的问题 | |||
## 1.2.7(2022-11-21) | |||
- 修复 uni-list-chat avatar属性 在腾讯云版uniCloud下错误的问题 | |||
## 1.2.6(2022-11-18) | |||
- 修复 uni-list-chat note属性 支持:“草稿”字样功能 文本少1位的问题 | |||
## 1.2.5(2022-11-15) | |||
- 修复 uni-list-item 的 customStyle 属性 padding值在 H5端 无效的bug | |||
## 1.2.4(2022-11-15) | |||
- 修复 uni-list-item 的 customStyle 属性 padding值在nvue(vue2)下无效的bug | |||
## 1.2.3(2022-11-14) | |||
- uni-list-chat 新增 avatar 支持 fileId | |||
## 1.2.2(2022-11-11) | |||
- uni-list 新增属性 render-reverse 详情参考:[https://uniapp.dcloud.net.cn/component/list.html](https://uniapp.dcloud.net.cn/component/list.html) | |||
- uni-list-chat note属性 支持:“草稿”字样 加红显示 详情参考uni-im:[https://ext.dcloud.net.cn/plugin?name=uni-im](https://ext.dcloud.net.cn/plugin?name=uni-im) | |||
- uni-list-item 新增属性 customStyle 支持设置padding、backgroundColor | |||
## 1.2.1(2022-03-30) | |||
- 删除无用文件 | |||
## 1.2.0(2021-11-23) | |||
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) | |||
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-list](https://uniapp.dcloud.io/component/uniui/uni-list) | |||
## 1.1.3(2021-08-30) | |||
- 修复 在vue3中to属性在发行应用的时候报错的bug | |||
## 1.1.2(2021-07-30) | |||
- 优化 vue3下事件警告的问题 | |||
## 1.1.1(2021-07-21) | |||
- 修复 与其他组件嵌套使用时,点击失效的Bug | |||
## 1.1.0(2021-07-13) | |||
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) | |||
## 1.0.17(2021-05-12) | |||
- 新增 组件示例地址 | |||
## 1.0.16(2021-02-05) | |||
- 优化 组件引用关系,通过uni_modules引用组件 | |||
## 1.0.15(2021-02-05) | |||
- 调整为uni_modules目录规范 | |||
- 修复 uni-list-chat 角标显示不正常的问题 |
@ -0,0 +1,107 @@ | |||
<template> | |||
<!-- #ifdef APP-NVUE --> | |||
<cell> | |||
<!-- #endif --> | |||
<view class="uni-list-ad"> | |||
<view v-if="borderShow" :class="{'uni-list--border':border,'uni-list-item--first':isFirstChild}"></view> | |||
<ad style="width: 200px;height: 300px;border-width: 1px;border-color: red;border-style: solid;" adpid="1111111111" | |||
unit-id="" appid="" apid="" type="feed" @error="aderror" @close="closeAd"></ad> | |||
</view> | |||
<!-- #ifdef APP-NVUE --> | |||
</cell> | |||
<!-- #endif --> | |||
</template> | |||
<script> | |||
// #ifdef APP-NVUE | |||
const dom = uni.requireNativePlugin('dom'); | |||
// #endif | |||
export default { | |||
name: 'UniListAd', | |||
props: { | |||
title: { | |||
type: String, | |||
default: '', | |||
} | |||
}, | |||
// inject: ['list'], | |||
data() { | |||
return { | |||
isFirstChild: false, | |||
border: false, | |||
borderShow: true, | |||
} | |||
}, | |||
mounted() { | |||
this.list = this.getForm() | |||
if (this.list) { | |||
if (!this.list.firstChildAppend) { | |||
this.list.firstChildAppend = true | |||
this.isFirstChild = true | |||
} | |||
this.border = this.list.border | |||
} | |||
}, | |||
methods: { | |||
/** | |||
* 获取父元素实例 | |||
*/ | |||
getForm(name = 'uniList') { | |||
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; | |||
}, | |||
aderror(e) { | |||
console.log("aderror: " + JSON.stringify(e.detail)); | |||
}, | |||
closeAd(e) { | |||
this.borderShow = false | |||
} | |||
} | |||
} | |||
</script> | |||
<style lang="scss" > | |||
.uni-list-ad { | |||
position: relative; | |||
border: 1px red solid; | |||
} | |||
.uni-list--border { | |||
position: relative; | |||
padding-bottom: 1px; | |||
/* #ifdef APP-PLUS */ | |||
border-top-color: $uni-border-color; | |||
border-top-style: solid; | |||
border-top-width: 0.5px; | |||
/* #endif */ | |||
margin-left: $uni-spacing-row-lg; | |||
} | |||
/* #ifndef APP-NVUE */ | |||
.uni-list--border:after { | |||
position: absolute; | |||
top: 0; | |||
right: 0; | |||
left: 0; | |||
height: 1px; | |||
content: ''; | |||
-webkit-transform: scaleY(.5); | |||
transform: scaleY(.5); | |||
background-color: $uni-border-color; | |||
} | |||
.uni-list-item--first:after { | |||
height: 0px; | |||
} | |||
/* #endif */ | |||
</style> |
@ -0,0 +1,58 @@ | |||
/** | |||
* 这里是 uni-list 组件内置的常用样式变量 | |||
* 如果需要覆盖样式,这里提供了基本的组件样式变量,您可以尝试修改这里的变量,去完成样式替换,而不用去修改源码 | |||
* | |||
*/ | |||
// 背景色 | |||
$background-color : #fff; | |||
// 分割线颜色 | |||
$divide-line-color : #e5e5e5; | |||
// 默认头像大小,如需要修改此值,注意同步修改 js 中的值 const avatarWidth = xx ,目前只支持方形头像 | |||
// nvue 页面不支持修改头像大小 | |||
$avatar-width : 45px ; | |||
// 头像边框 | |||
$avatar-border-radius: 5px; | |||
$avatar-border-color: #eee; | |||
$avatar-border-width: 1px; | |||
// 标题文字样式 | |||
$title-size : 16px; | |||
$title-color : #3b4144; | |||
$title-weight : normal; | |||
// 描述文字样式 | |||
$note-size : 12px; | |||
$note-color : #999; | |||
$note-weight : normal; | |||
// 右侧额外内容默认样式 | |||
$right-text-size : 12px; | |||
$right-text-color : #999; | |||
$right-text-weight : normal; | |||
// 角标样式 | |||
// nvue 页面不支持修改圆点位置以及大小 | |||
// 角标在左侧时,角标的位置,默认为 0 ,负数左/下移动,正数右/上移动 | |||
$badge-left: 0px; | |||
$badge-top: 0px; | |||
// 显示圆点时,圆点大小 | |||
$dot-width: 10px; | |||
$dot-height: 10px; | |||
// 显示角标时,角标大小和字体大小 | |||
$badge-size : 18px; | |||
$badge-font : 12px; | |||
// 显示角标时,角标前景色 | |||
$badge-color : #fff; | |||
// 显示角标时,角标背景色 | |||
$badge-background-color : #ff5a5f; | |||
// 显示角标时,角标左右间距 | |||
$badge-space : 6px; | |||
// 状态样式 | |||
// 选中颜色 | |||
$hover : #f5f5f5; |
@ -0,0 +1,593 @@ | |||
<template> | |||
<!-- #ifdef APP-NVUE --> | |||
<cell> | |||
<!-- #endif --> | |||
<view :hover-class="!clickable && !link ? '' : 'uni-list-chat--hover'" class="uni-list-chat" @click.stop="onClick"> | |||
<view :class="{ 'uni-list--border': border, 'uni-list-chat--first': isFirstChild }"></view> | |||
<view class="uni-list-chat__container"> | |||
<view class="uni-list-chat__header-warp"> | |||
<view v-if="avatarCircle || avatarList.length === 0" class="uni-list-chat__header" :class="{ 'header--circle': avatarCircle }"> | |||
<image class="uni-list-chat__header-image" :class="{ 'header--circle': avatarCircle }" :src="avatarUrl" mode="aspectFill"></image> | |||
</view> | |||
<!-- 头像组 --> | |||
<view v-else class="uni-list-chat__header"> | |||
<view v-for="(item, index) in avatarList" :key="index" class="uni-list-chat__header-box" :class="computedAvatar" | |||
:style="{ width: imageWidth + 'px', height: imageWidth + 'px' }"> | |||
<image class="uni-list-chat__header-image" :style="{ width: imageWidth + 'px', height: imageWidth + 'px' }" :src="item.url" | |||
mode="aspectFill"></image> | |||
</view> | |||
</view> | |||
</view> | |||
<!-- #ifndef APP --> | |||
<view class="slot-header"> | |||
<!-- #endif --> | |||
<slot name="header"></slot> | |||
<!-- #ifndef APP --> | |||
</view> | |||
<!-- #endif --> | |||
<view v-if="badgeText && badgePositon === 'left'" class="uni-list-chat__badge uni-list-chat__badge-pos" :class="[isSingle]"> | |||
<text class="uni-list-chat__badge-text">{{ badgeText === 'dot' ? '' : badgeText }}</text> | |||
</view> | |||
<view class="uni-list-chat__content"> | |||
<view class="uni-list-chat__content-main"> | |||
<text class="uni-list-chat__content-title uni-ellipsis">{{ title }}</text> | |||
<view style="flex-direction: row;"> | |||
<text class="draft" v-if="isDraft">[草稿]</text> | |||
<text class="uni-list-chat__content-note uni-ellipsis">{{isDraft?note.slice(14):note}}</text> | |||
</view> | |||
</view> | |||
<view class="uni-list-chat__content-extra"> | |||
<slot> | |||
<text class="uni-list-chat__content-extra-text">{{ time }}</text> | |||
<view v-if="badgeText && badgePositon === 'right'" class="uni-list-chat__badge" :class="[isSingle, badgePositon === 'right' ? 'uni-list-chat--right' : '']"> | |||
<text class="uni-list-chat__badge-text">{{ badgeText === 'dot' ? '' : badgeText }}</text> | |||
</view> | |||
</slot> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<!-- #ifdef APP-NVUE --> | |||
</cell> | |||
<!-- #endif --> | |||
</template> | |||
<script> | |||
// 头像大小 | |||
const avatarWidth = 45; | |||
/** | |||
* ListChat 聊天列表 | |||
* @description 聊天列表,用于创建聊天类列表 | |||
* @tutorial https://ext.dcloud.net.cn/plugin?id=24 | |||
* @property {String} title 标题 | |||
* @property {String} note 描述 | |||
* @property {Boolean} clickable = [true|false] 是否开启点击反馈,默认为false | |||
* @property {String} badgeText 数字角标内容 | |||
* @property {String} badgePositon = [left|right] 角标位置,默认为 right | |||
* @property {String} link = [false|navigateTo|redirectTo|reLaunch|switchTab] 是否展示右侧箭头并开启点击反馈,默认为false | |||
* @value false 不开启 | |||
* @value navigateTo 同 uni.navigateTo() | |||
* @value redirectTo 同 uni.redirectTo() | |||
* @value reLaunch 同 uni.reLaunch() | |||
* @value switchTab 同 uni.switchTab() | |||
* @property {String | PageURIString} to 跳转目标页面 | |||
* @property {String} time 右侧时间显示 | |||
* @property {Boolean} avatarCircle = [true|false] 是否显示圆形头像,默认为false | |||
* @property {String} avatar 头像地址,avatarCircle 不填时生效 | |||
* @property {Array} avatarList 头像组,格式为 [{url:''}] | |||
* @event {Function} click 点击 uniListChat 触发事件 | |||
*/ | |||
export default { | |||
name: 'UniListChat', | |||
emits:['click'], | |||
props: { | |||
title: { | |||
type: String, | |||
default: '' | |||
}, | |||
note: { | |||
type: String, | |||
default: '' | |||
}, | |||
clickable: { | |||
type: Boolean, | |||
default: false | |||
}, | |||
link: { | |||
type: [Boolean, String], | |||
default: false | |||
}, | |||
to: { | |||
type: String, | |||
default: '' | |||
}, | |||
badgeText: { | |||
type: [String, Number], | |||
default: '' | |||
}, | |||
badgePositon: { | |||
type: String, | |||
default: 'right' | |||
}, | |||
time: { | |||
type: String, | |||
default: '' | |||
}, | |||
avatarCircle: { | |||
type: Boolean, | |||
default: false | |||
}, | |||
avatar: { | |||
type: String, | |||
default: '' | |||
}, | |||
avatarList: { | |||
type: Array, | |||
default () { | |||
return []; | |||
} | |||
} | |||
}, | |||
// inject: ['list'], | |||
computed: { | |||
isDraft(){ | |||
return this.note.slice(0,14) == '[uni-im-draft]' | |||
}, | |||
isSingle() { | |||
if (this.badgeText === 'dot') { | |||
return 'uni-badge--dot'; | |||
} else { | |||
const badgeText = this.badgeText.toString(); | |||
if (badgeText.length > 1) { | |||
return 'uni-badge--complex'; | |||
} else { | |||
return 'uni-badge--single'; | |||
} | |||
} | |||
}, | |||
computedAvatar() { | |||
if (this.avatarList.length > 4) { | |||
this.imageWidth = avatarWidth * 0.31; | |||
return 'avatarItem--3'; | |||
} else if (this.avatarList.length > 1) { | |||
this.imageWidth = avatarWidth * 0.47; | |||
return 'avatarItem--2'; | |||
} else { | |||
this.imageWidth = avatarWidth; | |||
return 'avatarItem--1'; | |||
} | |||
} | |||
}, | |||
watch: { | |||
avatar:{ | |||
handler(avatar) { | |||
if(avatar.substr(0,8) == 'cloud://'){ | |||
uniCloud.getTempFileURL({ | |||
fileList: [avatar] | |||
}).then(res=>{ | |||
// console.log(res); | |||
// 兼容uniCloud私有化部署 | |||
let fileList = res.fileList || res.result.fileList | |||
this.avatarUrl = fileList[0].tempFileURL | |||
}) | |||
}else{ | |||
this.avatarUrl = avatar | |||
} | |||
}, | |||
immediate: true | |||
} | |||
}, | |||
data() { | |||
return { | |||
isFirstChild: false, | |||
border: true, | |||
// avatarList: 3, | |||
imageWidth: 50, | |||
avatarUrl:'' | |||
}; | |||
}, | |||
mounted() { | |||
this.list = this.getForm() | |||
if (this.list) { | |||
if (!this.list.firstChildAppend) { | |||
this.list.firstChildAppend = true; | |||
this.isFirstChild = true; | |||
} | |||
this.border = this.list.border; | |||
} | |||
}, | |||
methods: { | |||
/** | |||
* 获取父元素实例 | |||
*/ | |||
getForm(name = 'uniList') { | |||
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; | |||
}, | |||
onClick() { | |||
if (this.to !== '') { | |||
this.openPage(); | |||
return; | |||
} | |||
if (this.clickable || this.link) { | |||
this.$emit('click', { | |||
data: {} | |||
}); | |||
} | |||
}, | |||
openPage() { | |||
if (['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'].indexOf(this.link) !== -1) { | |||
this.pageApi(this.link); | |||
} else { | |||
this.pageApi('navigateTo'); | |||
} | |||
}, | |||
pageApi(api) { | |||
let callback = { | |||
url: this.to, | |||
success: res => { | |||
this.$emit('click', { | |||
data: res | |||
}); | |||
}, | |||
fail: err => { | |||
this.$emit('click', { | |||
data: err | |||
}); | |||
} | |||
} | |||
switch (api) { | |||
case 'navigateTo': | |||
uni.navigateTo(callback) | |||
break | |||
case 'redirectTo': | |||
uni.redirectTo(callback) | |||
break | |||
case 'reLaunch': | |||
uni.reLaunch(callback) | |||
break | |||
case 'switchTab': | |||
uni.switchTab(callback) | |||
break | |||
default: | |||
uni.navigateTo(callback) | |||
} | |||
} | |||
} | |||
}; | |||
</script> | |||
<style lang="scss" > | |||
$uni-font-size-lg:16px; | |||
$uni-spacing-row-sm: 5px; | |||
$uni-spacing-row-base: 10px; | |||
$uni-spacing-row-lg: 15px; | |||
$background-color: #fff; | |||
$divide-line-color: #e5e5e5; | |||
$avatar-width: 45px; | |||
$avatar-border-radius: 5px; | |||
$avatar-border-color: #eee; | |||
$avatar-border-width: 1px; | |||
$title-size: 16px; | |||
$title-color: #3b4144; | |||
$title-weight: normal; | |||
$note-size: 12px; | |||
$note-color: #999; | |||
$note-weight: normal; | |||
$right-text-size: 12px; | |||
$right-text-color: #999; | |||
$right-text-weight: normal; | |||
$badge-left: 0px; | |||
$badge-top: 0px; | |||
$dot-width: 10px; | |||
$dot-height: 10px; | |||
$badge-size: 18px; | |||
$badge-font: 12px; | |||
$badge-color: #fff; | |||
$badge-background-color: #ff5a5f; | |||
$badge-space: 6px; | |||
$hover: #f5f5f5; | |||
.uni-list-chat { | |||
font-size: $uni-font-size-lg; | |||
position: relative; | |||
flex-direction: column; | |||
justify-content: space-between; | |||
background-color: $background-color; | |||
} | |||
// .uni-list-chat--disabled { | |||
// opacity: 0.3; | |||
// } | |||
.uni-list-chat--hover { | |||
background-color: $hover; | |||
} | |||
.uni-list--border { | |||
position: relative; | |||
margin-left: $uni-spacing-row-lg; | |||
/* #ifdef APP-PLUS */ | |||
border-top-color: $divide-line-color; | |||
border-top-style: solid; | |||
border-top-width: 0.5px; | |||
/* #endif */ | |||
} | |||
/* #ifndef APP-NVUE */ | |||
.uni-list--border:after { | |||
position: absolute; | |||
top: 0; | |||
right: 0; | |||
left: 0; | |||
height: 1px; | |||
content: ''; | |||
-webkit-transform: scaleY(0.5); | |||
transform: scaleY(0.5); | |||
background-color: $divide-line-color; | |||
} | |||
.uni-list-item--first:after { | |||
height: 0px; | |||
} | |||
/* #endif */ | |||
.uni-list-chat--first { | |||
border-top-width: 0px; | |||
} | |||
.uni-ellipsis { | |||
/* #ifndef APP-NVUE */ | |||
overflow: hidden; | |||
white-space: nowrap; | |||
text-overflow: ellipsis; | |||
/* #endif */ | |||
/* #ifdef APP-NVUE */ | |||
lines: 1; | |||
/* #endif */ | |||
} | |||
.uni-ellipsis-2 { | |||
/* #ifndef APP-NVUE */ | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
display: -webkit-box; | |||
-webkit-line-clamp: 2; | |||
-webkit-box-orient: vertical; | |||
/* #endif */ | |||
/* #ifdef APP-NVUE */ | |||
lines: 2; | |||
/* #endif */ | |||
} | |||
.uni-list-chat__container { | |||
position: relative; | |||
/* #ifndef APP-NVUE */ | |||
display: flex; | |||
/* #endif */ | |||
flex-direction: row; | |||
flex: 1; | |||
padding: $uni-spacing-row-base $uni-spacing-row-lg; | |||
position: relative; | |||
overflow: hidden; | |||
} | |||
.uni-list-chat__header-warp { | |||
position: relative; | |||
} | |||
.uni-list-chat__header { | |||
/* #ifndef APP-NVUE */ | |||
display: flex; | |||
align-content: center; | |||
/* #endif */ | |||
flex-direction: row; | |||
justify-content: center; | |||
align-items: center; | |||
flex-wrap: wrap-reverse; | |||
/* #ifdef APP-NVUE */ | |||
width: 50px; | |||
height: 50px; | |||
/* #endif */ | |||
/* #ifndef APP-NVUE */ | |||
width: $avatar-width; | |||
height: $avatar-width; | |||
/* #endif */ | |||
border-radius: $avatar-border-radius; | |||
border-color: $avatar-border-color; | |||
border-width: $avatar-border-width; | |||
border-style: solid; | |||
overflow: hidden; | |||
} | |||
.uni-list-chat__header-box { | |||
/* #ifndef APP-PLUS */ | |||
box-sizing: border-box; | |||
display: flex; | |||
width: $avatar-width; | |||
height: $avatar-width; | |||
/* #endif */ | |||
/* #ifdef APP-NVUE */ | |||
width: 50px; | |||
height: 50px; | |||
/* #endif */ | |||
overflow: hidden; | |||
border-radius: 2px; | |||
} | |||
.uni-list-chat__header-image { | |||
margin: 1px; | |||
/* #ifdef APP-NVUE */ | |||
width: 50px; | |||
height: 50px; | |||
/* #endif */ | |||
/* #ifndef APP-NVUE */ | |||
width: $avatar-width; | |||
height: $avatar-width; | |||
/* #endif */ | |||
} | |||
/* #ifndef APP-NVUE */ | |||
.uni-list-chat__header-image { | |||
display: block; | |||
width: 100%; | |||
height: 100%; | |||
} | |||
.avatarItem--1 { | |||
width: 100%; | |||
height: 100%; | |||
} | |||
.avatarItem--2 { | |||
width: 47%; | |||
height: 47%; | |||
} | |||
.avatarItem--3 { | |||
width: 32%; | |||
height: 32%; | |||
} | |||
/* #endif */ | |||
.header--circle { | |||
border-radius: 50%; | |||
} | |||
.uni-list-chat__content { | |||
/* #ifndef APP-NVUE */ | |||
display: flex; | |||
/* #endif */ | |||
flex-direction: row; | |||
flex: 1; | |||
overflow: hidden; | |||
padding: 2px 0; | |||
} | |||
.uni-list-chat__content-main { | |||
/* #ifndef APP-NVUE */ | |||
display: flex; | |||
/* #endif */ | |||
flex-direction: column; | |||
justify-content: space-between; | |||
padding-left: $uni-spacing-row-base; | |||
flex: 1; | |||
overflow: hidden; | |||
} | |||
.uni-list-chat__content-title { | |||
font-size: $title-size; | |||
color: $title-color; | |||
font-weight: $title-weight; | |||
overflow: hidden; | |||
} | |||
.draft ,.uni-list-chat__content-note { | |||
margin-top: 3px; | |||
color: $note-color; | |||
font-size: $note-size; | |||
font-weight: $title-weight; | |||
overflow: hidden; | |||
} | |||
.draft{ | |||
color: #eb3a41; | |||
/* #ifndef APP-NVUE */ | |||
flex-shrink: 0; | |||
/* #endif */ | |||
padding-right: 3px; | |||
} | |||
.uni-list-chat__content-extra { | |||
/* #ifndef APP-NVUE */ | |||
flex-shrink: 0; | |||
display: flex; | |||
/* #endif */ | |||
flex-direction: column; | |||
justify-content: space-between; | |||
align-items: flex-end; | |||
margin-left: 5px; | |||
} | |||
.uni-list-chat__content-extra-text { | |||
color: $right-text-color; | |||
font-size: $right-text-size; | |||
font-weight: $right-text-weight; | |||
overflow: hidden; | |||
} | |||
.uni-list-chat__badge-pos { | |||
position: absolute; | |||
/* #ifdef APP-NVUE */ | |||
left: 55px; | |||
top: 3px; | |||
/* #endif */ | |||
/* #ifndef APP-NVUE */ | |||
left: calc(#{$avatar-width} + 10px - #{$badge-space} + #{$badge-left}); | |||
top: calc(#{$uni-spacing-row-base}/ 2 + 1px + #{$badge-top}); | |||
/* #endif */ | |||
} | |||
.uni-list-chat__badge { | |||
/* #ifndef APP-NVUE */ | |||
display: flex; | |||
/* #endif */ | |||
justify-content: center; | |||
align-items: center; | |||
border-radius: 100px; | |||
background-color: $badge-background-color; | |||
} | |||
.uni-list-chat__badge-text { | |||
color: $badge-color; | |||
font-size: $badge-font; | |||
} | |||
.uni-badge--single { | |||
/* #ifndef APP-NVUE */ | |||
// left: calc(#{$avatar-width} + 7px + #{$badge-left}); | |||
/* #endif */ | |||
width: $badge-size; | |||
height: $badge-size; | |||
} | |||
.uni-badge--complex { | |||
/* #ifdef APP-NVUE */ | |||
left: 50px; | |||
/* #endif */ | |||
/* #ifndef APP-NVUE */ | |||
width: auto; | |||
/* #endif */ | |||
height: $badge-size; | |||
padding: 0 $badge-space; | |||
} | |||
.uni-badge--dot { | |||
/* #ifdef APP-NVUE */ | |||
left: 60px; | |||
top: 6px; | |||
/* #endif */ | |||
/* #ifndef APP-NVUE */ | |||
left: calc(#{$avatar-width} + 15px - #{$dot-width}/ 2 + 1px + #{$badge-left}); | |||
/* #endif */ | |||
width: $dot-width; | |||
height: $dot-height; | |||
padding: 0; | |||
} | |||
.uni-list-chat--right { | |||
/* #ifdef APP-NVUE */ | |||
left: 0; | |||
/* #endif */ | |||
} | |||
</style> |
@ -0,0 +1,534 @@ | |||
<template> | |||
<!-- #ifdef APP-NVUE --> | |||
<cell :keep-scroll-position="keepScrollPosition"> | |||
<!-- #endif --> | |||
<view :class="{ 'uni-list-item--disabled': disabled }" :style="{'background-color':customStyle.backgroundColor}" | |||
:hover-class="(!clickable && !link) || disabled || showSwitch ? '' : 'uni-list-item--hover'" | |||
class="uni-list-item" @click="onClick"> | |||
<view v-if="!isFirstChild" class="border--left" :class="{ 'uni-list--border': border }"></view> | |||
<view class="uni-list-item__container" | |||
:class="{ 'container--right': showArrow || link, 'flex--direction': direction === 'column'}" | |||
:style="{paddingTop:padding.top,paddingLeft:padding.left,paddingRight:padding.right,paddingBottom:padding.bottom}"> | |||
<slot name="header"> | |||
<view class="uni-list-item__header"> | |||
<view v-if="thumb" class="uni-list-item__icon"> | |||
<image :src="thumb" class="uni-list-item__icon-img" :class="['uni-list--' + thumbSize]" /> | |||
</view> | |||
<view v-else-if="showExtraIcon" class="uni-list-item__icon"> | |||
<uni-icons :customPrefix="extraIcon.customPrefix" :color="extraIcon.color" :size="extraIcon.size" :type="extraIcon.type" /> | |||
</view> | |||
</view> | |||
</slot> | |||
<slot name="body"> | |||
<view class="uni-list-item__content" | |||
:class="{ 'uni-list-item__content--center': thumb || showExtraIcon || showBadge || showSwitch }"> | |||
<text v-if="title" class="uni-list-item__content-title" | |||
:class="[ellipsis !== 0 && ellipsis <= 2 ? 'uni-ellipsis-' + ellipsis : '']">{{ title }}</text> | |||
<text v-if="note" class="uni-list-item__content-note">{{ note }}</text> | |||
</view> | |||
</slot> | |||
<slot name="footer"> | |||
<view v-if="rightText || showBadge || showSwitch" class="uni-list-item__extra" | |||
:class="{ 'flex--justify': direction === 'column' }"> | |||
<text v-if="rightText" class="uni-list-item__extra-text">{{ rightText }}</text> | |||
<uni-badge v-if="showBadge" :type="badgeType" :text="badgeText" :custom-style="badgeStyle" /> | |||
<switch v-if="showSwitch" :disabled="disabled" :checked="switchChecked" | |||
@change="onSwitchChange" /> | |||
</view> | |||
</slot> | |||
</view> | |||
<uni-icons v-if="showArrow || link" :size="16" class="uni-icon-wrapper" color="#bbb" type="arrowright" /> | |||
</view> | |||
<!-- #ifdef APP-NVUE --> | |||
</cell> | |||
<!-- #endif --> | |||
</template> | |||
<script> | |||
/** | |||
* ListItem 列表子组件 | |||
* @description 列表子组件 | |||
* @tutorial https://ext.dcloud.net.cn/plugin?id=24 | |||
* @property {String} title 标题 | |||
* @property {String} note 描述 | |||
* @property {String} thumb 左侧缩略图,若thumb有值,则不会显示扩展图标 | |||
* @property {String} thumbSize = [lg|base|sm] 略缩图大小 | |||
* @value lg 大图 | |||
* @value base 一般 | |||
* @value sm 小图 | |||
* @property {String} badgeText 数字角标内容 | |||
* @property {String} badgeType 数字角标类型,参考[uni-icons](https://ext.dcloud.net.cn/plugin?id=21) | |||
* @property {Object} badgeStyle 数字角标样式 | |||
* @property {String} rightText 右侧文字内容 | |||
* @property {Boolean} disabled = [true|false] 是否禁用 | |||
* @property {Boolean} clickable = [true|false] 是否开启点击反馈 | |||
* @property {String} link = [navigateTo|redirectTo|reLaunch|switchTab] 是否展示右侧箭头并开启点击反馈 | |||
* @value navigateTo 同 uni.navigateTo() | |||
* @value redirectTo 同 uni.redirectTo() | |||
* @value reLaunch 同 uni.reLaunch() | |||
* @value switchTab 同 uni.switchTab() | |||
* @property {String | PageURIString} to 跳转目标页面 | |||
* @property {Boolean} showBadge = [true|false] 是否显示数字角标 | |||
* @property {Boolean} showSwitch = [true|false] 是否显示Switch | |||
* @property {Boolean} switchChecked = [true|false] Switch是否被选中 | |||
* @property {Boolean} showExtraIcon = [true|false] 左侧是否显示扩展图标 | |||
* @property {Object} extraIcon 扩展图标参数,格式为 {color: '#4cd964',size: '22',type: 'spinner'} | |||
* @property {String} direction = [row|column] 排版方向 | |||
* @value row 水平排列 | |||
* @value column 垂直排列 | |||
* @event {Function} click 点击 uniListItem 触发事件 | |||
* @event {Function} switchChange 点击切换 Switch 时触发 | |||
*/ | |||
export default { | |||
name: 'UniListItem', | |||
emits: ['click', 'switchChange'], | |||
props: { | |||
direction: { | |||
type: String, | |||
default: 'row' | |||
}, | |||
title: { | |||
type: String, | |||
default: '' | |||
}, | |||
note: { | |||
type: String, | |||
default: '' | |||
}, | |||
ellipsis: { | |||
type: [Number, String], | |||
default: 0 | |||
}, | |||
disabled: { | |||
type: [Boolean, String], | |||
default: false | |||
}, | |||
clickable: { | |||
type: Boolean, | |||
default: false | |||
}, | |||
showArrow: { | |||
type: [Boolean, String], | |||
default: false | |||
}, | |||
link: { | |||
type: [Boolean, String], | |||
default: false | |||
}, | |||
to: { | |||
type: String, | |||
default: '' | |||
}, | |||
showBadge: { | |||
type: [Boolean, String], | |||
default: false | |||
}, | |||
showSwitch: { | |||
type: [Boolean, String], | |||
default: false | |||
}, | |||
switchChecked: { | |||
type: [Boolean, String], | |||
default: false | |||
}, | |||
badgeText: { | |||
type: String, | |||
default: '' | |||
}, | |||
badgeType: { | |||
type: String, | |||
default: 'success' | |||
}, | |||
badgeStyle: { | |||
type: Object, | |||
default () { | |||
return {} | |||
} | |||
}, | |||
rightText: { | |||
type: String, | |||
default: '' | |||
}, | |||
thumb: { | |||
type: String, | |||
default: '' | |||
}, | |||
thumbSize: { | |||
type: String, | |||
default: 'base' | |||
}, | |||
showExtraIcon: { | |||
type: [Boolean, String], | |||
default: false | |||
}, | |||
extraIcon: { | |||
type: Object, | |||
default () { | |||
return { | |||
type: '', | |||
color: '#000000', | |||
size: 20, | |||
customPrefix: '' | |||
}; | |||
} | |||
}, | |||
border: { | |||
type: Boolean, | |||
default: true | |||
}, | |||
customStyle: { | |||
type: Object, | |||
default () { | |||
return { | |||
padding: '', | |||
backgroundColor: '#FFFFFF' | |||
} | |||
} | |||
}, | |||
keepScrollPosition: { | |||
type: Boolean, | |||
default: false | |||
} | |||
}, | |||
watch: { | |||
'customStyle.padding': { | |||
handler(padding) { | |||
if(typeof padding == 'number'){ | |||
padding += '' | |||
} | |||
let paddingArr = padding.split(' ') | |||
if (paddingArr.length === 1) { | |||
const allPadding = paddingArr[0] | |||
this.padding = { | |||
"top": allPadding, | |||
"right": allPadding, | |||
"bottom": allPadding, | |||
"left": allPadding | |||
} | |||
} else if (paddingArr.length === 2) { | |||
const [verticalPadding, horizontalPadding] = paddingArr; | |||
this.padding = { | |||
"top": verticalPadding, | |||
"right": horizontalPadding, | |||
"bottom": verticalPadding, | |||
"left": horizontalPadding | |||
} | |||
} else if (paddingArr.length === 4) { | |||
const [topPadding, rightPadding, bottomPadding, leftPadding] = paddingArr; | |||
this.padding = { | |||
"top": topPadding, | |||
"right": rightPadding, | |||
"bottom": bottomPadding, | |||
"left": leftPadding | |||
} | |||
} | |||
}, | |||
immediate: true | |||
} | |||
}, | |||
// inject: ['list'], | |||
data() { | |||
return { | |||
isFirstChild: false, | |||
padding: { | |||
top: "", | |||
right: "", | |||
bottom: "", | |||
left: "" | |||
} | |||
}; | |||
}, | |||
mounted() { | |||
this.list = this.getForm() | |||
// 判断是否存在 uni-list 组件 | |||
if (this.list) { | |||
if (!this.list.firstChildAppend) { | |||
this.list.firstChildAppend = true; | |||
this.isFirstChild = true; | |||
} | |||
} | |||
}, | |||
methods: { | |||
/** | |||
* 获取父元素实例 | |||
*/ | |||
getForm(name = 'uniList') { | |||
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; | |||
}, | |||
onClick() { | |||
if (this.to !== '') { | |||
this.openPage(); | |||
return; | |||
} | |||
if (this.clickable || this.link) { | |||
this.$emit('click', { | |||
data: {} | |||
}); | |||
} | |||
}, | |||
onSwitchChange(e) { | |||
this.$emit('switchChange', e.detail); | |||
}, | |||
openPage() { | |||
if (['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'].indexOf(this.link) !== -1) { | |||
this.pageApi(this.link); | |||
} else { | |||
this.pageApi('navigateTo'); | |||
} | |||
}, | |||
pageApi(api) { | |||
let callback = { | |||
url: this.to, | |||
success: res => { | |||
this.$emit('click', { | |||
data: res | |||
}); | |||
}, | |||
fail: err => { | |||
this.$emit('click', { | |||
data: err | |||
}); | |||
} | |||
} | |||
switch (api) { | |||
case 'navigateTo': | |||
uni.navigateTo(callback) | |||
break | |||
case 'redirectTo': | |||
uni.redirectTo(callback) | |||
break | |||
case 'reLaunch': | |||
uni.reLaunch(callback) | |||
break | |||
case 'switchTab': | |||
uni.switchTab(callback) | |||
break | |||
default: | |||
uni.navigateTo(callback) | |||
} | |||
} | |||
} | |||
}; | |||
</script> | |||
<style lang="scss"> | |||
$uni-font-size-sm:12px; | |||
$uni-font-size-base:14px; | |||
$uni-font-size-lg:16px; | |||
$uni-spacing-col-lg: 12px; | |||
$uni-spacing-row-lg: 15px; | |||
$uni-img-size-sm:20px; | |||
$uni-img-size-base:26px; | |||
$uni-img-size-lg:40px; | |||
$uni-border-color:#e5e5e5; | |||
$uni-bg-color-hover:#f1f1f1; | |||
$uni-text-color-grey:#999; | |||
$list-item-pd: $uni-spacing-col-lg $uni-spacing-row-lg; | |||
.uni-list-item { | |||
/* #ifndef APP-NVUE */ | |||
display: flex; | |||
/* #endif */ | |||
font-size: $uni-font-size-lg; | |||
position: relative; | |||
justify-content: space-between; | |||
align-items: center; | |||
background-color: #fff; | |||
flex-direction: row; | |||
/* #ifdef H5 */ | |||
cursor: pointer; | |||
/* #endif */ | |||
} | |||
.uni-list-item--disabled { | |||
opacity: 0.3; | |||
} | |||
.uni-list-item--hover { | |||
background-color: $uni-bg-color-hover !important; | |||
} | |||
.uni-list-item__container { | |||
position: relative; | |||
/* #ifndef APP-NVUE */ | |||
display: flex; | |||
/* #endif */ | |||
flex-direction: row; | |||
padding: $list-item-pd; | |||
padding-left: $uni-spacing-row-lg; | |||
flex: 1; | |||
overflow: hidden; | |||
// align-items: center; | |||
} | |||
.container--right { | |||
padding-right: 0; | |||
} | |||
// .border--left { | |||
// margin-left: $uni-spacing-row-lg; | |||
// } | |||
.uni-list--border { | |||
position: absolute; | |||
top: 0; | |||
right: 0; | |||
left: 0; | |||
/* #ifdef APP-NVUE */ | |||
border-top-color: $uni-border-color; | |||
border-top-style: solid; | |||
border-top-width: 0.5px; | |||
/* #endif */ | |||
} | |||
/* #ifndef APP-NVUE */ | |||
.uni-list--border:after { | |||
position: absolute; | |||
top: 0; | |||
right: 0; | |||
left: 0; | |||
height: 1px; | |||
content: ''; | |||
-webkit-transform: scaleY(0.5); | |||
transform: scaleY(0.5); | |||
background-color: $uni-border-color; | |||
} | |||
/* #endif */ | |||
.uni-list-item__content { | |||
/* #ifndef APP-NVUE */ | |||
display: flex; | |||
/* #endif */ | |||
padding-right: 8px; | |||
flex: 1; | |||
color: #3b4144; | |||
// overflow: hidden; | |||
flex-direction: column; | |||
justify-content: space-between; | |||
overflow: hidden; | |||
} | |||
.uni-list-item__content--center { | |||
justify-content: center; | |||
} | |||
.uni-list-item__content-title { | |||
font-size: $uni-font-size-base; | |||
color: #3b4144; | |||
overflow: hidden; | |||
} | |||
.uni-list-item__content-note { | |||
margin-top: 6rpx; | |||
color: $uni-text-color-grey; | |||
font-size: $uni-font-size-sm; | |||
overflow: hidden; | |||
} | |||
.uni-list-item__extra { | |||
// width: 25%; | |||
/* #ifndef APP-NVUE */ | |||
display: flex; | |||
/* #endif */ | |||
flex-direction: row; | |||
justify-content: flex-end; | |||
align-items: center; | |||
} | |||
.uni-list-item__header { | |||
/* #ifndef APP-NVUE */ | |||
display: flex; | |||
/* #endif */ | |||
flex-direction: row; | |||
align-items: center; | |||
} | |||
.uni-list-item__icon { | |||
margin-right: 18rpx; | |||
flex-direction: row; | |||
justify-content: center; | |||
align-items: center; | |||
} | |||
.uni-list-item__icon-img { | |||
/* #ifndef APP-NVUE */ | |||
display: block; | |||
/* #endif */ | |||
height: $uni-img-size-base; | |||
width: $uni-img-size-base; | |||
margin-right: 10px; | |||
} | |||
.uni-icon-wrapper { | |||
/* #ifndef APP-NVUE */ | |||
display: flex; | |||
/* #endif */ | |||
align-items: center; | |||
padding: 0 10px; | |||
} | |||
.flex--direction { | |||
flex-direction: column; | |||
/* #ifndef APP-NVUE */ | |||
align-items: initial; | |||
/* #endif */ | |||
} | |||
.flex--justify { | |||
/* #ifndef APP-NVUE */ | |||
justify-content: initial; | |||
/* #endif */ | |||
} | |||
.uni-list--lg { | |||
height: $uni-img-size-lg; | |||
width: $uni-img-size-lg; | |||
} | |||
.uni-list--base { | |||
height: $uni-img-size-base; | |||
width: $uni-img-size-base; | |||
} | |||
.uni-list--sm { | |||
height: $uni-img-size-sm; | |||
width: $uni-img-size-sm; | |||
} | |||
.uni-list-item__extra-text { | |||
color: $uni-text-color-grey; | |||
font-size: $uni-font-size-sm; | |||
} | |||
.uni-ellipsis-1 { | |||
/* #ifndef APP-NVUE */ | |||
overflow: hidden; | |||
white-space: nowrap; | |||
text-overflow: ellipsis; | |||
/* #endif */ | |||
/* #ifdef APP-NVUE */ | |||
lines: 1; | |||
text-overflow: ellipsis; | |||
/* #endif */ | |||
} | |||
.uni-ellipsis-2 { | |||
/* #ifndef APP-NVUE */ | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
display: -webkit-box; | |||
-webkit-line-clamp: 2; | |||
-webkit-box-orient: vertical; | |||
/* #endif */ | |||
/* #ifdef APP-NVUE */ | |||
lines: 2; | |||
text-overflow: ellipsis; | |||
/* #endif */ | |||
} | |||
</style> |
@ -0,0 +1,123 @@ | |||
<template> | |||
<!-- #ifndef APP-NVUE --> | |||
<view class="uni-list uni-border-top-bottom"> | |||
<view v-if="border" class="uni-list--border-top"></view> | |||
<slot /> | |||
<view v-if="border" class="uni-list--border-bottom"></view> | |||
</view> | |||
<!-- #endif --> | |||
<!-- #ifdef APP-NVUE --> | |||
<list :bounce="false" :scrollable="true" show-scrollbar :render-reverse="renderReverse" @scroll="scroll" class="uni-list" :class="{ 'uni-list--border': border }" :enableBackToTop="enableBackToTop" | |||
loadmoreoffset="15"> | |||
<slot /> | |||
</list> | |||
<!-- #endif --> | |||
</template> | |||
<script> | |||
/** | |||
* List 列表 | |||
* @description 列表组件 | |||
* @tutorial https://ext.dcloud.net.cn/plugin?id=24 | |||
* @property {String} border = [true|false] 标题 | |||
*/ | |||
export default { | |||
name: 'uniList', | |||
'mp-weixin': { | |||
options: { | |||
multipleSlots: false | |||
} | |||
}, | |||
props: { | |||
stackFromEnd:{ | |||
type: Boolean, | |||
default:false | |||
}, | |||
enableBackToTop: { | |||
type: [Boolean, String], | |||
default: false | |||
}, | |||
scrollY: { | |||
type: [Boolean, String], | |||
default: false | |||
}, | |||
border: { | |||
type: Boolean, | |||
default: true | |||
}, | |||
renderReverse:{ | |||
type: Boolean, | |||
default: false | |||
} | |||
}, | |||
// provide() { | |||
// return { | |||
// list: this | |||
// }; | |||
// }, | |||
created() { | |||
this.firstChildAppend = false; | |||
}, | |||
methods: { | |||
loadMore(e) { | |||
this.$emit('scrolltolower'); | |||
}, | |||
scroll(e) { | |||
this.$emit('scroll', e); | |||
} | |||
} | |||
}; | |||
</script> | |||
<style lang="scss"> | |||
$uni-bg-color:#ffffff; | |||
$uni-border-color:#e5e5e5; | |||
.uni-list { | |||
/* #ifndef APP-NVUE */ | |||
display: flex; | |||
/* #endif */ | |||
background-color: $uni-bg-color; | |||
position: relative; | |||
flex-direction: column; | |||
} | |||
.uni-list--border { | |||
position: relative; | |||
/* #ifdef APP-NVUE */ | |||
border-top-color: $uni-border-color; | |||
border-top-style: solid; | |||
border-top-width: 0.5px; | |||
border-bottom-color: $uni-border-color; | |||
border-bottom-style: solid; | |||
border-bottom-width: 0.5px; | |||
/* #endif */ | |||
z-index: -1; | |||
} | |||
/* #ifndef APP-NVUE */ | |||
.uni-list--border-top { | |||
position: absolute; | |||
top: 0; | |||
right: 0; | |||
left: 0; | |||
height: 1px; | |||
-webkit-transform: scaleY(0.5); | |||
transform: scaleY(0.5); | |||
background-color: $uni-border-color; | |||
z-index: 1; | |||
} | |||
.uni-list--border-bottom { | |||
position: absolute; | |||
bottom: 0; | |||
right: 0; | |||
left: 0; | |||
height: 1px; | |||
-webkit-transform: scaleY(0.5); | |||
transform: scaleY(0.5); | |||
background-color: $uni-border-color; | |||
} | |||
/* #endif */ | |||
</style> |
@ -0,0 +1,65 @@ | |||
<template> | |||
<!-- #ifdef APP-NVUE --> | |||
<refresh :display="display" @refresh="onrefresh" @pullingdown="onpullingdown"> | |||
<slot /> | |||
</refresh> | |||
<!-- #endif --> | |||
<!-- #ifndef APP-NVUE --> | |||
<view ref="uni-refresh" class="uni-refresh" v-show="isShow"> | |||
<slot /> | |||
</view> | |||
<!-- #endif --> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'UniRefresh', | |||
props: { | |||
display: { | |||
type: [String], | |||
default: "hide" | |||
} | |||
}, | |||
data() { | |||
return { | |||
pulling: false | |||
} | |||
}, | |||
computed: { | |||
isShow() { | |||
if (this.display === "show" || this.pulling === true) { | |||
return true; | |||
} | |||
return false; | |||
} | |||
}, | |||
created() {}, | |||
methods: { | |||
onchange(value) { | |||
this.pulling = value; | |||
}, | |||
onrefresh(e) { | |||
this.$emit("refresh", e); | |||
}, | |||
onpullingdown(e) { | |||
// #ifdef APP-NVUE | |||
this.$emit("pullingdown", e); | |||
// #endif | |||
// #ifndef APP-NVUE | |||
var detail = { | |||
viewHeight: 90, | |||
pullingDistance: e.height | |||
} | |||
this.$emit("pullingdown", detail); | |||
// #endif | |||
} | |||
} | |||
} | |||
</script> | |||
<style> | |||
.uni-refresh { | |||
height: 0; | |||
overflow: hidden; | |||
} | |||
</style> |
@ -0,0 +1,87 @@ | |||
var pullDown = { | |||
threshold: 95, | |||
maxHeight: 200, | |||
callRefresh: 'onrefresh', | |||
callPullingDown: 'onpullingdown', | |||
refreshSelector: '.uni-refresh' | |||
}; | |||
function ready(newValue, oldValue, ownerInstance, instance) { | |||
var state = instance.getState() | |||
state.canPullDown = newValue; | |||
// console.log(newValue); | |||
} | |||
function touchStart(e, instance) { | |||
var state = instance.getState(); | |||
state.refreshInstance = instance.selectComponent(pullDown.refreshSelector); | |||
state.canPullDown = (state.refreshInstance != null && state.refreshInstance != undefined); | |||
if (!state.canPullDown) { | |||
return | |||
} | |||
// console.log("touchStart"); | |||
state.height = 0; | |||
state.touchStartY = e.touches[0].pageY || e.changedTouches[0].pageY; | |||
state.refreshInstance.setStyle({ | |||
'height': 0 | |||
}); | |||
state.refreshInstance.callMethod("onchange", true); | |||
} | |||
function touchMove(e, ownerInstance) { | |||
var instance = e.instance; | |||
var state = instance.getState(); | |||
if (!state.canPullDown) { | |||
return | |||
} | |||
var oldHeight = state.height; | |||
var endY = e.touches[0].pageY || e.changedTouches[0].pageY; | |||
var height = endY - state.touchStartY; | |||
if (height > pullDown.maxHeight) { | |||
return; | |||
} | |||
var refreshInstance = state.refreshInstance; | |||
refreshInstance.setStyle({ | |||
'height': height + 'px' | |||
}); | |||
height = height < pullDown.maxHeight ? height : pullDown.maxHeight; | |||
state.height = height; | |||
refreshInstance.callMethod(pullDown.callPullingDown, { | |||
height: height | |||
}); | |||
} | |||
function touchEnd(e, ownerInstance) { | |||
var state = e.instance.getState(); | |||
if (!state.canPullDown) { | |||
return | |||
} | |||
state.refreshInstance.callMethod("onchange", false); | |||
var refreshInstance = state.refreshInstance; | |||
if (state.height > pullDown.threshold) { | |||
refreshInstance.callMethod(pullDown.callRefresh); | |||
return; | |||
} | |||
refreshInstance.setStyle({ | |||
'height': 0 | |||
}); | |||
} | |||
function propObserver(newValue, oldValue, instance) { | |||
pullDown = newValue; | |||
} | |||
module.exports = { | |||
touchmove: touchMove, | |||
touchstart: touchStart, | |||
touchend: touchEnd, | |||
propObserver: propObserver | |||
} |
@ -0,0 +1,88 @@ | |||
{ | |||
"id": "uni-list", | |||
"displayName": "uni-list 列表", | |||
"version": "1.2.14", | |||
"description": "List 组件 ,帮助使用者快速构建列表。", | |||
"keywords": [ | |||
"", | |||
"uni-ui", | |||
"uniui", | |||
"列表", | |||
"", | |||
"list" | |||
], | |||
"repository": "https://github.com/dcloudio/uni-ui", | |||
"engines": { | |||
"HBuilderX": "" | |||
}, | |||
"directories": { | |||
"example": "../../temps/example_temps" | |||
}, | |||
"dcloudext": { | |||
"sale": { | |||
"regular": { | |||
"price": "0.00" | |||
}, | |||
"sourcecode": { | |||
"price": "0.00" | |||
} | |||
}, | |||
"contact": { | |||
"qq": "" | |||
}, | |||
"declaration": { | |||
"ads": "无", | |||
"data": "无", | |||
"permissions": "无" | |||
}, | |||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", | |||
"type": "component-vue" | |||
}, | |||
"uni_modules": { | |||
"dependencies": [ | |||
"uni-badge", | |||
"uni-icons" | |||
], | |||
"encrypt": [], | |||
"platforms": { | |||
"cloud": { | |||
"tcb": "y", | |||
"aliyun": "y" | |||
}, | |||
"client": { | |||
"App": { | |||
"app-vue": "y", | |||
"app-nvue": "y" | |||
}, | |||
"H5-mobile": { | |||
"Safari": "y", | |||
"Android Browser": "y", | |||
"微信浏览器(Android)": "y", | |||
"QQ浏览器(Android)": "y" | |||
}, | |||
"H5-pc": { | |||
"Chrome": "y", | |||
"IE": "y", | |||
"Edge": "y", | |||
"Firefox": "y", | |||
"Safari": "y" | |||
}, | |||
"小程序": { | |||
"微信": "y", | |||
"阿里": "y", | |||
"百度": "y", | |||
"字节跳动": "y", | |||
"QQ": "y" | |||
}, | |||
"快应用": { | |||
"华为": "u", | |||
"联盟": "u" | |||
}, | |||
"Vue": { | |||
"vue2": "y", | |||
"vue3": "y" | |||
} | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,346 @@ | |||
## List 列表 | |||
> **组件名:uni-list** | |||
> 代码块: `uList`、`uListItem` | |||
> 关联组件:`uni-list-item`、`uni-badge`、`uni-icons`、`uni-list-chat`、`uni-list-ad` | |||
List 列表组件,包含基本列表样式、可扩展插槽机制、长列表性能优化、多端兼容。 | |||
在vue页面里,它默认使用页面级滚动。在app-nvue页面里,它默认使用原生list组件滚动。这样的长列表,在滚动出屏幕外后,系统会回收不可见区域的渲染内存资源,不会造成滚动越长手机越卡的问题。 | |||
uni-list组件是父容器,里面的核心是uni-list-item子组件,它代表列表中的一个可重复行,子组件可以无限循环。 | |||
uni-list-item有很多风格,uni-list-item组件通过内置的属性,满足一些常用的场景。当内置属性不满足需求时,可以通过扩展插槽来自定义列表内容。 | |||
内置属性可以覆盖的场景包括:导航列表、设置列表、小图标列表、通信录列表、聊天记录列表。 | |||
涉及很多大图或丰富内容的列表,比如类今日头条的新闻列表、类淘宝的电商列表,需要通过扩展插槽实现。 | |||
下文均有样例给出。 | |||
uni-list不包含下拉刷新和上拉翻页。上拉翻页另见组件:[uni-load-more](https://ext.dcloud.net.cn/plugin?id=29) | |||
### 安装方式 | |||
本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。 | |||
如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55) | |||
> **注意事项** | |||
> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。 | |||
> - 组件需要依赖 `sass` 插件 ,请自行手动安装 | |||
> - 组件内部依赖 `'uni-icons'` 、`uni-badge` 组件 | |||
> - `uni-list` 和 `uni-list-item` 需要配套使用,暂不支持单独使用 `uni-list-item` | |||
> - 只有开启点击反馈后,会有点击选中效果 | |||
> - 使用插槽时,可以完全自定义内容 | |||
> - note 、rightText 属性暂时没做限制,不支持文字溢出隐藏,使用时应该控制长度显示或通过默认插槽自行扩展 | |||
> - 支付宝小程序平台需要在支付宝小程序开发者工具里开启 component2 编译模式,开启方式: 详情 --> 项目配置 --> 启用 component2 编译 | |||
> - 如果需要修改 `switch`、`badge` 样式,请使用插槽自定义 | |||
> - 在 `HBuilderX` 低版本中,可能会出现组件显示 `undefined` 的问题,请升级最新的 `HBuilderX` 或者 `cli` | |||
> - 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 | |||
### 基本用法 | |||
- 设置 `title` 属性,可以显示列表标题 | |||
- 设置 `disabled` 属性,可以禁用当前项 | |||
```html | |||
<uni-list> | |||
<uni-list-item title="列表文字" ></uni-list-item> | |||
<uni-list-item :disabled="true" title="列表禁用状态" ></uni-list-item> | |||
</uni-list> | |||
``` | |||
### 多行内容显示 | |||
- 设置 `note` 属性 ,可以在第二行显示描述文本信息 | |||
```html | |||
<uni-list> | |||
<uni-list-item title="列表文字" note="列表描述信息"></uni-list-item> | |||
<uni-list-item :disabled="true" title="列表文字" note="列表禁用状态"></uni-list-item> | |||
</uni-list> | |||
``` | |||
### 右侧显示角标、switch | |||
- 设置 `show-badge` 属性 ,可以显示角标内容 | |||
- 设置 `show-switch` 属性,可以显示 switch 开关 | |||
```html | |||
<uni-list> | |||
<uni-list-item title="列表右侧显示角标" :show-badge="true" badge-text="12" ></uni-list-item> | |||
<uni-list-item title="列表右侧显示 switch" :show-switch="true" @switchChange="switchChange" ></uni-list-item> | |||
</uni-list> | |||
``` | |||
### 左侧显示略缩图、图标 | |||
- 设置 `thumb` 属性 ,可以在列表左侧显示略缩图 | |||
- 设置 `show-extra-icon` 属性,并指定 `extra-icon` 可以在左侧显示图标 | |||
```html | |||
<uni-list> | |||
<uni-list-item title="列表左侧带略缩图" note="列表描述信息" thumb="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" | |||
thumb-size="lg" rightText="右侧文字"></uni-list-item> | |||
<uni-list-item :show-extra-icon="true" :extra-icon="extraIcon1" title="列表左侧带扩展图标" ></uni-list-item> | |||
</uni-list> | |||
``` | |||
### 开启点击反馈和右侧箭头 | |||
- 设置 `clickable` 为 `true` ,则表示这是一个可点击的列表,会默认给一个点击效果,并可以监听 `click` 事件 | |||
- 设置 `link` 属性,会自动开启点击反馈,并给列表右侧添加一个箭头 | |||
- 设置 `to` 属性,可以跳转页面,`link` 的值表示跳转方式,如果不指定,默认为 `navigateTo` | |||
```html | |||
<uni-list> | |||
<uni-list-item title="开启点击反馈" clickable @click="onClick" ></uni-list-item> | |||
<uni-list-item title="默认 navigateTo 方式跳转页面" link to="/pages/vue/index/index" @click="onClick($event,1)" ></uni-list-item> | |||
<uni-list-item title="reLaunch 方式跳转页面" link="reLaunch" to="/pages/vue/index/index" @click="onClick($event,1)" ></uni-list-item> | |||
</uni-list> | |||
``` | |||
### 聊天列表示例 | |||
- 设置 `clickable` 为 `true` ,则表示这是一个可点击的列表,会默认给一个点击效果,并可以监听 `click` 事件 | |||
- 设置 `link` 属性,会自动开启点击反馈,`link` 的值表示跳转方式,如果不指定,默认为 `navigateTo` | |||
- 设置 `to` 属性,可以跳转页面 | |||
- `time` 属性,通常会设置成时间显示,但是这个属性不仅仅可以设置时间,你可以传入任何文本,注意文本长度可能会影响显示 | |||
- `avatar` 和 `avatarList` 属性同时只会有一个生效,同时设置的话,`avatarList` 属性的长度大于1 ,`avatar` 属性将失效 | |||
- 可以通过默认插槽自定义列表右侧内容 | |||
```html | |||
<uni-list> | |||
<uni-list :border="true"> | |||
<!-- 显示圆形头像 --> | |||
<uni-list-chat :avatar-circle="true" title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" ></uni-list-chat> | |||
<!-- 右侧带角标 --> | |||
<uni-list-chat title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-text="12" :badge-style="{backgroundColor:'#FF80AB'}"></uni-list-chat> | |||
<!-- 头像显示圆点 --> | |||
<uni-list-chat title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot"></uni-list-chat> | |||
<!-- 头像显示角标 --> | |||
<uni-list-chat title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="99"></uni-list-chat> | |||
<!-- 显示多头像 --> | |||
<uni-list-chat title="uni-app" :avatar-list="avatarList" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot"></uni-list-chat> | |||
<!-- 自定义右侧内容 --> | |||
<uni-list-chat title="uni-app" :avatar-list="avatarList" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot"> | |||
<view class="chat-custom-right"> | |||
<text class="chat-custom-text">刚刚</text> | |||
<!-- 需要使用 uni-icons 请自行引入 --> | |||
<uni-icons type="star-filled" color="#999" size="18"></uni-icons> | |||
</view> | |||
</uni-list-chat> | |||
</uni-list> | |||
</uni-list> | |||
``` | |||
```javascript | |||
export default { | |||
components: {}, | |||
data() { | |||
return { | |||
avatarList: [{ | |||
url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png' | |||
}, { | |||
url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png' | |||
}, { | |||
url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png' | |||
}] | |||
} | |||
} | |||
} | |||
``` | |||
```css | |||
.chat-custom-right { | |||
flex: 1; | |||
/* #ifndef APP-NVUE */ | |||
display: flex; | |||
/* #endif */ | |||
flex-direction: column; | |||
justify-content: space-between; | |||
align-items: flex-end; | |||
} | |||
.chat-custom-text { | |||
font-size: 12px; | |||
color: #999; | |||
} | |||
``` | |||
## API | |||
### List Props | |||
属性名 |类型 |默认值 | 说明 | |||
:-: |:-: |:-: | :-: | |||
border |Boolean |true | 是否显示边框 | |||
### ListItem Props | |||
属性名 |类型 |默认值 | 说明 | |||
:-: |:-: |:-: | :-: | |||
title |String |- | 标题 | |||
note |String |- | 描述 | |||
ellipsis |Number |0 | title 是否溢出隐藏,可选值,0:默认; 1:显示一行; 2:显示两行;【nvue 暂不支持】 | |||
thumb |String |- | 左侧缩略图,若thumb有值,则不会显示扩展图标 | |||
thumbSize |String |medium | 略缩图尺寸,可选值,lg:大图; medium:一般; sm:小图; | |||
showBadge |Boolean |false | 是否显示数字角标 | |||
badgeText |String |- | 数字角标内容 | |||
badgeType |String |- | 数字角标类型,参考[uni-icons](https://ext.dcloud.net.cn/plugin?id=21) | |||
badgeStyle |Object |- | 数字角标样式,使用uni-badge的custom-style参数 | |||
rightText |String |- | 右侧文字内容 | |||
disabled |Boolean |false | 是否禁用 | |||
showArrow |Boolean |true | 是否显示箭头图标 | |||
link |String |navigateTo | 新页面跳转方式,可选值见下表 | |||
to |String |- | 新页面跳转地址,如填写此属性,click 会返回页面是否跳转成功 | |||
clickable |Boolean |false | 是否开启点击反馈 | |||
showSwitch |Boolean |false | 是否显示Switch | |||
switchChecked |Boolean |false | Switch是否被选中 | |||
showExtraIcon |Boolean |false | 左侧是否显示扩展图标 | |||
extraIcon |Object |- | 扩展图标参数,格式为 ``{color: '#4cd964',size: '22',type: 'spinner'}``,参考 [uni-icons](https://ext.dcloud.net.cn/plugin?id=28) | |||
direction | String |row | 排版方向,可选值,row:水平排列; column:垂直排列; 3个插槽是水平排还是垂直排,也受此属性控制 | |||
#### Link Options | |||
属性名 | 说明 | |||
:-: | :-: | |||
navigateTo | 同 uni.navigateTo() | |||
redirectTo | 同 uni.reLaunch() | |||
reLaunch | 同 uni.reLaunch() | |||
switchTab | 同 uni.switchTab() | |||
### ListItem Events | |||
事件称名 |说明 |返回参数 | |||
:-: |:-: |:-: | |||
click |点击 uniListItem 触发事件,需开启点击反馈 |- | |||
switchChange |点击切换 Switch 时触发,需显示 switch |e={value:checked} | |||
### ListItem Slots | |||
名称 | 说明 | |||
:-: | :-: | |||
header | 左/上内容插槽,可完全自定义默认显示 | |||
body | 中间内容插槽,可完全自定义中间内容 | |||
footer | 右/下内容插槽,可完全自定义右侧内容 | |||
> **通过插槽扩展** | |||
> 需要注意的是当使用插槽时,内置样式将会失效,只保留排版样式,此时的样式需要开发者自己实现 | |||
> 如果 `uni-list-item` 组件内置属性样式无法满足需求,可以使用插槽来自定义uni-list-item里的内容。 | |||
> uni-list-item提供了3个可扩展的插槽:`header`、`body`、`footer` | |||
> - 当 `direction` 属性为 `row` 时表示水平排列,此时 `header` 表示列表的左边部分,`body` 表示列表的中间部分,`footer` 表示列表的右边部分 | |||
> - 当 `direction` 属性为 `column` 时表示垂直排列,此时 `header` 表示列表的上边部分,`body` 表示列表的中间部分,`footer` 表示列表的下边部分 | |||
> 开发者可以只用1个插槽,也可以3个一起使用。在插槽中可自主编写view标签,实现自己所需的效果。 | |||
**示例** | |||
```html | |||
<uni-list> | |||
<uni-list-item title="自定义右侧插槽" note="列表描述信息" link> | |||
<template slot="header"> | |||
<image class="slot-image" src="/static/logo.png" mode="widthFix"></image> | |||
</template> | |||
</uni-list-item> | |||
<uni-list-item> | |||
<!-- 自定义 header --> | |||
<view slot="header" class="slot-box"><image class="slot-image" src="/static/logo.png" mode="widthFix"></image></view> | |||
<!-- 自定义 body --> | |||
<text slot="body" class="slot-box slot-text">自定义插槽</text> | |||
<!-- 自定义 footer--> | |||
<template slot="footer"> | |||
<image class="slot-image" src="/static/logo.png" mode="widthFix"></image> | |||
</template> | |||
</uni-list-item> | |||
</uni-list> | |||
``` | |||
### ListItemChat Props | |||
属性名 |类型 |默认值 | 说明 | |||
:-: |:-: |:-: | :-: | |||
title |String |- | 标题 | |||
note |String |- | 描述 | |||
clickable |Boolean |false | 是否开启点击反馈 | |||
badgeText |String |- | 数字角标内容,设置为 `dot` 将显示圆点 | |||
badgePositon |String |right | 角标位置 | |||
link |String |navigateTo | 是否展示右侧箭头并开启点击反馈,可选值见下表 | |||
clickable |Boolean |false | 是否开启点击反馈 | |||
to |String |- | 跳转页面地址,如填写此属性,click 会返回页面是否跳转成功 | |||
time |String |- | 右侧时间显示 | |||
avatarCircle |Boolean |false | 是否显示圆形头像 | |||
avatar |String |- | 头像地址,avatarCircle 不填时生效 | |||
avatarList |Array |- | 头像组,格式为 [{url:''}] | |||
#### Link Options | |||
属性名 | 说明 | |||
:-: | :-: | |||
navigateTo | 同 uni.navigateTo() | |||
redirectTo | 同 uni.reLaunch() | |||
reLaunch | 同 uni.reLaunch() | |||
switchTab | 同 uni.switchTab() | |||
### ListItemChat Slots | |||
名称 | 说明 | |||
:- | :- | |||
default | 自定义列表右侧内容(包括时间和角标显示) | |||
### ListItemChat Events | |||
事件称名 | 说明 | 返回参数 | |||
:-: | :-: | :-: | |||
@click | 点击 uniListChat 触发事件 | {data:{}} ,如有 to 属性,会返回页面跳转信息 | |||
## 基于uni-list扩展的页面模板 | |||
通过扩展插槽,可实现多种常见样式的列表 | |||
**新闻列表类** | |||
1. 云端一体混合布局:[https://ext.dcloud.net.cn/plugin?id=2546](https://ext.dcloud.net.cn/plugin?id=2546) | |||
2. 云端一体垂直布局,大图模式:[https://ext.dcloud.net.cn/plugin?id=2583](https://ext.dcloud.net.cn/plugin?id=2583) | |||
3. 云端一体垂直布局,多行图文混排:[https://ext.dcloud.net.cn/plugin?id=2584](https://ext.dcloud.net.cn/plugin?id=2584) | |||
4. 云端一体垂直布局,多图模式:[https://ext.dcloud.net.cn/plugin?id=2585](https://ext.dcloud.net.cn/plugin?id=2585) | |||
5. 云端一体水平布局,左图右文:[https://ext.dcloud.net.cn/plugin?id=2586](https://ext.dcloud.net.cn/plugin?id=2586) | |||
6. 云端一体水平布局,左文右图:[https://ext.dcloud.net.cn/plugin?id=2587](https://ext.dcloud.net.cn/plugin?id=2587) | |||
7. 云端一体垂直布局,无图模式,主标题+副标题:[https://ext.dcloud.net.cn/plugin?id=2588](https://ext.dcloud.net.cn/plugin?id=2588) | |||
**商品列表类** | |||
1. 云端一体列表/宫格视图互切:[https://ext.dcloud.net.cn/plugin?id=2651](https://ext.dcloud.net.cn/plugin?id=2651) | |||
2. 云端一体列表(宫格模式):[https://ext.dcloud.net.cn/plugin?id=2671](https://ext.dcloud.net.cn/plugin?id=2671) | |||
3. 云端一体列表(列表模式):[https://ext.dcloud.net.cn/plugin?id=2672](https://ext.dcloud.net.cn/plugin?id=2672) | |||
## 组件示例 | |||
点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/list/list](https://hellouniapp.dcloud.net.cn/pages/extUI/list/list) |