u-sidebar.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <template>
  2. <view class="u-sidebar" :style="[sidebarStyle]">
  3. <slot></slot>
  4. </view>
  5. </template>
  6. <script>
  7. import props from './props.js';
  8. import mixin from '../../libs/mixin/mixin'
  9. import mpMixin from '../../libs/mixin/mpMixin';
  10. /**
  11. * Sidebar 侧边栏
  12. * @description 垂直展示的导航栏,用于在不同的内容区域之间进行切换
  13. * @tutorial https://uview.d3u.cn/components/sidebar.html
  14. *
  15. * @property {Number | String} value 当前导航项的索引
  16. * @property {Number | String} modelValue Vue3模式下当前导航项的索引
  17. * @property {String} width 宽度
  18. * @property {String} fontSize 字体大小
  19. * @property {String} lineHeight 行高
  20. * @property {String} textColor 文本颜色
  21. * @property {String} disabledColor 禁用文本颜色
  22. * @property {String} disabledBgColor 禁用背景颜色
  23. * @property {String} bgColor 背景色
  24. * @property {String} activeColor 激活时文本颜色
  25. * @property {String} activeBgColor 激活时背景颜色
  26. * @property {Boolean} activeBold 激活时是否加粗
  27. * @property {String | Object} activeStyle 激活时的样式
  28. * @property {String | Object} inactiveStyle 非激活时的样式
  29. * @property {String | Number} lineWidth 滑块长度
  30. * @property {String | Number} lineHeight 滑块高度
  31. * @property {String} lineColor 滑块颜色
  32. * @property {String} lineBgSize 滑块背景显示大小,当滑块背景设置为图片时使用
  33. * @property {Boolean} showLine 是否显示滑块
  34. *
  35. * @event {Function(Object)} change 切换导航项时触发,返回包含index、label、value的对象
  36. * @example
  37. * <u-sidebar v-model="current" :width="'200px'" :fontSize="'16px'">
  38. * <u-sidebar-item label="标签名称" badge="5" />
  39. * </u-sidebar>
  40. */
  41. export default {
  42. name: 'u-sidebar',
  43. mixins: [mpMixin, mixin, props],
  44. data() {
  45. return {
  46. innerCurrent: 0
  47. }
  48. },
  49. watch: {
  50. value: {
  51. immediate: true,
  52. handler(newValue) {
  53. if (newValue !== this.innerCurrent) {
  54. this.innerCurrent = parseInt(newValue) || 0
  55. this.updateChildData()
  56. }
  57. }
  58. },
  59. // #ifdef VUE3
  60. modelValue: {
  61. immediate: true,
  62. handler(newValue) {
  63. if (newValue !== this.innerCurrent) {
  64. this.innerCurrent = parseInt(newValue) || 0
  65. this.updateChildData()
  66. }
  67. }
  68. }
  69. // #endif
  70. },
  71. computed: {
  72. sidebarStyle() {
  73. const style = {}
  74. if (this.width) style.width = this.$u.addUnit(this.width)
  75. if (this.fontSize) style.fontSize = this.$u.addUnit(this.fontSize)
  76. if (this.lineHeight) style.lineHeight = this.$u.addUnit(this.lineHeight)
  77. if (this.bgColor) style.backgroundColor = this.bgColor
  78. return style
  79. },
  80. // 监听参数的变化,通过watch中,手动去更新子组件的数据,否则子组件不会自动变化
  81. parentData() {
  82. return [
  83. this.innerCurrent,
  84. this.width,
  85. this.fontSize,
  86. this.lineHeight,
  87. this.textColor,
  88. this.disabledColor,
  89. this.disabledBgColor,
  90. this.bgColor,
  91. this.activeColor,
  92. this.activeBgColor,
  93. this.activeBold,
  94. this.activeStyle,
  95. this.inactiveStyle,
  96. this.lineWidth,
  97. this.lineHeight,
  98. this.lineColor,
  99. this.lineBgSize,
  100. this.showLine
  101. ]
  102. }
  103. },
  104. created() {
  105. this.children = []
  106. },
  107. // #ifdef VUE3
  108. emits: ["update:modelValue", "change"],
  109. // #endif
  110. methods: {
  111. init() {
  112. // 当某个子组件内容变化时,触发父组件的init,父组件再让每一个子组件重新初始化一遍
  113. // 以保证数据的正确性
  114. this.children.map(child => {
  115. child.init();
  116. })
  117. },
  118. // 更新子组件的数据
  119. updateChildData() {
  120. this.children.map(child => {
  121. uni.$u.test.func((child || {}).updateFromParent) && child.updateFromParent()
  122. })
  123. },
  124. // 处理子组件点击
  125. handleItemClick(index) {
  126. const child = this.children[index]
  127. if (child && !child.disabled) {
  128. this.innerCurrent = index
  129. // #ifdef VUE2
  130. this.$emit('input', index)
  131. // #endif
  132. // #ifdef VUE3
  133. this.$emit('update:modelValue', index)
  134. // #endif
  135. this.$emit('change', {
  136. index: index,
  137. label: child.label,
  138. value: child.value
  139. })
  140. this.updateChildData()
  141. }
  142. }
  143. }
  144. }
  145. </script>
  146. <style lang="scss" scoped>
  147. .u-sidebar {
  148. }
  149. </style>