WidgetConfig.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. <template>
  2. <div class="widget-config">
  3. <el-form label-suffix=":"
  4. v-if="this.data && Object.keys(this.data).length > 0"
  5. labelPosition="left"
  6. labelWidth="90px"
  7. size="small">
  8. <el-collapse v-model="collapse">
  9. <el-collapse-item name="1"
  10. title="基本属性">
  11. <el-form-item label="类型"
  12. v-if="data.type && !data.component">
  13. <el-select v-model="data.type"
  14. style="width:100%;"
  15. placeholder="请选择类型"
  16. @change="handleChangeType">
  17. <el-option-group v-for="group in fields"
  18. :key="group.title"
  19. :label="group.title">
  20. <el-option v-for="item in group.list"
  21. :key="item.type"
  22. :label="item.label"
  23. :value="item.type">
  24. </el-option>
  25. </el-option-group>
  26. </el-select>
  27. </el-form-item>
  28. <el-form-item label="属性值">
  29. <el-input v-model="data.prop"
  30. clearable
  31. placeholder="属性值"></el-input>
  32. </el-form-item>
  33. <el-form-item label="标题">
  34. <el-input v-model="data.label"
  35. clearable
  36. placeholder="标题"></el-input>
  37. </el-form-item>
  38. <el-form-item label="宽度"
  39. v-if="data.subfield">
  40. <el-input-number style="width:100%;"
  41. v-model="data.width"
  42. controls-position="right"
  43. placeholder="宽度"
  44. :min="100"></el-input-number>
  45. </el-form-item>
  46. <el-form-item label="表单栅格"
  47. v-if="!data.subfield && !['group'].includes(data.type)">
  48. <el-input-number style="width:100%;"
  49. v-model="data.span"
  50. controls-position="right"
  51. placeholder="表单栅格"
  52. :min="8"
  53. :max="24"></el-input-number>
  54. </el-form-item>
  55. <el-form-item label="数据类型"
  56. v-if="['cascader','checkbox','radio','select','tree','upload','img','array','slider','timerange','daterange','datetimerange'].includes(data.type)">
  57. <template slot="label">
  58. <el-link :underline="false"
  59. href="https://avuejs.com/doc/dataType"
  60. target="_blank">数据类型 <i class="el-icon-question"></i></el-link>
  61. </template>
  62. <el-select v-model="data.dataType"
  63. placeholder="数据类型"
  64. clearable>
  65. <el-option label="String"
  66. value="string"></el-option>
  67. <el-option label="Number"
  68. value="number"></el-option>
  69. <el-option label="Array"
  70. value="array"></el-option>
  71. </el-select>
  72. </el-form-item>
  73. <el-form-item label="深结构"
  74. v-if="data.type && !data.component">
  75. <template slot="label">
  76. <el-link :underline="false"
  77. href="https://avuejs.com/doc/form/form-bind"
  78. target="_blank">深结构 <i class="el-icon-question"></i></el-link>
  79. </template>
  80. <el-input v-model="data.bind"
  81. clearable
  82. placeholder="深结构"></el-input>
  83. </el-form-item>
  84. <el-form-item label="字段提示">
  85. <template slot="label">
  86. <el-link :underline="false"
  87. href="https://avuejs.com/doc/form/form-tip"
  88. target="_blank">字段提示 <i class="el-icon-question"></i></el-link>
  89. </template>
  90. <el-input v-model="data.tip"
  91. clearable
  92. placeholder="字段提示"></el-input>
  93. </el-form-item>
  94. <el-form-item v-if="data.tip && !['upload'].includes(data.type)"
  95. label="字段提示位置"
  96. label-width="110px">
  97. <el-select v-model="data.tipPlacement"
  98. placeholder="字段提示位置"
  99. clearable>
  100. <el-option label="上"
  101. value="top"></el-option>
  102. <el-option label="下"
  103. value="bottom"></el-option>
  104. <el-option label="左"
  105. value="left"></el-option>
  106. <el-option label="右"
  107. value="right"></el-option>
  108. </el-select>
  109. </el-form-item>
  110. <el-form-item label="标题提示">
  111. <template slot="label">
  112. <el-link :underline="false"
  113. href="https://avuejs.com/doc/form/form-tip"
  114. target="_blank">标题提示 <i class="el-icon-question"></i></el-link>
  115. </template>
  116. <el-input v-model="data.labelTip"
  117. clearable
  118. placeholder="标题提示"></el-input>
  119. </el-form-item>
  120. <el-form-item v-if="data.labelTip && !['upload'].includes(data.type)"
  121. label="标题提示位置"
  122. label-width="110px">
  123. <el-select v-model="data.labelTipPlacement"
  124. placeholder="标题提示位置"
  125. clearable>
  126. <el-option label="上"
  127. value="top"></el-option>
  128. <el-option label="下"
  129. value="bottom"></el-option>
  130. <el-option label="左"
  131. value="left"></el-option>
  132. <el-option label="右"
  133. value="right"></el-option>
  134. </el-select>
  135. </el-form-item>
  136. <el-form-item v-if="!['color', 'dynamic', 'group', 'ueditor', 'upload', 'map'].includes(data.type)"
  137. label="默认值">
  138. <template v-if="defaultValues && defaultValues[data.type]">
  139. <el-select v-model="data.value"
  140. allow-create
  141. clearable
  142. filterable
  143. placeholder="默认值">
  144. <el-option v-for="item in defaultValues[data.type]"
  145. :key="item.value"
  146. :label="item.label"
  147. :value="item.value">
  148. </el-option>
  149. </el-select>
  150. </template>
  151. <template v-else>
  152. <el-input v-model="data.value"
  153. clearable
  154. placeholder="默认值"></el-input>
  155. </template>
  156. </el-form-item>
  157. <el-form-item label="详情模式">
  158. <el-switch v-model="data.detail"></el-switch>
  159. </el-form-item>
  160. <component :is="getComponent"
  161. :data="data"
  162. :default-values="defaultValues"></component>
  163. </el-collapse-item>
  164. <el-collapse-item name="2"
  165. title="事件属性"
  166. v-if="!['group'].includes(data.type)">
  167. <config-event :data="data"></config-event>
  168. </el-collapse-item>
  169. </el-collapse>
  170. </el-form>
  171. <avue-empty v-else
  172. desc="拖拽字段进行配置"
  173. style="margin-top: 100%;"></avue-empty>
  174. </div>
  175. </template>
  176. <script>
  177. import fields from './fieldsConfig.js'
  178. const dateArr = [
  179. 'year', 'month', 'week', 'date', 'datetime', 'time', 'daterange', 'timerange', 'datetimerange', 'dates'
  180. ]
  181. export default {
  182. name: 'widget-config',
  183. props: ['data', 'defaultValues'],
  184. computed: {
  185. getComponent() {
  186. const prefix = 'config-'
  187. const { type, component } = this.data
  188. if ((!type || component) && type != 'ueditor') return prefix + 'custom'
  189. let result = 'input'
  190. if ([undefined, 'input', 'password', 'url'].includes(type)) result = 'input'
  191. else if (dateArr.includes(type)) result = 'date'
  192. else if (['array', 'img'].includes(type)) result = 'array'
  193. else if (['tree', 'cascader'].includes(type)) result = 'tree'
  194. else if (['radio', 'checkbox', 'select'].includes(type)) result = 'select'
  195. else result = type
  196. return prefix + result
  197. }
  198. },
  199. data() {
  200. return {
  201. fields,
  202. collapse: ['1', '2']
  203. }
  204. },
  205. methods: {
  206. async handleChangeType(type) {
  207. if (type) {
  208. const config = await this.getConfigByType(type);
  209. config.prop = this.data.prop;
  210. for (let key in config) {
  211. if (config && Object.prototype.hasOwnProperty.call(config, key) && !['icon', 'label', 'span'].includes(key)) {
  212. const val = config[key]
  213. this.$set(this.data, key, val);
  214. }
  215. }
  216. }
  217. },
  218. getConfigByType(type) {
  219. return new Promise((resolve, reject) => {
  220. fields.forEach(field => {
  221. field.list.forEach(config => {
  222. if (config.type == type) resolve(config)
  223. })
  224. })
  225. reject()
  226. })
  227. }
  228. }
  229. }
  230. </script>