Browse Source

feat: taro rate

richard1015 4 years ago
parent
commit
1950dc9499

+ 1 - 0
src/config.json

@@ -542,6 +542,7 @@
         {
           "version": "3.0.0",
           "name": "Rate",
+          "taro": true,
           "sort": 4,
           "cName": "评分",
           "type": "component",

+ 114 - 0
src/packages/__VUE/rate/index.taro.vue

@@ -0,0 +1,114 @@
+<template>
+  <view :class="classes">
+    <view
+      class="nut-rate-item"
+      v-for="n in count"
+      :key="n"
+      :style="{ marginRight: pxCheck(spacing) }"
+    >
+      <nut-icon
+        :size="iconSize"
+        class="nut-rate-item__icon"
+        @click="onClick(1, n)"
+        :class="{ 'nut-rate-item__icon--disabled': disabled || n > modelValue }"
+        :color="n <= modelValue ? activeColor : voidColor"
+        :name="n <= modelValue ? checkedIcon : uncheckedIcon"
+      />
+      <nut-icon
+        v-if="allowHalf && modelValue + 1 > n"
+        class="nut-rate-item__icon nut-rate-item__icon--half"
+        @click="onClick(2, n)"
+        :color="n <= modelValue ? activeColor : voidColor"
+        :size="iconSize"
+        :name="checkedIcon"
+      />
+    </view>
+  </view>
+</template>
+<script lang="ts">
+import { computed } from 'vue';
+import { createComponent } from '@/packages/utils/create';
+import { pxCheck } from '@/packages/utils/pxCheck';
+const { componentName, create } = createComponent('rate');
+import Taro from '@tarojs/taro';
+export default create({
+  props: {
+    count: {
+      type: [String, Number],
+      default: 5
+    },
+    modelValue: {
+      type: [String, Number],
+      default: 0
+    },
+    iconSize: {
+      type: [String, Number],
+      default: 18
+    },
+    activeColor: {
+      type: String,
+      default: ''
+    },
+    voidColor: {
+      type: String,
+      default: ''
+    },
+    uncheckedIcon: {
+      type: String,
+      default: 'star-n'
+    },
+    checkedIcon: {
+      type: String,
+      default: 'star-fill-n'
+    },
+    readonly: {
+      type: Boolean,
+      default: false
+    },
+    disabled: {
+      type: Boolean,
+      default: false
+    },
+    allowHalf: {
+      type: Boolean,
+      default: false
+    },
+    spacing: {
+      type: [String, Number],
+      default: 14
+    }
+  },
+  emits: ['update:modelValue', 'change'],
+  setup(props, { emit }) {
+    const classes = computed(() => {
+      const prefixCls = componentName;
+      return {
+        [prefixCls]: true
+      };
+    });
+    const onClick = (e: number, index: number) => {
+      if (props.disabled || props.readonly) return;
+      let value = 0;
+      if (index === 1 && props.modelValue === index) {
+      } else {
+        value = index;
+        if (props.allowHalf && e == 2) {
+          value -= 0.5;
+        }
+      }
+      emit('update:modelValue', value);
+      emit('change', value);
+    };
+
+    return {
+      classes,
+      onClick,
+      pxCheck
+    };
+  }
+});
+</script>
+
+<style lang="scss">
+@import 'index.scss';
+</style>

+ 1 - 0
src/sites/mobile-taro/vue/src/app.config.ts

@@ -1,5 +1,6 @@
 export default {
   pages: [
+    'pages/rate/index',
     'pages/collapse/index',
     'pages/shortpassword/index',
     'pages/textarea/index',

+ 3 - 0
src/sites/mobile-taro/vue/src/pages/rate/index.config.ts

@@ -0,0 +1,3 @@
+export default {
+  navigationBarTitleText: 'Rate'
+};

+ 63 - 0
src/sites/mobile-taro/vue/src/pages/rate/index.vue

@@ -0,0 +1,63 @@
+<template>
+  <div class="demo">
+    <h2>基本用法</h2>
+    <nut-rate v-model="state.val" />
+
+    <h2>半星</h2>
+    <nut-rate allow-half v-model="state.val1"></nut-rate>
+
+    <h2>自定义 icon </h2>
+    <nut-rate
+      checked-icon="heart-fill1"
+      unchecked-icon="heart"
+      v-model="state.val2"
+    ></nut-rate>
+
+    <h2>自定义数量</h2>
+    <nut-rate :count="6" v-model="state.val3"></nut-rate>
+
+    <h2>自定义颜色</h2>
+    <nut-rate active-color="#FFC800" v-model="state.val4"></nut-rate>
+
+    <h2>禁用状态</h2>
+    <nut-rate disabled v-model="state.val5"></nut-rate>
+
+    <h2>只读状态</h2>
+    <nut-rate v-model="state.val6" readonly></nut-rate>
+
+    <h2>绑定事件</h2>
+    <nut-rate v-model="state.val7" @change="onChange"></nut-rate>
+    <h2>自定义尺寸 35px</h2>
+    <nut-rate v-model="state.val8" icon-size="35"></nut-rate>
+  </div>
+</template>
+
+<script>
+import { reactive, getCurrentInstance } from 'vue';
+export default {
+  setup() {
+    let { proxy } = getCurrentInstance();
+
+    const state = reactive({
+      val: 3,
+      val1: 3.5,
+      val2: 3,
+      val3: 3,
+      val4: 3,
+      val5: 3,
+      val6: 3,
+      val7: 3,
+      val8: 3
+    });
+    const onChange = (val) => {
+      proxy.$toast.text(val);
+    };
+    return {
+      state,
+      onChange
+    };
+  }
+};
+</script>
+
+<style lang="scss" scoped></style>