graceSelectMenu.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <template>
  2. <view class="grace-select-menu-wrap">
  3. <view class="grace-select-menu-title" @click.stop="showMenu" id="menuMain">
  4. <text :style="{fontSize:fontSize}">{{items[currentIndex]}}</text>
  5. <text class="grace-select-menu-icon icon-allow-b" v-if="!show"></text>
  6. <text class="grace-select-menu-icon icon-allow-t" v-if="show"></text>
  7. </view>
  8. <view class="grace-select-menu" :style="{top : top +'px', height:heightIn+'px', zIndex:zIndex}" @click.stop="close" @touchmove.stop.prevent="" v-if="show">
  9. <view style="height:92rpx; width:100%; flex-shrink:0;"></view>
  10. <scroll-view scroll-y class="grace-select-menus" :style="{padding:padding}">
  11. <view @tap.stop="" class="grace-select-item" v-if="isInput"
  12. style="display:flex; flex-direction:row; flex-wrap:nowrap; align-items:center;">
  13. <view class="grace-select-input-wrap">
  14. <input type="text" v-model="inputVal" class="grace-select-input" @confirm="addTag" :placeholder="placeholder" />
  15. </view>
  16. <view class="grace-select-input-btn" @tap.stop="addTag">{{addBtnName}}</view>
  17. </view>
  18. <view :class="['grace-select-item', index == currentIndex ? 'grace-selected' : '']"
  19. v-for="(item, index) in items" :style="{color : index == currentIndex ? activeColor : color}"
  20. :key="index" :data-index="index" @click.stop="select">
  21. <text class="grace-selected-icon" v-if="index == currentIndex"></text>
  22. <text :style="{fontSize:fontSize}">{{item}}</text>
  23. </view>
  24. <view style="height:100rpx; width:100%"></view>
  25. </scroll-view>
  26. </view>
  27. </view>
  28. </template>
  29. <script scoped>
  30. export default {
  31. props:{
  32. items : {
  33. type : Array,
  34. default : function () { return [] }
  35. },
  36. show : {
  37. type : Boolean,
  38. default : false
  39. },
  40. height : {
  41. type : Number,
  42. default : 300
  43. },
  44. color : {
  45. type : String,
  46. default : "#333333"
  47. },
  48. activeColor : {
  49. type : String,
  50. default : "#3688FF"
  51. },
  52. selectIndex : {
  53. type : Number,
  54. default : 0
  55. },
  56. isH5header : {
  57. type : Boolean,
  58. default : true
  59. },
  60. fontSize : {
  61. type : String,
  62. default : '26rpx'
  63. },
  64. padding:{
  65. type : String,
  66. default : "0 20rpx"
  67. },
  68. zIndex:{
  69. type : Number,
  70. default : 9999
  71. },
  72. isInput:{type:Boolean, default:false},
  73. placeholder:{type:String, default:"自定义"},
  74. addBtnName:{type:String, default:"+ 添加"}
  75. },
  76. data() {
  77. return {
  78. currentIndex : 0,
  79. top : 0,
  80. heightIn : 200,
  81. showRes : [],
  82. inputVal : ''
  83. }
  84. },
  85. watch:{
  86. selectIndex : function () {
  87. this.currentIndex = this.selectIndex;
  88. }
  89. },
  90. created : function () {
  91. this.currentIndex = this.selectIndex;
  92. },
  93. methods:{
  94. showMenu:function () {
  95. uni.createSelectorQuery().in(this).select('#menuMain').fields(
  96. {rect: true}, (res) => {
  97. var system = uni.getSystemInfoSync();
  98. var wHeight = system.windowHeight;
  99. this.top = res.top;
  100. this.heightIn = wHeight - this.top;
  101. // #ifdef H5
  102. if(this.isH5header){
  103. this.top += 44;
  104. this.heightIn -= 44;
  105. }
  106. // #endif
  107. }
  108. ).exec();
  109. this.$emit('showMenu');
  110. },
  111. close : function(){
  112. this.$emit('close');
  113. },
  114. select : function(e){
  115. var index = Number(e.currentTarget.dataset.index);
  116. this.currentIndex = index;
  117. this.$emit('select', index);
  118. this.close();
  119. },
  120. addTag : function () {
  121. if(this.inputVal == ''){return ;}
  122. this.$emit('submit', this.inputVal);
  123. this.inputVal = '';
  124. }
  125. }
  126. }
  127. </script>
  128. <style>
  129. .grace-select-menu-wrap{width:100%; position:relative;}
  130. .grace-select-menu-title{height:90rpx; line-height:90rpx; font-size:28rpx; color:#333333; width:100%; text-align:center; overflow:hidden;}
  131. .grace-select-menu-icon{font-family:"grace-iconfont"; margin-left:10rpx; font-size:22rpx;}
  132. .icon-allow-b:after{content:"\e603";}
  133. .icon-allow-t:after{content:"\e654";}
  134. .grace-select-menu{position:fixed; width:750rpx; left:0; top:0; box-sizing:border-box; z-index:9999; overflow:hidden; display:flex; flex-direction:column;}
  135. .grace-select-menus{background:#FFFFFF; padding:0; height:300px; flex:1;}
  136. .grace-select-item{line-height:100rpx; width:700rpx; padding:0 10rpx; font-size:28rpx; color:#333333; border-bottom:1px solid #F8F8F8;}
  137. .grace-select-item:last-child{border:0;}
  138. .grace-selected{font-weight:bold;}
  139. .grace-selected-icon{margin-right:15rpx; font-family:"grace-iconfont";}
  140. .grace-selected-icon:after{content:"\e7f8";}
  141. .grace-select-input-wrap{width:700rpx;}
  142. .grace-select-input{line-height:60rpx; padding:25rpx 0; font-size:28rpx;}
  143. .grace-select-input-btn{width:120rpx; line-height:60rpx; height:60rpx; text-align:center; background:#F8F8F8; font-size:24rpx; border-radius:6rpx; color:#3688FF; flex-shrink:0;}
  144. </style>