evan-form-item.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. <template>
  2. <view>
  3. <slot name="formItem" v-if="$slots.formItem"></slot>
  4. <view v-else class="evan-form-item-container" :class="'evan-form-item-container--'+mLabelPosition" :style="{borderWidth:border?'1rpx':0}">
  5. <view v-if="label" class="evan-form-item-container__label" :class="{showAsteriskRect:hasRequiredAsterisk,isRequired:showRequiredAsterisk}"
  6. :style="mLabelStyle">{{label}}</view>
  7. <view class="evan-form-item-container__main" :style="mContentStyle">
  8. <slot></slot>
  9. </view>
  10. </view>
  11. </view>
  12. </template>
  13. <script>
  14. export default {
  15. name: 'EvanFormItem',
  16. props: {
  17. labelStyle: Object,
  18. label: String,
  19. contentStyle: {
  20. type: Object,
  21. default: () => {
  22. return {}
  23. }
  24. },
  25. prop: String,
  26. border: {
  27. type: Boolean,
  28. default: true
  29. },
  30. labelPosition: {
  31. validator: function(value) {
  32. if (!value) {
  33. return true
  34. }
  35. return ['top', 'left'].indexOf(value) !== -1
  36. },
  37. default: ''
  38. }
  39. },
  40. computed: {
  41. mLabelStyle() {
  42. const parent = this.getParent()
  43. let labelStyle = Object.assign({}, (parent.labelStyle || {}), (this.labelStyle || {}))
  44. let arr = Object.keys(labelStyle).map((key) => `${key}:${labelStyle[key]}`)
  45. return arr.join(';')
  46. },
  47. mContentStyle() {
  48. let contentStyle = Object.assign({}, this.contentStyle || {})
  49. let arr = Object.keys(contentStyle).map((key) => `${key}:${contentStyle[key]}`)
  50. return arr.join(';')
  51. },
  52. mLabelPosition() {
  53. if (this.labelPosition) {
  54. return this.labelPosition
  55. }
  56. const parent = this.getParent()
  57. if (parent) {
  58. return parent.labelPosition
  59. }
  60. return 'left'
  61. },
  62. // 整个表单是否有*号
  63. hasRequiredAsterisk() {
  64. const parent = this.getParent()
  65. if (parent) {
  66. return parent.hasRequiredAsterisk
  67. }
  68. return false
  69. },
  70. // 当前formItem是否显示*号
  71. showRequiredAsterisk() {
  72. const parent = this.getParent()
  73. if (parent && parent.hideRequiredAsterisk) {
  74. return false
  75. }
  76. const rules = this.getRules()
  77. if (rules && rules.length > 0) {
  78. if (rules.find((rule) => rule.required === true)) {
  79. return true
  80. }
  81. }
  82. return false
  83. }
  84. },
  85. methods: {
  86. // 获取EvanForm组件
  87. getParent() {
  88. let parent = this.$parent
  89. let parentName = parent.$options.name
  90. while (parentName !== 'EvanForm') {
  91. parent = parent.$parent
  92. parentName = parent.$options.name
  93. }
  94. return parent
  95. },
  96. getRules() {
  97. let form = this.getParent()
  98. let formRules = form.mRules;
  99. formRules = formRules ? formRules[this.prop] : [];
  100. return [].concat(formRules || []);
  101. }
  102. }
  103. }
  104. </script>
  105. <style lang="scss">
  106. .evan-form-item-container {
  107. border-bottom: 1rpx solid #eee;
  108. &__label {
  109. font-size: 28rpx;
  110. color: #666;
  111. line-height: 40rpx;
  112. padding: 25rpx 0;
  113. display: inline-block;
  114. &.showAsteriskRect::before {
  115. content: '';
  116. color: #F56C6C;
  117. width: 30rpx;
  118. display: inline-block;
  119. }
  120. &.isRequired::before {
  121. content: '*';
  122. }
  123. }
  124. &__main {
  125. flex: 1;
  126. min-height: 90rpx;
  127. display: flex;
  128. align-items: center;
  129. overflow: hidden;
  130. }
  131. &--left {
  132. display: flex;
  133. flex-direction: row;
  134. align-items: flex-start;
  135. }
  136. &--top {
  137. .evan-form-item-container__label {
  138. padding-bottom: 10rpx;
  139. }
  140. }
  141. }
  142. </style>