| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- <template>
- <!-- <view class="form-item"> -->
- <!-- <view class="item-label">
- <text class="label-text">{{ label }}</text>
- <text v-if="required" class="required">*</text>
- </view> -->
- <!-- 编辑模式:输入框 -->
- <uni-data-picker
- v-if="mode === 'edit'"
- v-model="innerValue"
- :localdata="localData"
- :popup-title="popupTitle"
- @change="onChange"
- >
- <u-input
- :value="getLocationLabel(innerValue)"
- :placeholder="placeholder"
- readonly
- suffix-icon="arrow-down"
- >
- <!-- 清除按钮 -->
- <template slot="suffix">
- <view
- v-if="innerValue"
- @click.stop="clearAddress"
- style="padding: 0 8rpx; display: flex; align-items: center;"
- >
- <uni-icons type="close" color="#999" size="20"></uni-icons>
- </view>
- </template>
- </u-input>
- </uni-data-picker>
- <!-- 展示模式:纯文本 -->
- <text v-else class="location-text">
- {{ getLocationLabel(innerValue) || "无" }}
- </text>
- <!-- </view> -->
- </template>
- <script>
- import cityRows from '@/utils/data.json';
- export default {
- name: "LocationPicker",
- props: {
- mode: { // 新增模式属性
- type: String,
- default: "edit" // edit / view
- },
- value: { // v-model
- type: [String, Number],
- default: ""
- },
- label: { // 左侧文字
- type: String,
- default: "所在地"
- },
- placeholder: {
- type: String,
- default: "请选择省市区"
- },
- popupTitle: {
- type: String,
- default: "请选择省市区"
- },
- required: {
- type: Boolean,
- default: false
- }
- },
- data() {
- return {
- innerValue: this.value,
- localData: [] // 省市区树数据
- }
- },
- watch: {
- value(newVal) {
- this.innerValue = newVal
- },
- innerValue(newVal) {
- this.$emit("input", newVal)
- }
- },
- created() {
- this.localData = this.get_city_tree()
- },
- methods: {
- /** 点击选择后的回调 */
- onChange(e) {
- const lastNode = e.detail.value[e.detail.value.length - 1]
- this.innerValue = lastNode.value // 只存最底层的 code
- },
- /** 清空地址 */
- clearAddress() {
- this.innerValue = ""
- this.$emit("clear")
- },
- /** 回显文字(递归找路径) */
- getLocationLabel(value) {
- if (!value) return ""
- let label = ""
- const traverse = (nodes) => {
- for (const node of nodes) {
- if (node.value === value) {
- label = node.text
- return true
- }
- if (node.children && traverse(node.children)) {
- label = node.text + " - " + label
- return true
- }
- }
- return false
- }
- traverse(this.localData)
- return label
- },
- /** 生成树数据 */
- get_city_tree() {
- let res = []
- if (cityRows.length) {
- res = this.handleTree(cityRows)
- }
- return res
- },
- /** 递归组装树 */
- handleTree(data, parent_code = null) {
- let res = []
- let keys = {
- id: "code",
- pid: "parent_code",
- children: "children",
- text: "name",
- value: "code"
- }
- for (let item of data) {
- if (parent_code === null) {
- // 顶级
- if (!item.hasOwnProperty(keys.pid) || item[keys.pid] == parent_code) {
- let node = {
- text: item[keys.text],
- value: item[keys.value],
- children: this.handleTree(data, item[keys.id])
- }
- res.push(node)
- }
- } else {
- // 子级
- if (item.hasOwnProperty(keys.pid) && item[keys.pid] == parent_code) {
- let node = {
- text: item[keys.text],
- value: item[keys.value],
- children: this.handleTree(data, item[keys.id])
- }
- res.push(node)
- }
- }
- }
- return res
- }
- }
- }
- </script>
- <style scoped>
- .form-item {
- display: flex;
- flex-direction: column;
- /* margin-bottom: 20rpx; */
- }
- .item-label {
- display: flex;
- align-items: center;
- margin-bottom: 10rpx;
- }
- .label-text {
- font-size: 28rpx;
- color: #333;
- }
- .required {
- color: red;
- margin-left: 5rpx;
- }
- .location-text {
- /* font-size: 28rpx;
- color: #333; */
- /* padding: 16rpx 0; */
- }
- </style>
|