tm-rate.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <template>
  2. <view class="tm-rate d-inline-block">
  3. <view @touchstart="ishover=false" @touchend="ishover=disabled?false:true" v-for="(item,index) in num" :key="index" class="d-inline-block" :class="[ishover&&index+1==indexStar?'ani':'','pr-'+margin]">
  4. <tm-icons :black="black_tmeme" dense @click="clicSelect(index+1)" :size="size" :color="index+1 <= indexStar?color_tmeme:uncolor"
  5. :name="icon"></tm-icons>
  6. </view>
  7. <slot name="default" :num="num"><text v-if="showNum" :class="['text-'+color_tmeme]">{{indexStar}}</text></slot>
  8. </view>
  9. </template>
  10. <script>
  11. /**
  12. * 评分
  13. * @property {String} color = [] 默认:primary,选中的颜色
  14. * @property {String} uncolor = [] 默认:grey-lighten-2,未选中的颜色
  15. * @property {Number} num = [] 默认:5,数量
  16. * @property {Number} value = [] 默认:0,当前的评分,推荐:value.sync或者v-model.
  17. * @property {Number} size = [] 默认:32,单位upx,图标大小。
  18. * @property {Number} margin = [] 默认:16,单位upx,间隙。
  19. * @property {Boolean} disabled = [] 默认:false,是否禁用。
  20. * @property {Boolean} black = [] 默认:null,暗黑模式。
  21. * @property {Boolean} show-num = [] 默认:false,是否展示评分数字。
  22. * @property {Boolean} icon = [] 默认:icon-collection-fill,图片名称,可以自定义其它的。
  23. * @property {String} name = [] 默认:'',提交表单时的的字段名称标识
  24. * @property {Function} change 评分改变时触发,参数当前的评分。
  25. */
  26. import tmIcons from "@/tm-vuetify/components/tm-icons/tm-icons.vue"
  27. export default {
  28. components:{tmIcons},
  29. name: "tm-rate",
  30. model: {
  31. prop: "value",
  32. event: "input"
  33. },
  34. props: {
  35. //提交表单时的的字段名称
  36. name:{
  37. type:String,
  38. default:''
  39. },
  40. color: {
  41. type: String,
  42. default: "primary"
  43. },
  44. uncolor: {
  45. type: String,
  46. default: "grey-lighten-2"
  47. },
  48. black:{
  49. type:Boolean|String,
  50. default:null
  51. },
  52. num: {
  53. type: Number,
  54. default: 5
  55. },
  56. value: {
  57. type: Number,
  58. default: 0
  59. },
  60. size: {
  61. type: Number,
  62. default: 42
  63. },
  64. margin: {
  65. type: Number,
  66. default: 16
  67. },
  68. disabled: {
  69. type: Boolean,
  70. default: false
  71. },
  72. showNum:{
  73. type: Boolean,
  74. default: false
  75. },
  76. icon:{
  77. type: String,
  78. default: 'icon-collection-fill'
  79. },
  80. // 跟随主题色的改变而改变。
  81. fllowTheme:{
  82. type:Boolean|String,
  83. default:true
  84. }
  85. },
  86. computed: {
  87. black_tmeme:function(){
  88. if(this.black!==null) return this.black;
  89. return this.$tm.vx.state().tmVuetify.black;
  90. },
  91. color_tmeme:function(){
  92. if(this.$tm.vx.state().tmVuetify.color!==null&&this.$tm.vx.state().tmVuetify.color && this.fllowTheme){
  93. return this.$tm.vx.state().tmVuetify.color;
  94. }
  95. return this.color;
  96. },
  97. indexStar: {
  98. get: function() {
  99. return this.value;
  100. },
  101. set: function(val) {
  102. let dval = val;
  103. if(val > this.num) dval = this.num;
  104. this.$emit("input",val)
  105. this.$emit("update:value",val)
  106. this.$emit("change",val)
  107. }
  108. }
  109. },
  110. data() {
  111. return {
  112. ishover:false,
  113. };
  114. },
  115. methods: {
  116. clicSelect(index) {
  117. if (this.disabled) return;
  118. this.indexStar = index;
  119. }
  120. },
  121. }
  122. </script>
  123. <style lang="scss" scoped>
  124. .tm-rate{
  125. .ani {
  126. animation: ani 0.2s linear;
  127. }
  128. }
  129. @keyframes ani {
  130. 0% {
  131. transform: scale(0.85)
  132. }
  133. 50% {
  134. transform: scale(1.2)
  135. }
  136. 100% {
  137. transform: scale(0.85)
  138. }
  139. }
  140. </style>