This commit is contained in:
2024-05-17 18:02:49 +08:00
parent 8407d51fb6
commit b5264dc222
4056 changed files with 308094 additions and 41932 deletions

View File

@@ -0,0 +1,5 @@
## 1.0.12024-04-19
1.优化代码结构;
2.修复某些情况不能选择的bug
## 1.0.02024-04-05
First Blood

View File

@@ -0,0 +1,412 @@
<template>
<uni-popup ref="popup" type="bottom" @change="popChange">
<view class="sx-address-picker">
<view class="sx-address-picker__close">
<uni-icons
class="absolute"
size="20"
color="#ccc"
type="closeempty"
@click="$refs.popup.close"
></uni-icons>
</view>
<view class="sx-address-picker__title"> 请选择所在地区 </view>
<!-- 已选择区域 -->
<uni-list v-for="item in activeItems" :key="item.code" :border="false">
<uni-list-item show-arrow clickable @click="selectLevel(item)">
<template v-slot:header>
<view :class="activeLevel === item.level - 1 ? 'primary-text' : ''"
>{{ item.name || selectTitle }}
</view>
</template>
</uni-list-item>
</uni-list>
<view class="sx-address-picker--divider"></view>
<view class="sx-address-picker__list">
<template v-if="activeLevel === -1">
<!-- 中国/海外切换 -->
<!-- <radio-group class="sx-address-picker__list-tab" @change="typeChange">
<label
v-for="(item, index) in worlds"
:key="item"
:class="
world == index ? 'sx-address-picker__list-tab--active' : ''
"
>
<radio
class="sx-address-picker__list-tab--hide"
:checked="world === item"
:value="index + ''"
/><text>{{ item }}</text>
</label>
</radio-group> -->
<!-- 后续计划TODO 常用城市 -->
<!-- <view class="font-5 font-weight-500 mb-4">
{{quickTitle}}
</view>
<radio-group class="flex flex-wrap" @change="quickIndex = $event.detail.value">
<label class="mr-3" v-for="(item,index) in quickList" :key="item"
:class="world == index? 'active':''">
<radio class="none" :checked="world === item" :value="index + ''" />
<view class="radius bg-445 px-4 py-1 mb-3">{{item}}</view>
</label>
</radio-group> -->
</template>
<view class="sx-address-picker__list-title">
{{ selectTitle }}
</view>
<view class="sx-address-picker__list-content" @click="reGetList">
<uni-load-more
v-if="loadingStatus !== 'more'"
:status="loadingStatus"
:content-text="{ contentnomore: '加载失败请点击重试' }"
></uni-load-more>
<!-- 省市区选择 -->
<uni-list v-if="world == 0" :border="false">
<uni-list-item
v-for="(item, index) in currentList"
:key="item.code"
:title="item.name"
:border="false"
clickable
@click="selectHandle(item, index)"
>
<template v-slot:footer>
<uni-icons
v-if="
activeItems[item.level]
? activeItems[item.level].code === item.code
: false
"
type="checkmarkempty"
class="sx-address-picker__list-tab--active"
></uni-icons>
</template>
</uni-list-item>
</uni-list>
<!-- 国家地区列表选择 -->
<uni-list v-else :border="false">
<uni-list-item
v-for="(item, index) in country.filter((v, i) => v.value !== 0)"
:key="item.id"
:title="item.name"
:border="false"
clickable
@click="selectHandle(item, index, true)"
>
<template v-slot:footer>
<uni-icons
v-if="countryName == item.name"
type="checkmarkempty"
class="sx-address-picker__list-tab--active"
></uni-icons>
</template>
</uni-list-item>
</uni-list>
</view>
</view>
</view>
</uni-popup>
</template>
<script>
const cityDataUrl =
"https://static-mp-97eb3f65-f610-4509-81e4-a6cd5df3859b.next.bspapp.com/cos/data.json";
const countryDataUrl =
"https://static-mp-97eb3f65-f610-4509-81e4-a6cd5df3859b.next.bspapp.com/cos/country.json";
// 后续计划TODO 常用城市、国家
// const quickCitys = ['上海市', '北京市', '苏州市', '杭州市', '广州市', '深圳市', '南京市', '天津市']
// const quickCountys = ['中国香港', '中国澳门', '中国台湾', '新加坡']
export default {
props: {
value: Boolean,
selected: {
type: Array,
default() {
return [];
},
},
},
data() {
return {
// "港澳台地区及海外"
world: "0",
loading: true,
loadingStatus: "loading",
countryName: "",
country: [],
worlds: ["中国内地(大陆)", ],
quickIndex: "0",
list: [],
activeLevel: -1,
activeIndex: -1,
level0: "",
activeItems: [],
childList: [],
};
},
methods: {
clear() {
console.log(1111111111111111)
this.activeItems = [];
this.countryName = "";
this.level0 = "";
this.$forceUpdate()
},
// 弹窗是否显示状态事件
popChange(e) {
this.$emit("input", e.show);
},
// 已选择项切换事件
selectLevel(item) {
if (item.code && this.world === "0") {
this.activeLevel = item.level - 1;
}
},
typeChange(e) {
const value = e.detail.value;
this.world = value;
this.getList();
},
// 选择省市区/国家事件 isOhter区分选择省市区
selectHandle(item, index, isOhter = false) {
if (isOhter) {
// 选择国家
this.activeLevel = -1;
this.activeIndex = 0;
this.countryName = item.name;
this.activeItems = [item];
this.$refs.popup.close();
this.$emit("confirm", this.activeItems);
} else {
// 选择省市区
this.activeLevel = item.level;
this.activeIndex = index;
this.$set(this.activeItems, item.level, item);
this.activeItems.splice(item.level + 1);
if (item.children) {
this.$set(this.activeItems, item.level + 1, {});
} else {
this.$refs.popup.close();
this.$emit("confirm", [
{
code: "CN",
level: -1,
name: "中国",
},
...this.activeItems,
]);
}
}
},
// 获取中国省市区数据
getCityData() {
if (!this.list.length) {
this.loadingStatus = "loading";
// 循环给省市区增加level级别字段
const eachList = function (arr, level) {
arr.forEach((v) => {
v.level = level;
if (v.children) {
eachList(v.children, v.level + 1);
}
});
};
uni.request({
url: cityDataUrl,
success: (res) => {
const list = res.data;
if (Array.isArray(list)) {
eachList(list, 0);
this.list = list;
if (this.selected.length) {
const activeItems = [];
if (this.selected.length !== 1) {
activeItems[0] = this.list.find(
(v) => v.name === this.selected[1]
);
activeItems[1] = activeItems[0].children.find(
(v) => v.name === this.selected[2]
);
activeItems[2] = activeItems[1].children.find(
(v) => v.name === this.selected[3]
);
activeItems[3] = activeItems[2].children.find(
(v) => v.name === this.selected[4]
);
this.activeItems = activeItems;
this.activeLevel = 2;
} else {
this.activeLevel = -1;
}
}
this.loadingStatus = "more";
} else {
this.loadingStatus = "noMore";
}
},
fail: () => {
this.loadingStatus = "noMore";
},
});
} else {
this.loadingStatus = "more";
}
},
// 获取国家数据
getCountryData() {
if (this.world == 1 && !this.country.length) {
this.loadingStatus = "loading";
uni.request({
url: countryDataUrl,
success: (res) => {
const data = res.data;
if (data.others) {
const list = data.others.reduce((arr, v) => {
arr.push(...v.items);
return arr;
}, []);
this.country = list;
this.loadingStatus = "more";
} else {
this.loadingStatus = "noMore";
}
},
fail: () => {
this.loadingStatus = "noMore";
},
});
} else {
this.loadingStatus = "more";
}
},
reGetList() {
if (this.loadingStatus === "noMore") {
this.getList();
}
},
getList() {
switch (this.world) {
case "0":
this.getCityData();
break;
case "1":
this.getCountryData();
break;
}
},
},
computed: {
// 动态计算当前要选择的列表
currentList() {
if (this.activeLevel !== -1) {
return this.activeItems[this.activeLevel].children;
}
return this.list;
},
// 动态标题显示
selectTitle() {
const titles = {
"-1": "请选择省份/地区",
0: "请选择城市",
1: "请选择区/县",
2: "请选择街道",
};
return titles[this.activeLevel];
},
// TODO 后续更新
// quickTitle() {
// const items = {
// 0: '常用城市',
// 1: '常用国家/地区'
// }
// return items[this.world]
// },
// TODO 后续计划 常用选项
// quickList() {
// return this.world === '0' ? quickCitys : quickCountys
// }
},
watch: {
// 监听value触发弹窗显示状态以及事件处理
async value(val) {
if (val) {
this.$refs.popup.open();
const countyName = this.selected[0];
this.world = this.selected.length === 1 ? "1" : "0";
if (this.activeItems.length === 4) {
this.activeLevel = 2;
}
this.countryName = countyName;
this.getList();
} else {
this.$refs.popup.close();
}
},
},
};
</script>
<style lang="scss" scoped>
.sx-address-picker {
border-top-left-radius: 20px;
border-top-right-radius: 20px;
background-color: white;
padding-left: 8px;
padding-right: 8px;
padding-top: 16px;
font-size: 16px;
&__close {
text-align: right;
margin-right: 16px;
margin-top: 4px;
position: absolute;
left: 0;
right: 0;
}
&__title {
text-align: center;
font-weight: 500;
font-size: 18px;
margin-bottom: 20px;
}
&--divider {
border-top: 0.5px solid #ddd;
}
&__list {
max-height: 400px;
overflow-y: auto;
margin-top: 12px;
&-tab {
display: flex;
margin-bottom: 20px;
justify-content: space-between;
padding-left: 16px;
padding-right: 16px;
&--hide {
display: none;
}
&--active {
color: $uni-color-primary !important;
}
}
&-title {
font-weight: bold;
margin-bottom: 16px;
}
.uni-load-more {
padding: 100px 0;
}
}
}
</style>

View File

@@ -0,0 +1,86 @@
{
"id": "sx-address-picker",
"displayName": "仿淘宝地址选择 地址选择器 address-picker 省市区 海外选择",
"version": "1.0.1",
"description": "该组件高仿淘宝地址省市区区域的picker交互效果效果基本一致。",
"keywords": [
"address-picker",
"省市区",
"地址选择",
"海外"
],
"repository": "https://github.com/yuxianwen/sx-address-picker",
"engines": {
"HBuilderX": "^3.6.11"
},
"dcloudext": {
"type": "component-vue",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "y"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "n"
},
"App": {
"app-vue": "y",
"app-nvue": "n",
"app-uvue": "n"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"钉钉": "y",
"快手": "y",
"飞书": "y",
"京东": "y"
},
"快应用": {
"华为": "y",
"联盟": "y"
}
}
}
}
}

View File

@@ -0,0 +1,45 @@
# sx-address-picker
[中国省省市区 数据来源](https://github.com/modood/Administrative-divisions-of-China)
[国家地区来源](https://h5api.m.taobao.com/h5/mtop.cainiao.address.ua.global.area.list/1.0/?jsv=2.5.1&appKey=12574478&t=1712242102859&sign=0a30509ed7f24a5bf58a953d3d908dc2&api=mtop.cainiao.address.ua.global.area.list&v=1.0&dataType=jsonp&type=jsonp&callback=mtopjsonp2&data=%7B%22sn%22%3A%22suibianchuan%22%7D)
# SxAddressPicker 地址选择器
> **组件名sx-address-picker**
### 介绍
该组件高仿淘宝地址省市区区域的picker交互效果效果基本一致。
### 安装方式
本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`
### 基本用法
更多示例请下载示例安装查看。该组件依赖官方ui组件uni-icons、uni-list、uni-load-more、uni-popup、uni-transition如果项目本身已导入uni-ui请忽略。
两个json文件在示例包static文件下自己引入或自建cdn
```html
<sx-address-picker v-model="addressPopup" @confirm="addressConfirm"/>
```
## API
### Props
| 属性名 | 类型 | 默认值 | 说明 |
| --------- | -------------- | ------ | ------------------------------- |
| value | Boolean | false | 控制picker是否显示可使用v-model进行控制。 |
| selected | Array | [] | 可选,默认回显的选项。 |
### Events
| 事件称名 | 说明 | 返回参数 |
| -------- | -------------------- | ------------------------------------------------ |
| confirm | 当点击完成选择时发出 | 用户选择完毕/收起菜单触发confirm事件event=[] |
### 名人语录
每个人都会有缺陷,就像被上帝咬过的苹果,有的人缺陷比较大,正是因为上帝特别喜欢他的芬芳。——**托尔斯泰(俄国)**

View File

@@ -436,7 +436,7 @@
display: flex;
/* #endif */
flex-direction: row;
/* border-bottom: 1px solid #f0f0f0; */
/* border-bottom: 1px solid #f5f5f5; */
}
.title-area {

View File

@@ -290,7 +290,7 @@
.item {
padding: 12px 15px;
/* border-bottom: 1px solid #f0f0f0; */
/* border-bottom: 1px solid #f5f5f5; */
/* #ifndef APP-NVUE */
display: flex;
/* #endif */

View File

@@ -491,7 +491,7 @@
.uni-easyinput__placeholder-class {
color: #999;
font-size: 12px;
font-size: 14px;
// font-weight: 200;
}
@@ -599,7 +599,7 @@
.uni-easyinput__placeholder-class {
color: #D5D5D5;
font-size: 12px;
font-size: 14px;
}
}
</style>

View File

@@ -2,7 +2,7 @@
<view v-if="show" class="uni-noticebar" :style="{ backgroundColor }" @click="onClick">
<uni-icons v-if="showIcon === true || showIcon === 'true'" class="uni-noticebar-icon" type="sound"
:color="color" :size="fontSize * 1.5" />
<view ref="textBox" class="uni-noticebar__content-wrapper"
<view ref="textBox" class="uni-noticebar__content-wrapper"
:class="{
'uni-noticebar__content-wrapper--scrollable': scrollable,
'uni-noticebar__content-wrapper--single': !scrollable && (single || moreText)

View File

@@ -229,7 +229,7 @@
}
.uni-border-left {
border-left-color: #f0f0f0;
border-left-color: #f5f5f5;
border-left-style: solid;
border-left-width: 1px;
}

View File

@@ -78,7 +78,7 @@
padding: 8px 10px;
font-size: 14px;
border-bottom: 1px $border-color solid;
font-weight: 400;
font-weight: 600;
color: #606266;
line-height: 23px;
box-sizing: border-box;

View File

@@ -440,7 +440,7 @@
}
.list-item:hover {
background-color: #f0f0f0;
background-color: #f5f5f5;
}
.check {
@@ -453,7 +453,7 @@
.search-input {
font-size: 12px;
border: 1px solid #f0f0f0;
border: 1px solid #f5f5f5;
border-radius: 3px;
padding: 2px 5px;
min-width: 150px;
@@ -467,7 +467,7 @@
.input {
font-size: 12px;
border: 1px solid #f0f0f0;
border: 1px solid #f5f5f5;
border-radius: 3px;
margin: 10px;
padding: 2px 5px;

View File

@@ -152,7 +152,7 @@
font-size: 16px;
color: #333;
font-weight: bold;
/* font-weight: 400; */
/* font-weight: 600; */
}
.uni-h4 {

View File

@@ -520,7 +520,7 @@
text-align: center;
flex: 1;
font-size: 30rpx;
font-weight: 400;
font-weight: 600;
color: #FFFFFF;
border-radius: 40rpx;
margin: 0 18rpx;

View File

@@ -44,6 +44,7 @@
:class="[effect === 'dark' ? 'u-alert__text--dark' : `u-alert__text--${type}--light`]"
>{{ description }}</text>
</view>
<slot name="rightSlot" ></slot>
<view
class="u-alert__close"
v-if="closable"

View File

@@ -10,6 +10,10 @@ export default {
type: String,
default: uni.$u.props.columnNotice.icon
},
label: {
type: String,
},
// 通告模式link-显示右箭头closable-显示右侧关闭图标
mode: {
type: String,

View File

@@ -32,7 +32,7 @@
<text
class="u-notice__swiper__item__text u-line-1"
:style="[textStyle]"
>{{ item }}</text>
>{{ label?item[label]:item }}</text>
</swiper-item>
</swiper>
<view

View File

@@ -10,6 +10,10 @@ export default {
type: String,
default: uni.$u.props.noticeBar.direction
},
label: {
type: String,
},
// direction = row时是否使用步进形式滚动
step: {
type: Boolean,

View File

@@ -11,6 +11,7 @@
:color="color"
:bgColor="bgColor"
:text="text"
:label="label"
:mode="mode"
:step="step"
:icon="icon"
@@ -26,6 +27,7 @@
:color="color"
:bgColor="bgColor"
:text="text"
:label="label"
:mode="mode"
:fontSize="fontSize"
:speed="speed"

View File

@@ -30,6 +30,8 @@
class="u-tabs__wrapper__nav__item__text"
:style="[textStyle(index)]"
>{{ item[keyName] }}</text>
<slot name="labelSlot" :data="item"></slot>
<u-badge
:show="!!(item.badge && (item.badge.show || item.badge.isDot || item.badge.value))"
:isDot="item.badge && item.badge.isDot || propsBadge.isDot"

File diff suppressed because it is too large Load Diff

View File

@@ -163,7 +163,7 @@ $http.dataFactory = async function(res) {
loginPopupNum--;
if (res.confirm) {
uni.navigateTo({
url: "/pages/user/login"
url: "/pages/user/login/login"
});
}
}