fab/fab.vue

  1. <template>
  2. <div class="ion-fab" :style="styleObj">
  3. <slot></slot>
  4. </div>
  5. </template>
  6. <style lang="scss" src="./style.scss"></style>
  7. <script type="text/javascript">
  8. /**
  9. * @component Fab
  10. * @description
  11. *
  12. * ## 浮层组件 / FAB浮动按钮组件
  13. *
  14. * ### 简介
  15. *
  16. * FAB是Floating Action Buttons的缩写, 表示浮动按钮组件, 点击主按钮展开附属按钮用于选择操作. FAB组件悬浮在Content组件之上, 不随着内容滚动而变动位置.
  17. *
  18. * ### 组件关闭
  19. *
  20. * 组件关闭需要自己手动执行, 页面切换对关闭不起作用(只有弹出层对 popstate 有动作)
  21. *
  22. * ### 其他
  23. *
  24. * FAB可在四个方向展开, 此外, FAB可以放置在6中不同位置. 详情参考Demo. 另外, 为了保证组件悬浮在Content组件之上, `slot="fixed"` 属性不要忘记添加.
  25. *
  26. * ### 如何引入
  27. * ```
  28. * // 引入
  29. * import { Fab, FabButton, FabList } from 'vimo'
  30. * // 安装
  31. * Vue.component(Fab.name, Fab)
  32. * Vue.component(FabButton.name, FabButton)
  33. * Vue.component(FabList.name, FabList)
  34. * // 或者
  35. * export default{
  36. * components: {
  37. * Fab, FabButton, FabList
  38. * }
  39. * }
  40. * ```
  41. *
  42. * @usage
  43. * <Fab slot="fixed" bottom right ref="fab5">
  44. * <FabButton color="dark">
  45. * <Icon name="arrow-dropleft"></Icon>
  46. * </FabButton>
  47. * <FabList side="left">
  48. * <FabButton @click="clickHandler('facebook')" color="danger">
  49. * <Icon name="logo-facebook"></Icon>
  50. * </FabButton>
  51. * <FabButton @click="clickHandler('googleplus')" color="secondary">
  52. * <Icon name="logo-googleplus"></Icon>
  53. * </FabButton>
  54. * <FabButton @click="clickHandler('twitter')" color="dark">
  55. * <Icon name="logo-twitter"></Icon>
  56. * </FabButton>
  57. * <FabButton @click="clickHandler('vimeo')" color="primary">
  58. * <Icon name="logo-vimeo"></Icon>
  59. * </FabButton>
  60. * </FabList>
  61. * </Fab>
  62. *
  63. *
  64. * @props {Boolean} [top] - 设置放置位置
  65. * @props {Boolean} [bottom] - 设置放置位置
  66. * @props {Boolean} [left] - 设置放置位置
  67. * @props {Boolean} [right] - 设置放置位置
  68. * @props {Boolean} [middle] - 设置放置位置
  69. * @props {Boolean} [center] - 设置放置位置
  70. * @props {Boolean} [edge] - 设置放置位置, 放在Header/Footer组件与Content组件交界处
  71. * @props {Boolean} [fabContentMargin=10] - 靠边的距离, 默认是1opx
  72. *
  73. *
  74. * @demo #/fab
  75. * */
  76. import { parsePxUnit } from '../../util/util'
  77. export default {
  78. name: 'Fab',
  79. provide () {
  80. let _this = this
  81. return {
  82. fabComponent: _this
  83. }
  84. },
  85. data () {
  86. return {
  87. listsActive: false, // 组件开闭状态
  88. fabListComponents: [], // FabList 组件
  89. styleObj: {}
  90. }
  91. },
  92. props: {
  93. top: Boolean,
  94. bottom: Boolean,
  95. left: Boolean,
  96. right: Boolean,
  97. middle: Boolean,
  98. center: Boolean,
  99. edge: Boolean,
  100. fabContentMargin: {
  101. type: Number,
  102. default: 10
  103. }
  104. },
  105. methods: {
  106. /**
  107. * @private
  108. */
  109. $_toggleList () {
  110. this.$app && this.$app.setEnabled(false, 300)
  111. this.$_setActiveLists(!this.listsActive)
  112. },
  113. /**
  114. * @param {Boolean} isActive
  115. * @private
  116. */
  117. $_setActiveLists (isActive) {
  118. if (isActive === this.listsActive) {
  119. return
  120. }
  121. for (let list of this.fabListComponents) {
  122. list.$_setVisible(isActive)
  123. }
  124. this.listsActive = isActive
  125. },
  126. /**
  127. * 尺寸计算
  128. * @private
  129. * */
  130. $_setPosition () {
  131. let fabContentMargin = this.fabContentMargin
  132. let fabSize = parsePxUnit(window.getComputedStyle(this.$el).height)
  133. let style = {}
  134. if (this.top) {
  135. style.top = `${fabContentMargin}px`
  136. if (this.edge) {
  137. style.top = `${-fabSize / 2}px`
  138. }
  139. }
  140. if (this.bottom) {
  141. style.bottom = `${fabContentMargin}px`
  142. if (this.edge) {
  143. style.bottom = `${-fabSize / 2}px`
  144. }
  145. }
  146. if (this.left) {
  147. style.left = `${fabContentMargin}px`
  148. }
  149. if (this.right) {
  150. style.right = `${fabContentMargin}px`
  151. }
  152. if (this.center) {
  153. style.left = '50%'
  154. style.marginLeft = `${-fabSize / 2}px`
  155. }
  156. if (this.middle) {
  157. style.top = '50%'
  158. style.marginLeft = `${-fabSize / 2}px`
  159. style.position = 'fixed'
  160. }
  161. return style
  162. },
  163. /**
  164. * @function close
  165. * @description
  166. * 关闭组件, 通过ref获组件示例. 一般点击主按钮关闭组件
  167. * */
  168. close () {
  169. this.$_setActiveLists(false)
  170. }
  171. },
  172. mounted () {
  173. this.styleObj = this.$_setPosition()
  174. }
  175. }
  176. </script>