石可 5 years ago
parent
commit
f0e10135b3
  1. 20
      common/styles/sharedIconFont.css
  2. 281
      components/lf-rate/lf-rate.vue
  3. 142
      pages/my/getRedLine - 第一版卡片形式.vue
  4. 155
      pages/my/getRedLine.vue
  5. 3
      pages/my/index.vue
  6. 7
      pages/test/test.vue

20
common/styles/sharedIconFont.css

@ -1,18 +1,26 @@
@font-face {
font-family: "lf-iconfont"; /* Project id 2758976 */
src: url('//at.alicdn.com/t/font_2758976_9bezuvselm.woff2?t=1629452232587') format('woff2'),
url('//at.alicdn.com/t/font_2758976_9bezuvselm.woff?t=1629452232587') format('woff'),
url('//at.alicdn.com/t/font_2758976_9bezuvselm.ttf?t=1629452232587') format('truetype');
font-family: "le"; /* Project id 2758976 */
src: url('//at.alicdn.com/t/font_2758976_blqjbbep8zo.woff2?t=1629876001355') format('woff2'),
url('//at.alicdn.com/t/font_2758976_blqjbbep8zo.woff?t=1629876001355') format('woff'),
url('//at.alicdn.com/t/font_2758976_blqjbbep8zo.ttf?t=1629876001355') format('truetype');
}
.lf-iconfont {
font-family: "lf-iconfont" !important;
.le {
font-family: "le" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.lf-icon-xingxing-kong:before {
content: "\e649";
}
.lf-icon-xingxing-shi:before {
content: "\e651";
}
.lf-icon-shanchu:before {
content: "\e674";
}

281
components/lf-rate/lf-rate.vue

@ -0,0 +1,281 @@
<template>
<view>
<view ref="uni-rate" class="uni-rate">
<view class="uni-rate__icon"
:style="{ 'margin-right': margin + 'px' }"
v-for="(star, index) in stars" :key="index"
@touchstart.stop="touchstart"
@touchmove.stop="touchmove">
<text class="le lf-icon-xingxing-shi" :style="{'color': color, 'font-size': size +'px'}" v-if="isFill"></text>
<text class="le lf-icon-xingxing-kong" :style="{'color': color, 'font-size': size +'px'}" v-else></text>
<!-- #ifdef APP-NVUE -->
<view :style="{ width: star.activeWitch.replace('%','')*size/100+'px'}" class="uni-rate__icon-on" >
<text class="le lf-icon-xingxing-shi" :style="{'text-align': 'left', 'color': disabled?'#ccc':activeColor, 'font-size': size +'px'}"></text>
</view>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<view :style="{ width: star.activeWitch}" class="uni-rate__icon-on">
<text class="le lf-icon-xingxing-shi" :style="{'color': disabled?disabledColor:activeColor, 'font-size': size +'px'}"></text>
</view>
<!-- #endif -->
</view>
<view class="uni-num" :style="{'color': activeColor}" v-if="number && valueSync">{{ valueSync }}</view>
</view>
</view>
</template>
<script>
// #ifdef APP-NVUE
const dom = uni.requireNativePlugin('dom');
// #endif
/**
* Rate 评分
* @description 评分组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=33
* @property {Boolean} isFill = [true|false] 星星的类型是否为实心类型, 默认为实心
* @property {String} color 未选中状态的星星颜色默认为 "#ececec"
* @property {String} activeColor 选中状态的星星颜色默认为 "#ffca3e"
* @property {String} disabledColor 禁用状态的星星颜色默认为 "#c0c0c0"
* @property {Number} size 星星的大小
* @property {Number} value/v-model 当前评分
* @property {Number} max 最大评分评分数量目前一分一颗星
* @property {Number} margin 星星的间距单位 px
* @property {Boolean} disabled = [true|false] 是否为禁用状态默认为 false
* @property {Boolean} readonly = [true|false] 是否为只读状态默认为 false
* @property {Boolean} allowHalf = [true|false] 是否实现半星默认为 false
* @property {Boolean} touchable = [true|false] 是否支持滑动手势默认为 true
* @event {Function} change uniRate value 改变时触发事件e={value:Number}
*/
export default {
name: "UniRate",
props: {
isFill: {
//
type: [Boolean, String],
default: true
},
color: {
//
type: String,
default: "#ececec"
},
activeColor: {
//
type: String,
default: "#ffca3e"
},
disabledColor: {
//
type: String,
default: "#c0c0c0"
},
size: {
//
type: [Number, String],
default: 24
},
value: {
//
type: [Number, String],
default: 1
},
max: {
//
type: [Number, String],
default: 5
},
margin: {
//
type: [Number, String],
default: 0
},
disabled: {
//
type: [Boolean, String],
default: false
},
readonly: {
//
type: [Boolean, String],
default: false
},
allowHalf: {
//
type: [Boolean, String],
default: false
},
touchable: {
//
type: [Boolean, String],
default: true
},
number: {
// value
type: Boolean,
default: false
}
},
data() {
return {
valueSync: ""
};
},
watch: {
value(newVal) {
this.valueSync = Number(newVal);
}
},
computed: {
stars() {
const value = this.valueSync ? this.valueSync : 0;
const starList = [];
const floorValue = Math.floor(value);
const ceilValue = Math.ceil(value);
for (let i = 0; i < this.max; i++) {
if (floorValue > i) {
starList.push({
activeWitch: "100%"
});
} else if (ceilValue - 1 === i) {
starList.push({
activeWitch: (value - floorValue) * 100 + "%"
});
} else {
starList.push({
activeWitch: "0"
});
}
}
return starList;
}
},
created() {
this.valueSync = Number(this.value);
this._rateBoxLeft = 0
this._oldValue = null
},
mounted() {
setTimeout(() => {
this._getSize()
}, 100)
},
methods: {
touchstart(e) {
if (this.readonly || this.disabled) return
const {
clientX,
screenX
} = e.changedTouches[0]
// TODO Nvue screenX clientX
this._getRateCount(clientX || screenX)
},
touchmove(e) {
if (this.readonly || this.disabled || !this.touchable) return
const {
clientX,
screenX
} = e.changedTouches[0]
this._getRateCount(clientX || screenX)
},
/**
* 获取星星个数
*/
_getRateCount(clientX) {
const size = Number(this.size)
if(size === NaN){
return new Error('size 属性只能设置为数字')
}
const rateMoveRange = clientX - this._rateBoxLeft
let index = parseInt(rateMoveRange / (size + this.margin))
index = index < 0 ? 0 : index;
index = index > this.max ? this.max : index;
const range = parseInt(rateMoveRange - (size + this.margin) * index);
let value = 0;
if (this._oldValue === index) return;
this._oldValue = index;
if (this.allowHalf) {
if (range > (size / 2)) {
value = index + 1
} else {
value = index + 0.5
}
} else {
value = index + 1
}
value = Math.max(0.5, Math.min(value, this.max))
this.valueSync = value
this._onChange()
},
/**
* 触发动态修改
*/
_onChange() {
this.$emit("input", this.valueSync);
this.$emit("change", {
value: this.valueSync
});
},
/**
* 获取星星距离屏幕左侧距离
*/
_getSize() {
// #ifndef APP-NVUE
uni.createSelectorQuery()
.in(this)
.select('.uni-rate')
.boundingClientRect()
.exec(ret => {
if (ret) {
this._rateBoxLeft = ret[0].left
}
})
// #endif
// #ifdef APP-NVUE
dom.getComponentRect(this.$refs['uni-rate'], (ret) => {
const size = ret.size
if (size) {
this._rateBoxLeft = size.left
}
})
// #endif
}
}
};
</script>
<style lang="scss" scoped>
.uni-rate {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
line-height: 1;
font-size: 0;
flex-direction: row;
}
.uni-rate__icon {
position: relative;
line-height: 1;
font-size: 0;
}
.uni-rate__icon-on {
overflow: hidden;
position: absolute;
top: 0;
left: 0;
line-height: 1;
text-align: left;
}
.uni-num{
font-size: 28rpx;
margin-left: 10rpx;
display: flex;
align-items: center;
}
</style>

142
pages/my/getRedLine - 第一版卡片形式.vue

@ -0,0 +1,142 @@
<template>
<view class="content">
<view class="card" v-for="item in 4" :key="item">
<view class="cover">
<lf-image src="https://picsum.photos/200"></lf-image>
<view class="tips">有效3天</view>
</view>
<view class="info">
<view>
<text class="title" v-if="item == 0">套餐一实用</text>
<!-- <text class="title">套餐一实用</text> -->
<text class="title" v-else>套餐一实实用实用实用实用实用实用用</text>
<text class="label">6.5</text>
</view>
<view class="lf-m-t-12 lf-font-24">
<text class="lf-color-777">红线数</text>
<text>1</text>
</view>
<view class="lf-m-t-16">
<lf-price :price="30.12" color="#E21196"></lf-price>
<text class="original-price">¥30.00</text>
</view>
<view class="float-btn" hover-class="lf-opacity">
<button></button>
</view>
</view>
</view>
</view>
</template>
<script>
import lfPrice from '@/components/lf-price/lf-price.vue'
export default {
components: { lfPrice },
data(){
return {
}
},
onLoad(){
//
},
methods: {
}
}
</script>
<style lang="scss" scoped="scoped">
.content{
width: 750rpx;
height: max-content;
padding: 30rpx 32rpx;
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
.card{
width: 333rpx;
height: max-content;
background-color: #FFFFFF;
box-shadow: 0rpx -2rpx 20rpx 2rpx rgba(0, 0, 0, 0.07);
border-radius: 10rpx;
overflow: hidden;
margin-right: 20rpx;
&:nth-child(2n){
margin-right: 0;
}
&:nth-child(n+3){
margin-top: 20rpx;
}
.cover{
width: 100%;
height: 260rpx;
position: relative;
.tips{
position: absolute;
left: 0;
top: 0;
width: 111rpx;
height: 33rpx;
background: linear-gradient(180deg, #FE3EA5 0%, #FE7350 100%);
border-radius: 10rpx 0rpx 5rpx 0rpx;
color: #FFFFFF;
font-size: 24rpx;
display: flex;
justify-content: center;
align-items: center;
}
}
.info{
padding: 15rpx;
box-sizing: border-box;
position: relative;
.title{
font-size: 28rpx;
font-weight: bold;
color: #222222;
margin-right: 15rpx;
}
.label{
display: inline-block;
width: 84rpx;
height: 33rpx;
border-radius: 3rpx;
border: 2rpx solid #E21196;
font-size: 24rpx;
color: #E21196;
text-align: center;
line-height: 29rpx;
}
.original-price{
margin-left: 15rpx;
color: #777777;
font-size: 24rpx;
text-decoration: line-through;
}
.float-btn{
position: absolute;
width: 45rpx;
height: 45rpx;
padding: 15rpx;
right: 0;
bottom: 10rpx;
box-sizing: content-box;
button{
width: 100%;
height: 100%;
border-radius: 50%;
background: #E21196;
margin: 0;
padding: 0;
font-size: 24rpx;
color: #FFFFFF;
display: flex;
justify-content: center;
align-items: center;
}
}
}
}
}
</style>

155
pages/my/getRedLine.vue

@ -1,28 +1,24 @@
<template>
<view class="content">
<view class="card" v-for="item in 4" :key="item">
<view class="cover">
<lf-image src="https://picsum.photos/200"></lf-image>
<view class="tips">有效3天</view>
<view class="card" :class="'bg-color'+ (item+1)" v-for="item in 3" :key="item">
<view>
<text class="title">套餐一实实用用</text>
<text class="label">6.5</text>
</view>
<view class="info">
<view class="lf-m-t-12 lf-font-24 lf-row-between">
<view class="lf-color-777">红线数</view>
<view class="lf-color-222">1</view>
</view>
<view class="lf-m-t-12 lf-font-24 lf-row-between">
<view class="lf-color-777">有效时间</view>
<view class="lf-color-222">3</view>
</view>
<view class="lf-m-t-16 lf-row-between">
<view>
<text class="title" v-if="item == 0">套餐一实用</text>
<!-- <text class="title">套餐一实用</text> -->
<text class="title" v-else>套餐一实实用实用实用实用实用实用用</text>
<text class="label">6.5</text>
</view>
<view class="lf-m-t-12 lf-font-24">
<text class="lf-color-777">红线数</text>
<text>1</text>
</view>
<view class="lf-m-t-16">
<lf-price :price="30.12" color="#E21196"></lf-price>
<text class="original-price">¥30.00</text>
</view>
<view class="float-btn" hover-class="lf-opacity">
<button></button>
</view>
<view class="btn" hover-class="lf-opacity">立即购买</view>
</view>
</view>
</view>
@ -52,91 +48,60 @@
height: max-content;
padding: 30rpx 32rpx;
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
.card{
width: 333rpx;
width: 686rpx;
height: max-content;
background-color: #FFFFFF;
box-shadow: 0rpx -2rpx 20rpx 2rpx rgba(0, 0, 0, 0.07);
box-shadow: 0rpx 2rpx 4rpx 2rpx rgba(0, 0, 0, 0.07);
border-radius: 10rpx;
overflow: hidden;
margin-right: 20rpx;
&:nth-child(2n){
margin-right: 0;
padding: 30rpx;
box-sizing: border-box;
&:nth-child(n+2){
margin-top: 30rpx;
}
&:nth-child(n+3){
margin-top: 20rpx;
.title{
font-size: 28rpx;
font-weight: bold;
color: #222222;
margin-right: 15rpx;
}
.cover{
width: 100%;
height: 260rpx;
position: relative;
.tips{
position: absolute;
left: 0;
top: 0;
width: 111rpx;
height: 33rpx;
background: linear-gradient(180deg, #FE3EA5 0%, #FE7350 100%);
border-radius: 10rpx 0rpx 5rpx 0rpx;
color: #FFFFFF;
font-size: 24rpx;
display: flex;
justify-content: center;
align-items: center;
}
.label{
display: inline-block;
width: 84rpx;
height: 33rpx;
border-radius: 3rpx;
border: 2rpx solid #E21196;
font-size: 24rpx;
color: #E21196;
text-align: center;
line-height: 29rpx;
}
.info{
padding: 15rpx;
box-sizing: border-box;
position: relative;
.title{
font-size: 28rpx;
font-weight: bold;
color: #222222;
margin-right: 15rpx;
}
.label{
display: inline-block;
width: 84rpx;
height: 33rpx;
border-radius: 3rpx;
border: 2rpx solid #E21196;
font-size: 24rpx;
color: #E21196;
text-align: center;
line-height: 29rpx;
}
.original-price{
margin-left: 15rpx;
color: #777777;
font-size: 24rpx;
text-decoration: line-through;
}
.float-btn{
position: absolute;
width: 45rpx;
height: 45rpx;
padding: 15rpx;
right: 0;
bottom: 10rpx;
box-sizing: content-box;
button{
width: 100%;
height: 100%;
border-radius: 50%;
background: #E21196;
margin: 0;
padding: 0;
font-size: 24rpx;
color: #FFFFFF;
display: flex;
justify-content: center;
align-items: center;
}
}
.original-price{
margin-left: 15rpx;
color: #777777;
font-size: 24rpx;
text-decoration: line-through;
}
.btn{
width: 130rpx;
height: 43rpx;
background: linear-gradient(180deg, #FE3EA5 0%, #FE7350 100%);
border-radius: 22rpx;
font-size: 24rpx;
color: #FFFFFF;
display: flex;
justify-content: center;
align-items: center;
}
}
.bg-color1{
background-color: #FFF7FC;
}
.bg-color2{
background-color: #FFF4F2;
}
.bg-color3{
background-color: #F2FAFF;
}
}
</style>

3
pages/my/index.vue

@ -104,9 +104,10 @@
showCancel: false,
cancelText: '我知道了',
confirmColor: '#E21196',
success: function (res) {
success: res => {
if (res.confirm) {
console.log('用户点击确定');
this.$url('/pages/my/getRedLine');
}
}
});

7
pages/test/test.vue

@ -33,6 +33,10 @@
<lf-time-picker v-model="timeShow">
<view @click="timeShow = true">点击此处打开时间选择组件</view>
</lf-time-picker>
<view style="height: 100rpx;">
<text class="le lf-icon-xingxing-kong"></text>
</view>
<lf-rate allowHalf="true" :isFill="false"></lf-rate>
</view>
</template>
@ -44,9 +48,10 @@
<script>
import lfUploadImage from "@/components/lf-uploadImage/lf-uploadImage.vue"
import lfTimePicker from '@/components/lf-timePicker/lf-timePicker.vue'
import lfRate from '@/components/lf-rate/lf-rate.vue'
import drag from './drag.vue';
export default {
components: { lfUploadImage, drag, lfTimePicker },
components: { lfUploadImage, drag, lfTimePicker, lfRate },
data(){
return {
timeShow: false

Loading…
Cancel
Save