tag-sec-select.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <template>
  2. <div id="tag-sec-select">
  3. <el-row style="background:#fff;min-height:3.5rem;padding: 0.5rem 0;">
  4. <el-col :span="5" style="font-size: 0.875rem;padding-left: 0.6rem;padding-top:0.5rem;" v-if="title">{{ title }}</el-col>
  5. <el-col :span="title ? 18 : 24" style="text-align:left;padding-bottom:1rem;" @click.native="changeDisplay">
  6. <span v-if="selected.length <= 0" style="color:#bbb;">
  7. {{ placeholder }}
  8. </span>
  9. <span v-else>
  10. <span v-for="(item, index) in selected" :key="index" style="margin-right:0.1rem;">
  11. {{ item.label }}
  12. </span>
  13. </span>
  14. </el-col>
  15. </el-row>
  16. <el-dialog title="请选择" :visible.sync="dialog" :fullscreen="true" :show-close="false">
  17. <el-row style="background:#ffffff;">
  18. <el-col :span="24" v-if="selectList.length > 0">
  19. <el-tag v-for="(item, index) in selected" :key="index" @click="tagClose(item)" style="margin-right:0.8rem;" :disable-transitions="true">
  20. {{ item.label }}
  21. </el-tag>
  22. </el-col>
  23. <el-col :span="24" style="width:100%;text-align:center;" v-else>请选择</el-col>
  24. </el-row>
  25. <el-row :gutter="10" class="selectCard">
  26. <el-col :span="6" class="firstMenu">
  27. <el-menu background-color="#eeeeee" text-color="#000" active-text-color="#409EFF" @select="selectMenu">
  28. <el-menu-item v-for="(item, index) in firstList" :key="index" :index="item.value">
  29. <template v-slot="title">
  30. {{ item.label }}
  31. </template>
  32. </el-menu-item>
  33. </el-menu>
  34. </el-col>
  35. <el-col :span="18" style="padding:1rem 1rem;">
  36. <el-row type="flex" style="margin-bottom:1rem;" v-if="secondList.length > 0">
  37. <el-switch v-model="allSelect" active-text="全选" inactive-text="" @change="childrenSelect"> </el-switch>
  38. </el-row>
  39. <el-checkbox-group v-model="selectList" @change="selectChange">
  40. <el-col :span="6" v-for="(item, index) in secondList" :key="index" class="word">
  41. <el-checkbox :label="item.value">{{ item.label }}</el-checkbox>
  42. </el-col>
  43. </el-checkbox-group>
  44. </el-col>
  45. </el-row>
  46. <el-row class="btn__row">
  47. <el-col :span="23">
  48. <el-button type="info" @click="dialog = false" style="width:100%;border-radius: 30px">返回</el-button>
  49. </el-col>
  50. </el-row>
  51. </el-dialog>
  52. </div>
  53. </template>
  54. <script>
  55. import _ from 'lodash';
  56. export default {
  57. name: 'tag-sec-select',
  58. props: {
  59. title: { type: String },
  60. selected: { type: Array, default: () => [] }, //已选项
  61. placeholder: { type: String, default: '请选择' }, //提示
  62. firstList: { type: Array, default: () => [] }, //一级选项列表
  63. secondList: { type: Array, default: () => [] }, //二级选项列表
  64. type: { type: String, default: '' },
  65. },
  66. components: {},
  67. data: () => ({
  68. dialog: false,
  69. selectList: [],
  70. displayList: [],
  71. allSelect: false,
  72. }),
  73. watch: {
  74. selected: {
  75. handler(value, oval) {
  76. let dif = _.difference(value, oval);
  77. if (dif.length > 0) {
  78. this.defaultProcess();
  79. }
  80. },
  81. },
  82. },
  83. created() {
  84. if (this.selected.length > 0) {
  85. this.defaultProcess();
  86. }
  87. },
  88. computed: {},
  89. methods: {
  90. async selectMenu(value) {
  91. if (value !== '0') {
  92. this.cleanUnlimited();
  93. await this.$emit('listChange', { value: value, type: this.type });
  94. } else {
  95. this.$set(this, `displayList`, [{ label: '不限专业', value: '0' }]);
  96. this.$set(this, `selectList`, [{ label: '不限专业', value: '0' }]);
  97. this.$emit('selectChange', { value: [{ label: '不限专业', value: '0' }], type: this.type });
  98. }
  99. this.checkIsAll();
  100. },
  101. //选项操作
  102. selectChange() {
  103. let newArr = [];
  104. this.selectList.map(item => {
  105. let result = this.secondList.filter(fil => fil.value === item);
  106. if (result.length > 0) {
  107. result.forEach(res => {
  108. newArr.push(res);
  109. });
  110. } else {
  111. result = this.displayList.filter(fil => fil.value === item);
  112. if (result.length > 0) {
  113. result.forEach(res => {
  114. newArr.push(res);
  115. });
  116. }
  117. }
  118. });
  119. this.disFilter(newArr);
  120. this.checkIsAll();
  121. },
  122. //不限专业
  123. cleanUnlimited() {
  124. let result = this.displayList.filter(item => item.value !== '0');
  125. this.$set(this, `displayList`, result);
  126. this.$set(this, `allSelect`, false);
  127. },
  128. //全/反选
  129. childrenSelect(value) {
  130. //本子列表全选及反选
  131. let newArr = [];
  132. let result = [];
  133. this.secondList.map(item => {
  134. newArr.push(item.value);
  135. });
  136. if (value) {
  137. result = _.uniq(_.concat(this.selectList, newArr));
  138. } else {
  139. result = _.differenceWith(this.selectList, newArr);
  140. }
  141. this.$set(this, `selectList`, result);
  142. this.selectChange();
  143. },
  144. //该页选择全部选项,自动切换全选;该页未全部选择,去掉全选
  145. checkIsAll() {
  146. if (this.secondList.length > 0) {
  147. let result = true;
  148. for (const item of this.secondList) {
  149. let i = 0;
  150. for (i = 0; i < this.selectList.length; i++) {
  151. const select = this.selectList[i];
  152. if (item.value === select) {
  153. break;
  154. }
  155. }
  156. if (i === this.selectList.length) {
  157. result = false;
  158. break;
  159. }
  160. }
  161. this.$set(this, `allSelect`, result);
  162. }
  163. },
  164. //显示/隐藏选择面板
  165. changeDisplay() {
  166. this.$set(this, `dialog`, !this.dialog);
  167. },
  168. //初始化处理
  169. defaultProcess() {
  170. //处理复选框
  171. let select = this.selected.map(item => item.value);
  172. this.$set(this, `selectList`, select);
  173. //处理显示
  174. this.$set(this, `displayList`, this.selected);
  175. },
  176. //显示处理;选择值
  177. disFilter(value) {
  178. this.$emit('selectChange', { value: value, type: this.type });
  179. this.$set(this, `displayList`, value);
  180. },
  181. //关闭标签方法
  182. tagClose(value) {
  183. //取消选择
  184. let leastList = this.selectList.filter(item => item !== value.value);
  185. let leastDisplayList = this.displayList.filter(item => item.value !== value.value);
  186. this.$set(this, `selectList`, leastList);
  187. this.disFilter(leastDisplayList);
  188. },
  189. },
  190. };
  191. </script>
  192. <style lang="less" scoped>
  193. .el-menu-item {
  194. height: 2rem;
  195. line-height: 2rem;
  196. text-align: center;
  197. }
  198. .btn__row {
  199. padding-top: 1rem;
  200. }
  201. </style>