

<template>
<div>
<van-field
readonly
clickable
:placeholder="placeholder"
:disabled="disabled"
:clearable="clearable"
:rules="rules"
:left-icon="prefixIcon"
input-align="left"
:required="required"
:value="currentValue.name"
:icon="suffixIcon"
:label="label"
@click.native="selectClick">
<template #label>
<div>
<span>{{ label }}</span>
</div>
</template>
<template #right-icon>
<div @click.stop="openCamera">
<van-icon name="scan" class="scan-icon"/>
</div>
</template>
</van-field>
<van-popup v-model="showPicker"
position="bottom">
<van-picker ref="picker"
show-toolbar
:title="title"
:visible-item-count="7"
:loading="pulling"
:columns="columns"
@cancel="handleCancel"
@change="onChange"
@confirm="handleConfirm">
<template #columns-top>
<van-steps inactive-icon="arrow" active-icon="location" :active="selectedItem.length-1" @click-step="stepClick" style="padding-bottom: 30px">
<van-step v-if="selectedItem.length>0">重选</van-step>
<van-step v-for="(item,index) in selectedItem" :key="item.id">
{{item.item.name | textAbbreviate(4)}}
</van-step>
</van-steps>
</template>
</van-picker>
</van-popup>
</div>
</template>
<script>
import {mapGetters} from 'vuex'
import {paging} from "../../../api/device-info";
export default {
name: 'DeviceSelect',
mounted() {
this.loadData();
},
components: {},
props: {
value: {
required: true,
default() {
return {};
}
},
loading: {
type: Boolean,
default: false
},
command: {
default: ''
},
disabled: {
type: Boolean,
default: false
},
label: null,
rules: null,
clearable: {
type: Boolean,
default: false
},
required: {
type: Boolean,
default: false
},
prefixIcon: null,
suffixIcon: null,
placeholder: null,
},
data() {
let value = this.value || {};
return {
showPicker: false,
pulling: false,
currentValue: {
...value
},
columns: [],
deep: 0,
selectedItem: [],
params: {
parentId: 0
},
device: this.deviceDetail
}
},
computed: {
title() {
if (!this.selectedItem || this.selectedItem.length <= 0) {
if (!this.currentValue || !this.currentValue.id) {
return '';
}
return this.currentValue.name;
}
return this.selectedItem[this.selectedItem.length - 1].item.name;
},
...mapGetters([
'deviceDetail'
])
},
methods: {
dataMapper(item) {
return {
text: item.name,
data: item,
}
},
loadData() {
this.pulling = true;
paging(this.params).then(res => {
this.pulling = false;
if (res.code !== 'ok') {
this.$toast.fail(res.msg || "设备数据获取失败");
return;
}
if (!res.data || res.data.length <= 0) {
return;
}
this.deep++;
this.columns = (res.data.list || []).map(this.dataMapper);
this.columns.unshift({
text: '请选择',
data: null
})
})
},
/**
* field 点击事件
* @date 2020/4/8 14:53
*/
selectClick() {
if (this.disabled) {
return;
}
this.showPicker = true;
},
/**
* 步骤条点击事件
* @date 2020/4/8 14:52
*/
stepClick(index) {
if (index === 0) {
this.deep = 0;
this.columns = [];
this.selectedItem = [];
this.params = {
parentId: 0
};
this.loadData();
return;
}
let selectedItemElement = this.selectedItem[index - 1];
this.params.parentId = selectedItemElement.item.id;
this.selectedItem = this.selectedItem.filter((val, i) => {
return i < index;
});
this.deep = selectedItemElement.deep;
this.loadData();
},
/**
* picker 改变事件
* @date 2020/4/8 14:53
*/
onChange(picker, values) {
if (!values.data || !values.data.id) {
return;
}
this.updateSelectedItem(values.data, this.deep);
this.params.parentId = values.data.id;
// this.loadData();
},
/**
* 更新选择项
* @date 2020/4/8 14:19
*/
updateSelectedItem(item, deep) {
if (!item || !item.id) {
return;
}
let index = this.selectedItem.findIndex(val => {
return val.deep === deep;
});
if (index !== -1) {
this.selectedItem = this.selectedItem.filter(val => {
return val.deep < deep;
});
}
this.selectedItem.push({
item,
deep
});
},
/**
* 取消
* @date 2020/4/8 14:54
*/
handleCancel() {
this.showPicker = false;
},
/**
* 确认选择
* @date 2020/4/8 14:54
*/
handleConfirm(value, index) {
if (!this.selectedItem || this.selectedItem.length <= 0) {
if (!this.currentValue || !this.currentValue.id) {
this.$toast.fail('请选择');
return;
}
this.showPicker = false;
return;
}
this.currentValue = {
...this.selectedItem[this.selectedItem.length - 1].item
};
this.$emit('input', this.currentValue);
this.$emit('change', this.currentValue);
this.showPicker = false;
},
openCamera() {
this.$android.qrCodeScan((data) => {
if (!data || !data.id) {
return;
}
this.currentValue = {
...data
};
this.$emit('input', this.currentValue);
this.$emit('change', this.currentValue)
})
}
},
watch: {
value: function (val) {
if (!val) {
this.currentValue = {};
return;
}
this.currentValue = {
...val
};
},
deviceDetail(val) {
if (val) {
this.currentValue = {
...val
};
this.$emit('input', this.currentValue);
this.$emit('change', this.currentValue);
}
}
},
filters: {},
beforeDestroy() {
}
}
</script>
<style scoped>
.scan-icon {
line-height: inherit;
font-size: 1.4rem;
vertical-align: middle
}
</style>