LanguageInput.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <template>
  2. <el-input class="_fd-language-input" :class="{'is-variable': isVar}" :placeholder="placeholder" :disabled="disabled"
  3. :modelValue="modelValue"
  4. @update:modelValue="onInput"
  5. @blur="$emit('blur')"
  6. :size="size || 'small'">
  7. <template #append>
  8. <el-popover placement="bottom-end" :width="300" :hide-after="0" trigger="click" ref="pop"
  9. popper-class="_fd-language-popover">
  10. <template #reference>
  11. <i class="fc-icon icon-language"></i>
  12. </template>
  13. <div class="_fd-language-list">
  14. <div class="_fd-language-header">
  15. <div class="_fd-language-title">
  16. {{ t('language.select') }}<i class="fc-icon icon-setting" @click="openConfig"></i>
  17. </div>
  18. <div class="_fd-language-name">
  19. <template v-for="item in localeList" :key="item.value">
  20. <div>{{ item.label }}</div>
  21. </template>
  22. </div>
  23. </div>
  24. <template v-for="lang in language" :key="lang.key">
  25. <div class="_fd-language-item" @click="clickLang(lang.key)">
  26. <template v-for="item in localeList" :key="item.value">
  27. <div>{{ lang[item.value] || '-' }}</div>
  28. </template>
  29. </div>
  30. </template>
  31. </div>
  32. </el-popover>
  33. </template>
  34. </el-input>
  35. </template>
  36. <script>
  37. import {defineComponent} from 'vue';
  38. export default defineComponent({
  39. name: 'LanguageInput',
  40. inject: ['designer'],
  41. emits: ['update:modelValue', 'blur', 'change'],
  42. props: {
  43. size: String,
  44. placeholder: String,
  45. modelValue: String,
  46. disabled: Boolean,
  47. },
  48. computed: {
  49. isVar() {
  50. return !!(this.modelValue || '').match(/^\{\{\s*\$t\.(.+)\s*\}\}$/);
  51. },
  52. t() {
  53. return this.designer.setupState.t;
  54. },
  55. localeList() {
  56. const localeOptions = this.designer.setupState.getConfig('localeOptions', [
  57. {value: 'zh-cn', label: '简体中文'},
  58. {value: 'en', label: 'English'},
  59. ]);
  60. const localeList = [];
  61. const locale = this.designer.props?.locale?.name || 'zh-cn';
  62. localeOptions.forEach((item) => {
  63. if (item.value === locale) {
  64. localeList.unshift(item);
  65. } else if (localeList.length < 2) {
  66. localeList.push(item);
  67. }
  68. });
  69. if (localeList.length > 2) {
  70. localeList.pop();
  71. }
  72. return localeList;
  73. },
  74. language() {
  75. const language = this.designer.setupState.formOptions.language || {};
  76. const column = {};
  77. Object.keys(language).forEach(lang => {
  78. Object.keys(language[lang]).forEach(key => {
  79. if (!column[key]) {
  80. column[key] = {
  81. key: key,
  82. }
  83. }
  84. column[key][lang] = language[lang][key];
  85. })
  86. });
  87. return Object.values(column);
  88. }
  89. },
  90. methods: {
  91. openConfig() {
  92. this.designer.setupState.activeModule = 'language';
  93. },
  94. clickLang(key) {
  95. this.onInput(`{{$t.${key}}}`);
  96. this.$refs.pop.hide();
  97. },
  98. onInput(val) {
  99. this.$emit('update:modelValue', val);
  100. this.$emit('change', val);
  101. }
  102. },
  103. mounted() {
  104. }
  105. });
  106. </script>
  107. <style>
  108. ._fd-language-list {
  109. max-height: 320px;
  110. padding-top: 70px;
  111. overflow: auto;
  112. }
  113. ._fd-language-input .el-input-group__append {
  114. width: 25px;
  115. padding: 0;
  116. margin: 0;
  117. color: #AAAAAA;
  118. cursor: pointer;
  119. }
  120. ._fd-language-input.is-variable input {
  121. color: #2E73FF;
  122. }
  123. ._fd-language-header, ._fd-language-item {
  124. display: flex;
  125. border-bottom: 1px solid #ECECEC;
  126. padding: 0 12px;
  127. }
  128. ._fd-language-header {
  129. font-weight: 500;
  130. padding-top: 10px;
  131. overflow: auto;
  132. color: #262626;
  133. position: absolute;
  134. top: 0;
  135. left: 0;
  136. right: 0;
  137. background-color: #FFFFFF;
  138. flex-direction: column;
  139. }
  140. ._fd-language-name > div, ._fd-language-item > div {
  141. flex: 1;
  142. font-size: 12px;
  143. padding: 5px;
  144. min-width: 70px;
  145. }
  146. ._fd-language-title {
  147. margin: 6px 0;
  148. }
  149. ._fd-language-title .fc-icon {
  150. color: #2E73FF;
  151. cursor: pointer;
  152. font-size: 14px;
  153. }
  154. ._fd-language-name {
  155. display: flex;
  156. }
  157. ._fd-language-name > div {
  158. white-space: nowrap;
  159. overflow: hidden;
  160. text-overflow: ellipsis;
  161. }
  162. ._fd-language-item {
  163. cursor: pointer;
  164. }
  165. ._fd-language-item:hover {
  166. color: #2E73FF;
  167. background-color: #CCDFFF;
  168. }
  169. ._fd-language-popover {
  170. padding: 0 !important;
  171. }
  172. </style>