1、效果

  1. ![屏幕录制 2020-09-09 下午3.10.42.gif](https://cdn.nlark.com/yuque/0/2020/gif/1225858/1599635641518-19897994-26b6-4eba-822c-42e5a950e04a.gif#align=left&display=inline&height=365&margin=%5Bobject%20Object%5D&name=%E5%B1%8F%E5%B9%95%E5%BD%95%E5%88%B6%202020-09-09%20%E4%B8%8B%E5%8D%883.10.42.gif&originHeight=365&originWidth=200&size=592116&status=done&style=none&width=200)

2、参数

参数 说明 默认
visible 是否打开 默认false
dataSource 数据源 { label: ‘标签一’, id: 1 },
{ label: ‘标签二’, id: 2 },
currentId 当前选增的标签id 1
classname 样式类 ‘ll’
clickMastClose 是否支持点击遮罩关闭 false

事件

handleCancel 点击取消触发的事件
handleChoose 切换标签的选中事件

3、使用

  1. import ModalList from './components/ModalList'
  2. ...
  3. components: {
  4. ModalList
  5. }
  6. ...
  7. <modal-list
  8. :visible.sync="visible"
  9. :dataSource="this.dataSource"
  10. :currentId="this.currentId"
  11. @handleChoose="handleChoose"
  12. >
  13. </modal-list>

4、组件源码

  1. <template>
  2. <div :class="classname" class="modal-list-wrapper" v-show="visible">
  3. <div class="mask" />
  4. <div class="list-wrapper" :class="visible ? 'active-entry' : 'active-out'">
  5. <ul class="list-ul">
  6. <li
  7. v-for="item in this.dataSource"
  8. :key="item.id"
  9. class="list-li"
  10. :style="currentId === item.id && 'color:#0082FF'"
  11. @click="handleChoose(item)"
  12. >
  13. {{ item.label }}
  14. </li>
  15. </ul>
  16. <div class="cancel" @click="cancel">{{ cancelText }}</div>
  17. </div>
  18. </div>
  19. </template>
  20. <script>
  21. import Vue from 'vue';
  22. export default Vue.extend({
  23. name: 'ModalList',
  24. props: {
  25. classname: {
  26. default: 'll',
  27. type: String,
  28. },
  29. dataSource: {
  30. default: () => [
  31. { label: '标签一', id: 1 },
  32. { label: '标签二', id: 2 },
  33. ],
  34. type: Array,
  35. },
  36. currentId: {
  37. default: 1,
  38. type: Number,
  39. },
  40. cancelText: {
  41. default: '取消',
  42. type: String,
  43. },
  44. visible: {
  45. type: Boolean,
  46. default: false,
  47. },
  48. },
  49. data() {
  50. return {};
  51. },
  52. watch: {},
  53. methods: {
  54. cancel: function () {
  55. this.$emit('update:visible', false);
  56. },
  57. handleChoose: function (item) {
  58. this.$emit('handleChoose', item);
  59. },
  60. open: function () {
  61. setTimeout(() => {
  62. this.visible = true;
  63. }, 1000);
  64. },
  65. },
  66. })
  67. </script>
  68. <style lang="scss" scoped>
  69. .modal-list-wrapper {
  70. .mask {
  71. position: fixed;
  72. top: 0px;
  73. left: 0px;
  74. right: 0px;
  75. bottom: 0px;
  76. background-color: rgba(0, 0, 0, 0.6);
  77. z-index: 99;
  78. }
  79. .list-wrapper {
  80. position: fixed;
  81. bottom: -180px;
  82. width: 100%;
  83. z-index: 100;
  84. padding: 0px 8px;
  85. // transition: all 3s;
  86. box-sizing: border-box;
  87. .list-ul {
  88. width: 100%;
  89. max-height: 300px;
  90. overflow: auto;
  91. list-style: none;
  92. border-radius: 8px;
  93. .list-li {
  94. width: 100%;
  95. background: #fff;
  96. height: 56px;
  97. line-height: 56px;
  98. text-align: center;
  99. border-bottom: 1px solid #e5e5e5;
  100. &:last-of-type {
  101. border-bottom: none;
  102. }
  103. }
  104. }
  105. .cancel {
  106. border-radius: 8px;
  107. background: #fff;
  108. margin-top: 8px;
  109. height: 56px;
  110. line-height: 56px;
  111. text-align: center;
  112. }
  113. }
  114. .active-entry {
  115. animation: slideIn 0.3s ease forwards;
  116. }
  117. .active-out {
  118. animation: slideOut 0.3s ease forwards;
  119. }
  120. @keyframes slideIn {
  121. 0% {
  122. transform translate3d(0, 0, 0);
  123. }
  124. 100% {
  125. transform translate3d(0, -115%, 0);
  126. }
  127. }
  128. @keyframes slideOut {
  129. 0% {
  130. transform translate3d(0, -115%, 0);
  131. }
  132. 100% {
  133. transform translate3d(0, 0, 0);
  134. }
  135. }
  136. }
  137. </style>