This commit is contained in:
魏啾
2024-04-30 18:07:59 +08:00
parent b72c4d7af1
commit 56863dd624
1369 changed files with 156460 additions and 0 deletions

153
components/navseat.vue Normal file
View File

@@ -0,0 +1,153 @@
<template>
<view class="content">
<!-- 导航栏 -->
<view class="navbar" :class="{active:opacity}">
<!-- #ifndef APP-PLUS || MP-WEIXIN -->
<view class="status-bar"></view>
<view class="navbar_tow flex-between"
:style="{'height':HeighT.customBar+'px','padding-right':HeighT.custwidth + 'px'}">
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view class="navbar_tow flex-between" :style="{'marginTop':HeighT.heightBar /2+'px'}">
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="navbar_tow flex-between"
:style="{'height':HeighT.customBar+'px','marginTop':HeighT.heightBar+'px','padding-right':HeighT.custwidth + 'px'}">
<!-- #endif -->
<!-- 标题搜索框 -->
<view class="flex-between" @click="clicknavigateBack">
<view class="navbar_tow_one flex-start">
<u-icon name="arrow-left" color="#000" size="24"></u-icon>
</view>
<view class="navbar_tow_tow" v-if="opacity || titleshow">
{{title}}
</view>
</view>
</view>
</view>
<view class="" :style="{'height':HeighT.customBar+'px'}">
</view>
</view>
</template>
<script>
export default {
data() {
return {};
},
props: {
title: {
type: String,
default: ''
},
opacity: {
type: Boolean,
default: false
},
titleshow: {
type: Boolean,
default: false
},
},
computed: {
HeighT() { //手机类型的尺寸
return this.$store.getters.is_BarHeight
},
},
methods: {
clicknavigateBack(){
uni.navigateBack()
}
}
};
</script>
<style scoped lang="scss">
page {
background: #F9F9F9;
}
.content {
position: -webkit-sticky;
position: sticky;
top: 0;
z-index: 999999;
background: #2f87fd;
.active {
background: rgba(249, 249, 249, 1);
}
.status-bar {
// #ifdef APP-PLUS
height: calc(var(--status-bar-height) / 2);
// #endif
// #ifdef MP-WEIXIN
height: var(--status-bar-height);
// #endif
}
// #ifdef APP-PLUS
.statusbarmargin {
margin-top: var(--status-bar-height);
}
// #endif
.navbar {
position: fixed;
top: 0;
width: 100%;
z-index: 99;
.navbar_tow {
width: 100%;
position: relative;
font-size: 36rpx;
.flex-between {
// #ifdef APP-PLUS || H5
margin: 28rpx;
// #endif
// #ifdef MP-WEIXIN
margin-left: 28rpx;
// #endif
width: 100%;
flex-wrap: nowrap;
height: 100%;
line-height: 100%;
.navbar_tow_one {
height: 100%;
line-height: 100%;
text:nth-child(1) {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: bold;
font-size: 28rpx;
color: #333333;
}
text:nth-child(2) {
margin-left: 16rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 28rpx;
color: #333333;
}
}
.navbar_tow_tow {
text-align: center;
flex: auto;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 28rpx;
color: #333333;
}
}
}
}
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,143 @@
/* eslint-disable */
var provinceData = [{
"label": "北京市",
"value": "11"
},
{
"label": "天津市",
"value": "12"
},
{
"label": "河北省",
"value": "13"
},
{
"label": "山西省",
"value": "14"
},
{
"label": "内蒙古自治区",
"value": "15"
},
{
"label": "辽宁省",
"value": "21"
},
{
"label": "吉林省",
"value": "22"
},
{
"label": "黑龙江省",
"value": "23"
},
{
"label": "上海市",
"value": "31"
},
{
"label": "江苏省",
"value": "32"
},
{
"label": "浙江省",
"value": "33"
},
{
"label": "安徽省",
"value": "34"
},
{
"label": "福建省",
"value": "35"
},
{
"label": "江西省",
"value": "36"
},
{
"label": "山东省",
"value": "37"
},
{
"label": "河南省",
"value": "41"
},
{
"label": "湖北省",
"value": "42"
},
{
"label": "湖南省",
"value": "43"
},
{
"label": "广东省",
"value": "44"
},
{
"label": "广西壮族自治区",
"value": "45"
},
{
"label": "海南省",
"value": "46"
},
{
"label": "重庆市",
"value": "50"
},
{
"label": "四川省",
"value": "51"
},
{
"label": "贵州省",
"value": "52"
},
{
"label": "云南省",
"value": "53"
},
{
"label": "西藏自治区",
"value": "54"
},
{
"label": "陕西省",
"value": "61"
},
{
"label": "甘肃省",
"value": "62"
},
{
"label": "青海省",
"value": "63"
},
{
"label": "宁夏回族自治区",
"value": "64"
},
{
"label": "新疆维吾尔自治区",
"value": "65"
},
{
"label": "台湾",
"value": "66"
},
{
"label": "香港",
"value": "67"
},
{
"label": "澳门",
"value": "68"
},
{
"label": "钓鱼岛",
"value": "69"
}
]
export default provinceData;

View File

@@ -0,0 +1,420 @@
<template>
<view class="simple-address" v-if="showPopup" @touchmove.stop.prevent="clear">
<!-- 遮罩层 -->
<view
class="simple-address-mask"
@touchmove.stop.prevent="clear"
v-if="maskClick"
:class="[ani + '-mask', animation ? 'mask-ani' : '']"
:style="{
'background-color': maskBgColor
}"
@tap="hideMask(true)"
></view>
<view class="simple-address-content simple-address--fixed" :class="[type, ani + '-content', animation ? 'content-ani' : '']">
<view class="simple-address__header">
<view class="simple-address__header-btn-box" @click="pickerCancel">
<text class="simple-address__header-text" :style="{ color: cancelColor, fontSize: btnFontSize }">取消</text>
</view>
<view class="simple-address__header-btn-box" @click="pickerConfirm">
<text class="simple-address__header-text" :style="{ color: confirmColor || themeColor, fontSize: btnFontSize }">确定</text>
</view>
</view>
<view class="simple-address__box">
<picker-view indicator-style="height: 70rpx;" class="simple-address-view" :value="pickerValue" @change="pickerChange">
<picker-view-column>
<!-- #ifndef APP-NVUE -->
<view class="picker-item" :style="{ fontSize: fontSize }" v-for="(item, index) in provinceDataList" :key="index">{{ item.label }}</view>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<text class="picker-item" :style="{ fontSize: fontSize }" v-for="(item, index) in provinceDataList" :key="index">{{ item.label }}</text>
<!-- #endif -->
</picker-view-column>
<picker-view-column>
<!-- #ifndef APP-NVUE -->
<view class="picker-item" :style="{ fontSize: fontSize }" v-for="(item, index) in cityDataList" :key="index">{{ item.label }}</view>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<text class="picker-item" :style="{ fontSize: fontSize }" v-for="(item, index) in cityDataList" :key="index">{{ item.label }}</text>
<!-- #endif -->
</picker-view-column>
<picker-view-column>
<!-- #ifndef APP-NVUE -->
<view class="picker-item" :style="{ fontSize: fontSize }" v-for="(item, index) in areaDataList" :key="index">{{ item.label }}</view>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<text class="picker-item" :style="{ fontSize: fontSize }" v-for="(item, index) in areaDataList" :key="index">{{ item.label }}</text>
<!-- #endif -->
</picker-view-column>
</picker-view>
</view>
</view>
</view>
</template>
<script>
/**
* Simple-addres 地址联动组件
* @description 三级地址联动支持appnvue、小程序、H5
* @tutorial https://ext.dcloud.net.cn/plugin?id=1084
* @property {String} animation 是否开启动画
* @property {String} type = [bottom] 弹出层类型,暂时只支持底部弹出
* @property {Boolean} maskClick = [true | false] 是否允许点击遮罩层关闭
* @property {Boolean} show = [true | false] 显示或隐藏地址组件
* @property {String} maskBgColor 遮罩层背景颜色
* @property {String} cancelColor 取消按钮颜色,默认为:#1aad19
* @property {String} confirmColor 确认按钮颜色默认为themeColor
* @property {String} themeColor 主题颜色,后续会废弃该配置,建议使用`cancelColor`或`confirmColor`
* @property {String} btnFontSize 取消、确认按钮字体大小,默认为`uni.scss里的 $uni-font-size-base `
* @property {String} fontSize picker-item字体大小默认为28rpx
* @property {Array} pickerValueDefault 默认值可以通过function queryIndex 获取
* @property {Function} queryIndex 根据自定义信息返回对应的index
* @property {Function} open 打开
* @example <simple-address ref="simpleAddress" :pickerValueDefault="cityPickerValueDefault" @onConfirm="onConfirm" themeColor='#007AFF'></simple-address>
*/
import provinceData from './city-data/province.js';
import cityData from './city-data/city.js';
import areaData from './city-data/area.js';
export default {
name: 'simpleAddress',
props: {
mode: {
// 地址类型
// default 则代表老版本根据index索引获取数据
//
type: String,
default: 'default'
},
// 开启动画
animation: {
type: Boolean,
default: true
},
/* 弹出层类型,可选值;
bottom底部弹出层
*/
type: {
type: String,
default: 'bottom'
},
// maskClick
maskClick: {
type: Boolean,
default: true
},
show: {
type: Boolean,
default: true
},
maskBgColor: {
type: String,
default: 'rgba(0, 0, 0, 0.4)' //背景颜色 rgba(0, 0, 0, 0.4) 为空则调用 uni.scss
},
themeColor: {
type: String,
default: '' // 确认按钮颜色(向下兼容)
},
cancelColor: {
type: String,
default: '' // 取消按钮颜色
},
confirmColor: {
type: String,
default: '' // 确认按钮颜色
},
fontSize: {
type: String,
default: '28rpx' // picker-item字体大小
},
btnFontSize: {
type: String,
default: '' // 按钮的字体大小
},
/* 默认值 */
pickerValueDefault: {
type: Array,
default() {
return [0, 0, 0];
}
}
},
data() {
return {
ani: '',
showPopup: false,
pickerValue: [0, 0, 0],
provinceDataList: [],
cityDataList: [],
areaDataList: []
};
},
watch: {
show(newValue) {
if (newValue) {
this.open();
} else {
this.close();
}
},
pickerValueDefault() {
this.init();
}
},
created() {
this.init();
},
methods: {
init() {
this.handPickValueDefault(); // 对 pickerValueDefault 做兼容处理
this.provinceDataList = provinceData;
this.cityDataList = cityData[this.pickerValueDefault[0]];
this.areaDataList = areaData[this.pickerValueDefault[0]][this.pickerValueDefault[1]];
this.pickerValue = this.pickerValueDefault;
},
handPickValueDefault() {
if (this.pickerValueDefault !== [0, 0, 0]) {
if (this.pickerValueDefault[0] > provinceData.length - 1) {
this.pickerValueDefault[0] = provinceData.length - 1;
}
if (this.pickerValueDefault[1] > cityData[this.pickerValueDefault[0]].length - 1) {
this.pickerValueDefault[1] = cityData[this.pickerValueDefault[0]].length - 1;
}
if (this.pickerValueDefault[2] > areaData[this.pickerValueDefault[0]][this.pickerValueDefault[1]].length - 1) {
this.pickerValueDefault[2] = areaData[this.pickerValueDefault[0]][this.pickerValueDefault[1]].length - 1;
}
}
},
pickerChange(e) {
let changePickerValue = e.detail.value;
if (this.pickerValue[0] !== changePickerValue[0]) {
// 第一级发生滚动
this.cityDataList = cityData[changePickerValue[0]];
this.areaDataList = areaData[changePickerValue[0]][0];
changePickerValue[1] = 0;
changePickerValue[2] = 0;
} else if (this.pickerValue[1] !== changePickerValue[1]) {
// 第二级滚动
this.areaDataList = areaData[changePickerValue[0]][changePickerValue[1]];
changePickerValue[2] = 0;
}
this.pickerValue = changePickerValue;
this._$emit('onChange');
},
_$emit(emitName) {
let pickObj = {
label: this._getLabel(),
value: this.pickerValue,
cityCode: this._getCityCode(),
areaCode: this._getAreaCode(),
provinceCode: this._getProvinceCode(),
labelArr: this._getLabel().split('-')
};
this.$emit(emitName, pickObj);
},
_getLabel() {
let pcikerLabel =
this.provinceDataList[this.pickerValue[0]].label + '-' + this.cityDataList[this.pickerValue[1]].label + '-' + this.areaDataList[this.pickerValue[2]].label;
return pcikerLabel;
},
_getCityCode() {
return this.cityDataList[this.pickerValue[1]].value;
},
_getProvinceCode() {
return this.provinceDataList[this.pickerValue[0]].value;
},
_getAreaCode() {
return this.areaDataList[this.pickerValue[2]].value;
},
queryIndex(params = [], type = 'value') {
// params = [ 11 ,1101,110101 ];
// 1.获取省份的index
let provinceIndex = provinceData.findIndex(res => res[type] == params[0]);
let cityIndex = cityData[provinceIndex].findIndex(res => res[type] == params[1]);
let areaIndex = areaData[provinceIndex][cityIndex].findIndex(res => res[type] == params[2]);
return {
index: [provinceIndex, cityIndex, areaIndex],
data: {
province: provinceData[provinceIndex],
city: cityData[provinceIndex][cityIndex],
area: areaData[provinceIndex][cityIndex][areaIndex]
}
};
},
clear() {},
hideMask() {
this._$emit('onCancel');
this.close();
},
pickerCancel() {
this._$emit('onCancel');
this.close();
},
pickerConfirm() {
this._$emit('onConfirm');
this.close();
},
open() {
this.showPopup = true;
this.$nextTick(() => {
setTimeout(() => {
this.ani = 'simple-' + this.type;
}, 100);
});
},
close(type) {
if (!this.maskClick && type) return;
this.ani = '';
this.$nextTick(() => {
setTimeout(() => {
this.showPopup = false;
}, 300);
});
}
}
};
</script>
<style lang="scss" scoped>
.simple-address {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
}
.simple-address-mask {
position: fixed;
bottom: 0;
top: 0;
left: 0;
right: 0;
transition-property: opacity;
transition-duration: 0.3s;
opacity: 0;
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.mask-ani {
transition-property: opacity;
transition-duration: 0.2s;
}
.simple-bottom-mask {
opacity: 1;
}
.simple-center-mask {
opacity: 1;
}
.simple-address--fixed {
position: fixed;
bottom: 0;
left: 0;
right: 0;
transition-property: transform;
transition-duration: 0.3s;
transform: translateY(460rpx);
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.simple-address-content {
background-color: #ffffff;
}
.simple-content-bottom {
bottom: 0;
left: 0;
right: 0;
transform: translateY(500rpx);
}
.content-ani {
transition-property: transform, opacity;
transition-duration: 0.2s;
}
.simple-bottom-content {
transform: translateY(0);
}
.simple-center-content {
transform: scale(1);
opacity: 1;
}
.simple-address__header {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
border-bottom-color: #f2f2f2;
border-bottom-style: solid;
border-bottom-width: 1rpx;
}
.simple-address--fixed-top {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: space-between;
border-top-color: $uni-border-color;
border-top-style: solid;
border-top-width: 1rpx;
}
.simple-address__header-btn-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
height: 70rpx;
}
.simple-address__header-text {
text-align: center;
font-size: $uni-font-size-base;
color: #1aad19;
line-height: 70rpx;
padding-left: 40rpx;
padding-right: 40rpx;
}
.simple-address__box {
position: relative;
}
.simple-address-view {
position: relative;
bottom: 0;
left: 0;
/* #ifndef APP-NVUE */
width: 100%;
/* #endif */
/* #ifdef APP-NVUE */
width: 750rpx;
/* #endif */
height: 408rpx;
background-color: rgba(255, 255, 255, 1);
}
.picker-item {
text-align: center;
line-height: 70rpx;
text-overflow: ellipsis;
font-size: 28rpx;
}
</style>

View File

@@ -0,0 +1,291 @@
<template>
<view class="wrapper" v-show="isShowMask">
<transition name="content">
<view class="content_view" v-show="isShow">
<view class="title_view">
<view class="title">请选择所在地区</view>
<view class="close_view" @click="hidden">
<text style="font-size:32rpx;">x</text>
</view>
</view>
<view class="select_top">
<view class="select_top_item" ref="select_top_item" v-for="(item,index) in dataList" :key="index" @click="select_top_item_click(index)">
<text class="address_value">{{item}}</text>
</view>
<view class="indicator" :style="{ left: indicatorStyleLeft + 'px' }" ref="indicator"></view>
</view>
<swiper class="swiper" :current="currentIndex" @change="swiperChange">
<swiper-item v-for="(swiper_item,swiper_index) in dataList" :key="swiper_index">
<view class="swiper-item">
<scroll-view class="scroll-view-item" scroll-y="true">
<view class="address_item" v-for="(item,index) in cityAreaArray[swiper_index]" :key="index" @click="address_item_click(swiper_index,index)">
<image v-if="selectIndexArr[swiper_index] === index" class="address_item_icon" src="@/static/yixuan-selectAddress/gou.png" mode=""></image>
{{item.name}}
</view>
</scroll-view>
</view>
</swiper-item>
</swiper>
</view>
</transition>
<view class="mask" @click="hidden" v-show="isShowMask"></view>
</view>
</template>
<script>
import cityData from '@/static/yixuan-selectAddress/city.json'
export default {
data() {
return {
isShow: false,
isShowMask: false,
dataList: ['请选择'],
currentIndex: 0,
cityData: {},
cityAreaArray: [],
selectIndexArr: [],
indicatorStyleLeft: 16
};
},
methods:{
show(){
this.isShow = true
this.isShowMask = true
},
hidden() {
this.isShow = false
setTimeout(() => {
this.isShowMask = false
}, 500);
},
select_top_item_click(index) {
console.log('select_top_item_click')
this.currentIndex = index
this.$nextTick(() => {
this.changeIndicator(index)
})
},
swiperChange(event){
let index = event.detail.current
this.currentIndex = index
this.changeIndicator(index)
},
changeIndicator(index){
/*
let itemWidth = this.$refs.select_top_item[index].$children[0].$el.offsetWidth
if (itemWidth > 80){
itemWidth = 80
}
let itemCenterX = 10 + index * 80 + itemWidth / 2
let indicatorWidth = this.$refs.indicator.$el.offsetWidth
this.$refs.indicator.$el.style.left = itemCenterX - indicatorWidth / 2 + 'px'
*/
let indicatorWidth = 30
const query = uni.createSelectorQuery().in(this);
let arr = query.selectAll('.select_top_item .address_value')
arr.fields({
size: true,
scrollOffset: false
}, data => {
let itemWidth = data[index]["width"] > 80 ? 70 : data[index]["width"]
let itemCenterX = 10 + index * 80 + itemWidth / 2
let left = itemCenterX - indicatorWidth / 2
this.indicatorStyleLeft = left
}).exec();
},
address_item_click(swiper_index,index){
// console.log(swiper_index,index)
this.selectIndexArr.splice(swiper_index, 5,index)
//判断当前是否为最下一级
if (swiper_index === 0){//第一级
let currentObj = this.cityData[index]
let city = currentObj.name
this.dataList.splice(swiper_index,5,city)
this.dataList.splice(swiper_index + 1,0,'请选择')
this.cityAreaArray.splice(swiper_index + 1, 1,currentObj["city"])
// console.log(this.dataList)
setTimeout(() => {
this.currentIndex = 1
this.changeIndicator(1)
}, 50);
}else {
let currentAreaArray = this.cityAreaArray[swiper_index]
let currentObj = currentAreaArray[index]
let area = currentObj["area"]
// console.log(currentAreaArray)
if (area !== undefined){
let city = currentObj.name
this.dataList.splice(swiper_index,5,city)
this.dataList.splice(swiper_index + 1,0,'请选择')
this.cityAreaArray.splice(swiper_index + 1,1,currentObj["area"])
setTimeout(() => {
this.currentIndex = swiper_index + 1
this.changeIndicator(swiper_index + 1)
}, 50);
}else{//是最下一级
let city = currentObj.name
this.dataList.splice(swiper_index,1,city)
//选择成功返回数据
this.$emit("selectAddress",this.dataList.join(','))
this.$nextTick(() => {
this.changeIndicator(swiper_index)
})
setTimeout(() => {
this.isShow = false
}, 100);
setTimeout(() => {
this.isShowMask = false
}, 500);
}
}
}
},
created() {
this.cityData = cityData
this.cityAreaArray.push(cityData)
},
mounted() {
// this.changeIndicator(0)
}
}
</script>
<style lang="scss">
// 不换行
@mixin no-wrap(){
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.wrapper{
z-index: 1999;
position: fixed;
top: -44px;
left: 0;
bottom: 0;
right: 0;
.content_view{
z-index: 999;
background: white;
position: absolute;
height: 80%;
left: 0;
bottom: 0;
right: 0;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
.title_view{
height: 12%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 $uni-spacing-row-sm;
.title{
font-size: uni-font-size-sm;
}
.close_view{
height: 60px;
width: 60px;
display: flex;
justify-content: center;
align-items: center;
}
}
.select_top{
height: 8%;
display: flex;
justify-content: start;
align-items: center;
padding: 10px;
position: relative;
box-sizing: border-box;
.select_top_item{
width: 80px;
font-size: 14px;
@include no-wrap();
}
.indicator{
position: absolute;
width: 30px;
height: 2px;
background: $uni-color-error;
left: 16px;
bottom: 0;
transition: left 0.5s ease;
}
}
.swiper{
height: 80%;
position: relative;
left: 0;
top: 0;
bottom: 0;
right: 0;
.swiper-item{
height: 100%;
.scroll-view-item{
height: 100%;
padding: 0 10px;
.address_item{
padding: 5px 0;
font-size: 14px;
display: flex;
align-items: center;
.address_item_icon{
width: 20px;
height: 20px;
margin-right: 10px;
}
}
}
}
}
}
.mask{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: $uni-text-color-grey;
opacity: 0.7;
}
}
.content-enter{
transform: translateY(100%);
}
.content-enter-to{
transform: translateY(0%);
}
.content-enter-active{
transition: transform 0.5s;
}
.content-leave{
transform: translateY(0%);
}
.content-leave-to{
transform: translateY(100%);
}
.content-leave-active{
transition: transform 0.5s;
}
</style>