index.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <template>
  2. <el-select
  3. :key="config.code"
  4. v-model="value"
  5. :popper-class="'basic-component-select select-popper-' + config.code"
  6. :class="['basic-component-select', `select-${config.code}`]"
  7. :placeholder="`请选择${placeholder || newPlaceholder}`"
  8. filterable
  9. clearable
  10. @visible-change="visibleChange"
  11. @change="selectChange"
  12. @mouseenter.native="mouseenter"
  13. >
  14. <el-option
  15. v-for="(option, key) in optionData"
  16. :key="key"
  17. :label="option[config.dataSource.dimensionField]"
  18. :value="option[config.dataSource.metricField]"
  19. />
  20. </el-select>
  21. </template>
  22. <script>
  23. import { EventBus } from 'data-room-ui/js/utils/eventBus'
  24. import commonMixins from 'data-room-ui/js/mixins/commonMixins'
  25. import linkageMixins from 'data-room-ui/js/mixins/linkageMixins'
  26. import { getDataSetDetails } from 'data-room-ui/js/api/bigScreenApi'
  27. window.dataSetFields = []
  28. export default {
  29. name: 'BasicComponentSelect',
  30. components: {},
  31. mixins: [commonMixins, linkageMixins],
  32. props: {
  33. // 组件配置
  34. config: {
  35. type: Object,
  36. default: () => ({})
  37. }
  38. },
  39. data () {
  40. return {
  41. value: '',
  42. innerConfig: {},
  43. optionData: [],
  44. newPlaceholder: ''
  45. }
  46. },
  47. computed: {
  48. isPreview () {
  49. return (this.$route.path === window?.BS_CONFIG?.routers?.previewUrl) || (this.$route.path === '/big-screen/preview')
  50. },
  51. placeholder: {
  52. get () {
  53. return window.dataSetFields.find(field => field.value === this.config.dataSource.dimensionField)?.label || ''
  54. },
  55. set (val) {
  56. this.newPlaceholder = val
  57. }
  58. }
  59. },
  60. watch: { },
  61. created () {
  62. },
  63. mounted () {
  64. window.dataSetFields = []
  65. this.changeStyle(this.config)
  66. EventBus.$on('changeBusinessKey', () => {
  67. window.dataSetFields = []
  68. })
  69. if (this.isPreview) {
  70. if (window.dataSetFields.length === 0) {
  71. getDataSetDetails(this.config.dataSource.businessKey).then(res => {
  72. window.dataSetFields = res.fields.map(field => {
  73. return {
  74. label: field.comment || field.fieldDesc,
  75. value: field.name || field.fieldName
  76. }
  77. })
  78. this.placeholder = window.dataSetFields.find(field => field.value === this.config.dataSource.dimensionField)?.label || ''
  79. })
  80. }
  81. }
  82. },
  83. beforeDestroy () {
  84. EventBus.$off('changeBusinessKey')
  85. },
  86. methods: {
  87. dataFormatting (config, data) {
  88. // 数据返回成功则赋值
  89. if (data.success) {
  90. data = data.data
  91. // 获取到后端返回的数据,有则赋值
  92. if (config.dataHandler) {
  93. try {
  94. // 此处函数处理data
  95. eval(config.dataHandler)
  96. } catch (e) {
  97. console.info(e)
  98. }
  99. }
  100. config.option.data = data
  101. this.optionData = data
  102. config.customize.title = config.option.data[config.dataSource.dimensionField] || config.customize.title
  103. if (window.dataSetFields.length === 0) {
  104. getDataSetDetails(this.config.dataSource.businessKey).then(res => {
  105. window.dataSetFields = res.fields.map(field => {
  106. return {
  107. label: field.comment || field.fieldDesc,
  108. value: field.name || field.fieldName
  109. }
  110. })
  111. this.placeholder = window.dataSetFields.find(field => field.value === this.config.dataSource.dimensionField)?.label || ''
  112. })
  113. }
  114. // 语音播报
  115. } else {
  116. // 数据返回失败则赋前端的模拟数据
  117. config.option.data = []
  118. this.optionData = []
  119. }
  120. return config
  121. },
  122. changeStyle (config) {
  123. config = { ...this.config, ...config }
  124. this.innerConfig = config
  125. // 选择器元素
  126. const selectInputEl = document.querySelector(`.select-${config.code} .el-input__inner`)
  127. // 背景颜色
  128. selectInputEl.style.backgroundColor = config.customize.backgroundColor
  129. // 字体大小
  130. selectInputEl.style.fontSize = config.customize.fontSize + 'px'
  131. // 字体颜色
  132. selectInputEl.style.color = config.customize.fontColor
  133. // 下拉图标
  134. const selectDropdownIcon = document.querySelector(`.select-${config.code} .el-icon-arrow-up`)
  135. selectDropdownIcon.style.fontSize = config.customize.fontSize + 'px'
  136. // 选择器下拉框元素
  137. const selectDropdownEl = document.querySelector(`.select-${config.code} .el-select-dropdown`)
  138. // 箭头背景颜色和下拉框背景颜色一致
  139. if (selectDropdownEl) {
  140. // 下拉框无边框
  141. selectDropdownEl.style.border = 'none'
  142. // 背景颜色
  143. selectDropdownEl.style.backgroundColor = config.customize.dropDownBackgroundColor
  144. }
  145. },
  146. // 组件联动
  147. selectChange (val) {
  148. this.linkage(this.config.option.data.find(item => item[this.config.dataSource.metricField] === val))
  149. },
  150. visibleChange (val) {
  151. if (val) {
  152. // 修改下拉框背景颜色,让下拉框背景颜色和箭头背景颜色一致
  153. const selectDropdownEl = document.querySelector(`.select-popper-${this.innerConfig.code}`)
  154. selectDropdownEl.style.color = this.innerConfig.customize.dropDownBackgroundColor
  155. // 空状态
  156. const selectDropdownEmptyEl = document.querySelector(`.select-popper-${this.innerConfig.code} .el-select-dropdown__empty`)
  157. if (selectDropdownEmptyEl) {
  158. selectDropdownEmptyEl.style.backgroundColor = this.innerConfig.customize.dropDownBackgroundColor
  159. }
  160. // 下拉项hover颜色
  161. const selectDropdownItemEl = document.querySelectorAll(`.select-popper-${this.innerConfig.code} .el-select-dropdown__item`)
  162. // 给--dropDownHoverFontColor 和 --dropDownHoverBackgroundColor 赋值
  163. selectDropdownItemEl.forEach(item => {
  164. item.style.setProperty('--dropDownHoverFontColor', this.innerConfig.customize.dropDownHoverFontColor)
  165. item.style.setProperty('--dropDownHoverBackgroundColor', this.innerConfig.customize.dropDownHoverBackgroundColor)
  166. })
  167. // 激活项
  168. // const selectDropdownItemSelectedEl = document.querySelectorAll(`.select-popper-${this.innerConfig.code} .el-select-dropdown__item.selected`)
  169. // selectDropdownItemSelectedEl.forEach(item => {
  170. // item.style.color = this.innerConfig.customize.activeFontColor
  171. // item.style.backgroundColor = this.innerConfig.customize.activeBackgroundColor
  172. // })
  173. }
  174. // 不是激活项的还是使用背景颜色
  175. const selectDropdownItemEl = document.querySelectorAll(`.select-popper-${this.innerConfig.code} .el-select-dropdown__item`)
  176. selectDropdownItemEl.forEach(item => {
  177. // 检查是否是激活项,不是则使用背景颜色
  178. if (!item.classList.contains('selected')) {
  179. item.style.color = this.innerConfig.customize.dropDownFontColor
  180. item.style.backgroundColor = this.innerConfig.customize.dropDownBackgroundColor
  181. }
  182. })
  183. },
  184. mouseenter () {
  185. if (this.value) {
  186. setTimeout(() => {
  187. // 清空图标
  188. const selectDropdownCloseIcon = document.querySelector(`.select-${this.innerConfig.code} .el-icon-circle-close`)
  189. if (selectDropdownCloseIcon) {
  190. selectDropdownCloseIcon.style.fontSize = this.innerConfig.customize.fontSize + 'px'
  191. }
  192. }, 30)
  193. }
  194. }
  195. }
  196. }
  197. </script>
  198. <style lang="scss">
  199. .basic-component-select{
  200. color: '';
  201. .el-select-dropdown__wrap {
  202. margin-bottom: 0px !important;
  203. }
  204. .el-select-group__wrap:not(:last-of-type)::after {
  205. background-color: transparent !important;
  206. }
  207. .popper__arrow{
  208. border-bottom-color:var(--color) !important;
  209. &::after{
  210. border-bottom-color:var(--color) !important;
  211. }
  212. }
  213. }
  214. </style>
  215. <style lang="scss" scoped>
  216. .basic-component-select {
  217. width: 100%;
  218. height: 100%;
  219. ::v-deep .el-input {
  220. height: 100% !important;
  221. .el-select__caret{
  222. width: 100%;
  223. height: 100%;
  224. display: flex;
  225. align-items: center;
  226. }
  227. // 选择器输入框样式
  228. .el-input__inner {
  229. height: 100% !important;
  230. border-color: var(--bs-el-border) !important;
  231. }
  232. }
  233. .el-select-dropdown__item.hover,
  234. .el-select-dropdown__item:hover {
  235. color: var(--dropDownHoverFontColor) !important;
  236. background-color: var(--dropDownHoverBackgroundColor) !important;
  237. }
  238. .el-tag.el-tag--info {
  239. color: var(--bs-el-text) !important;
  240. }
  241. .popper__arrow {
  242. bottom: 0 !important;
  243. &:after {
  244. bottom: 0 !important;
  245. }
  246. }
  247. }
  248. </style>