123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- <template>
- <div class='cascadeSelection'>
- <!-- 框框 -->
- <div ref="focusDiv" tabindex="0" :class="`input ${size} ${disabled ? 'inputDisabled' : ''}`"
- :style="`width: ${width}`" @focus="handleFocus" @blur="handleBlur">
- <!-- 默认提示文字 -->
- <span class="placeholderColor" v-if="resultText.length == 0">请选择</span>
- <!-- 选中数据 -->
- <div v-if="resultText.length > 0" class="textEllipsisNowrap">
- <template v-for="(item, index) in resultText[0]">
- <TranslationOpenDataText type='departmentName' :openid='item'></TranslationOpenDataText>
- <span v-if="index < resultText[0].length - 1" class="textSpan">/</span>
- </template>
- </div>
- <i v-if="resultText.length > 0" class="el-icon-circle-close iostu" @click.stop="clearDelete"></i>
- <!-- 级联面板 -->
- <div class="absoluteWeight" v-if="isFocused" :style="`top: ${sizeTop[size]}`">
- <el-cascader-panel v-model="modelValue" ref="cascaderPanelRef" :options="options" :props="props"
- @change="panelChange">
- <template slot-scope="{ node, data }">
- <TranslationOpenDataText type='departmentName' :openid='data.label'></TranslationOpenDataText>
- </template>
- </el-cascader-panel>
- </div>
- </div>
- </div>
- </template>
- <script>
- export default {
- name: '',
- components: {},
- props: {
- modelValue: {
- type: Array,
- default: () => []
- },
- size: {
- type: String,
- default: 'default',
- },
- width: {
- type: String,
- default: '100%',
- },
- options: {
- type: Array,
- default: () => [],
- },
- props: {
- type: Object,
- default: () => {
- return { checkStrictly: true, expandTrigger: 'hover' }
- }
- },
- disabled: {
- type: Boolean,
- default: false
- }
- },
- data() {
- return {
- isFocused: false,
- resultText: [],
- sizeTop: {
- default: '40px',
- medium: '36px',
- small: '32px',
- mini: '24px'
- }
- }
- },
- computed: {},
- watch: {},
- created() { },
- mounted() {
- setTimeout(() => {
- if ((this.modelValue || []).length > 0) {
- this.resultText = this.findDepartmentNames(this.options, this.props.multiple ? this.modelValue : [this.modelValue]);
- }
- }, 500)
- },
- model: {
- prop: 'modelValue',
- event: 'getValue'
- },
- methods: {
- panelChange(val) {
- this.resultText = this.findDepartmentNames(this.options, this.props.multiple ? val : [val]);
- this.updateModelValue()
- },
- findDepartmentNames(data, values) {
- const findLabels = (valueList) => {
- return valueList.map(value => {
- const findLabel = (data, value) => {
- for (let item of data) {
- if (item.value === value) {
- return item.label;
- }
- if (item.children) {
- const label = findLabel(item.children, value);
- if (label) return label;
- }
- }
- return null;
- };
- return findLabel(data, value);
- }).filter(label => label !== null);
- };
- return values.map(valueList => findLabels(valueList));
- },
- handleFocus() {
- if(this.disabled) {
- return
- }
- this.isFocused = true
- this.$refs.focusDiv.classList.add('focused');
- },
- handleBlur(event) {
- if(this.disabled) {
- return
- }
- if (this.$refs.focusDiv.contains(event.relatedTarget)) {
- this.$refs.focusDiv.focus();
- event.preventDefault();
- return;
- }
- this.isFocused = false
- this.$refs.focusDiv.classList.remove('focused');
- },
- clearDelete() {
- this.$refs.focusDiv.blur()
- this.resultText = [];
- this.$emit('getValue', []);
- this.$emit('change', []);
- },
- updateModelValue() {
- this.$emit('getValue', this.modelValue);
- this.$emit('change', this.modelValue);
- }
- },
- }
- </script>
- <style scoped lang='scss'>
- @import "../assets/scss/handle";
- .cascadeSelection {
- position: relative;
- max-height: 40px;
- .default {
- height: 40px;
- line-height: 40px;
- }
- .medium {
- height: 36px;
- line-height: 36px;
- }
- .small {
- height: 32px;
- line-height: 32px;
- }
- .mini {
- height: 28px;
- line-height: 28px;
- }
- .input {
- position: relative;
- font-size: 14px;
- background-color: #FFF;
- background-image: none;
- border-radius: 4px;
- border: 1px solid #DCDFE6;
- box-sizing: border-box;
- color: #606266;
- display: inline-block;
- outline: 0;
- padding: 0 15px;
- -webkit-transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
- transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
- width: 100%;
- }
- .input:focus {
- @include border_color("border_color");
- }
- .placeholderColor {
- color: #C0C4CC;
- }
- .absoluteWeight {
- position: absolute;
- z-index: 99;
- background: #fff;
- left: 0;
- }
- .textSpan {
- display: inline-block;
- padding: 0 3px
- }
- .textEllipsisNowrap {
- width: 100%;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- .iostu {
- position: absolute;
- top: 50%;
- margin-top: -4px;
- right: 8px;
- color: #C0C4CC;
- transition: All 0.2s ease-in-out;
- }
- .iostuHover {
- transform: rotate(-180deg);
- }
- .inputDisabled {
- background-color: #f5f7fa !important;
- border-color: #e4e7ed !important;
- color: #c0c4cc !important;
- cursor: not-allowed !important;
- }
- }
- </style>
|