猫妈狗爸伴宠师小程序前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
4.3 KiB

3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
  1. <template>
  2. <up-form label-position="left" :model="formData" :rules="rules" ref="dFormRef">
  3. <div class="form-item" v-for="item in list" :key="item.key">
  4. <up-form-item :label="item.label" :prop="item.key" @click="item.type==='select'&&open(item)"
  5. :labelStyle="{fontSize:'28rpx'}" :labelWidth="labelWidth" class="item">
  6. <template v-if="item.type==='input'">
  7. <div class="flex-rowr">
  8. <up-input inputAlign="right" v-model="formData[item.key]" :placeholder="item.placeholder"
  9. border="none" fontSize='28rpx'></up-input><text
  10. class="ml10">{{item.unit?item.unit:""}}</text>
  11. </div>
  12. </template>
  13. <template v-else-if="item.type==='select'">
  14. <up-input inputAlign="right" :value="getDesc(formData[item.key], item.options)" disabled disabledColor="#ffffff"
  15. :placeholder="item.placeholder" border="none">
  16. <template #suffix>
  17. <up-icon name="arrow-right" color="#999999" size="32rpx"></up-icon>
  18. </template>
  19. </up-input>
  20. </template>
  21. <template v-else-if="item.type==='radio'">
  22. <up-radio-group v-model="formData[item.key]" placement="column">
  23. <div class="flex-rowr">
  24. <up-radio class="mr16" activeColor="#FFBF60" :customStyle="{marginBottom: '8px'}"
  25. v-for="option in item.options" :key="option.value" :label="option.name" :name="option.value">
  26. </up-radio>
  27. </div>
  28. </up-radio-group>
  29. </template>
  30. <template v-else-if="item.type==='textarea'">
  31. <up-textarea v-model="formData[item.key]" :placeholder="item.placeholder" count autoHeight
  32. :maxlength="item.maxlength"></up-textarea>
  33. </template>
  34. <template v-else-if="item.type==='upload'">
  35. <up-upload :fileList="item.fileList" @afterRead="afterRead" @delete="deletePic" name="1"
  36. :multiple="item.multiple" :maxCount="item.maxCount" :accept='item.accept'
  37. :previewFullImage="item.previewFullImage"></up-upload>
  38. </template>
  39. <template v-else>
  40. <view>
  41. <slot :name="item.key"></slot>
  42. </view>
  43. </template>
  44. </up-form-item>
  45. <slot :name="`${item.key}-extend`"></slot>
  46. </div>
  47. <up-button @click="handleSubmit" class="mt20" type="warning" v-if="isFooter">提交</up-button>
  48. </up-form>
  49. <up-action-sheet :show="sheet.show" :actions="sheet.actions" :title="sheet.title" :description="sheet.description"
  50. @close="sheetClose" @select="handleSelect">
  51. </up-action-sheet>
  52. </template>
  53. <script setup>
  54. import {
  55. reactive,
  56. ref,
  57. computed,
  58. watch,
  59. } from "vue"
  60. const {
  61. list,
  62. labelWidth
  63. } = defineProps({
  64. list: {
  65. type: Array,
  66. default: () => []
  67. },
  68. labelWidth: {
  69. type: String,
  70. default: "200rpx"
  71. },
  72. isFooter: true
  73. })
  74. const emit = defineEmits(['submit', 'input'])
  75. const formData = reactive({
  76. name: ""
  77. })
  78. watch(formData, (val) => {
  79. emit('input', val)
  80. })
  81. const sheet = reactive({
  82. show: false,
  83. key: null,
  84. actions: [],
  85. title: "",
  86. description: ""
  87. })
  88. // 设置校验
  89. const rules = computed(() => {
  90. const obj = {}
  91. list.forEach(item => {
  92. if (item.rule && item.rule.length > 0)
  93. obj[item.key] = [...item.rule]
  94. })
  95. return obj
  96. })
  97. // 开启弹框
  98. const open = (item) => {
  99. sheet.show = true
  100. sheet.key = item.key
  101. sheet.actions = item.options
  102. sheet.title = item.placeholder
  103. sheet.description = item.description || ""
  104. }
  105. // 关闭弹框
  106. const sheetClose = () => {
  107. sheet.show = false
  108. }
  109. // 选择
  110. const handleSelect = (val) => {
  111. formData[sheet.key] = val?.value
  112. }
  113. const getDesc = (val, options) => {
  114. return options.find(item => item.value === val)?.name
  115. }
  116. // 上传
  117. const afterRead = () => {}
  118. // 删除上传文件
  119. const deletePic = () => {}
  120. const dFormRef = ref(null)
  121. // 提交
  122. const handleSubmit = () => {
  123. dFormRef.value.validate().then(valid => {
  124. if (valid) {
  125. submit(formData)
  126. }
  127. })
  128. }
  129. const setDataByKey = (key, value) => {
  130. formData[key] = value || null
  131. }
  132. const setData = (data) => {
  133. list.forEach(item => {
  134. const { key } = item
  135. formData[key] = data[key] || null
  136. })
  137. }
  138. const getData = () => {
  139. return formData
  140. }
  141. const validate = () => {
  142. return dFormRef.value.validate()
  143. }
  144. defineExpose({ setDataByKey, setData, getData, validate })
  145. </script>
  146. <style>
  147. .form-item {
  148. min-height: 90rpx;
  149. padding-top: 10rpx;
  150. width: 100%;
  151. border-bottom: 1rpx solid #f5f5f5;
  152. }
  153. .flex-rowr {
  154. display: flex;
  155. justify-content: flex-end;
  156. align-items: center;
  157. }
  158. .ml10 {
  159. margin-left: 10rpx;
  160. }
  161. </style>