Parcourir la source

fix: temporary storage

xiaoxian521 il y a 4 ans
Parent
commit
78d9c17201

+ 180 - 0
src/components/selector/index.vue

@@ -0,0 +1,180 @@
+<template>
+  <table cellspacing="0" cellpadding="0">
+    <tbody>
+      <tr>
+        <td
+          v-for="(item, key) in max"
+          :class="['hs-select__item' + key]"
+          @mousemove="setCurrentValue(key, $event)"
+          @mouseleave="resetCurrentValue(key)"
+          @click="selectValue(key, item)"
+          :style="{ cursor: rateDisabled ? 'auto' : 'pointer', 'text-align': 'center' }"
+          :key="key"
+        >
+          <div :class="[classes[key] + key]" class="hs-item">
+            <span>22</span>
+          </div>
+        </td>
+      </tr>
+    </tbody>
+  </table>
+</template>
+
+<script lang='ts'>
+import { defineComponent, computed, nextTick } from "vue";
+import { addClass, removeClass } from "../../utils/operate/index";
+import { useDebounceFn } from "@vueuse/core";
+
+// 选中非选中状态
+let stayClass = "stay"; //鼠标点击
+let activeClass = "hs-on"; //鼠标移动上去
+let voidClass = "hs-off"; //鼠标移开
+let inRange = "hs-range"; //当前选中的两个元素之间的背景
+
+// 存放第一个选中的元素和最后一个选中元素,只能存放这两个元素
+let selectedList = [];
+
+let overList = [];
+
+export default defineComponent({
+  props: {
+    disabled: {
+      type: Boolean,
+      default: false,
+    },
+    value: {
+      type: Number,
+      default: 0,
+    },
+    max: {
+      type: Number,
+      default: 10,
+    },
+  },
+  setup(props, { emit }) {
+    let currentValue = props.value;
+
+    let rateDisabled = computed(() => {
+      return props.disabled;
+    });
+
+    let classes = computed(() => {
+      let result = [];
+      let i = 0;
+      let threshold = currentValue;
+      if (currentValue !== Math.floor(currentValue)) {
+        threshold--;
+      }
+      for (; i < threshold; i++) {
+        result.push(activeClass);
+      }
+      for (; i < props.max; i++) {
+        result.push(voidClass);
+      }
+      return result;
+    });
+
+    const setCurrentValue = (index, event) => {
+      // 当选中一个元素后,开始添加背景色
+      if (selectedList.length === 1) {
+        overList.push({ index });
+
+        // let i = 0;
+
+        let firstIndex = overList[0].index;
+        // 往左走,索引变大
+
+        if (index > firstIndex) {
+          // console.log(index, firstIndex);
+          let leftIndex = index - firstIndex;
+
+          for (var i =0; i < index; i++) {
+            // useDebounceFn(() => {
+              if(document.querySelector(".hs-select__item" + (i+index))) {
+              addClass(document.querySelector(".hs-select__item" + (i+index)), inRange);
+              }
+            // }, 100)();
+          }
+        } else {
+        }
+      }
+
+      addClass(document.querySelector("." + voidClass + index), activeClass);
+    };
+
+    const resetCurrentValue = (index) => {
+      // 移除先检查是否选中 选中则返回false 不移除
+      const currentHsDom = document.querySelector("." + voidClass + index);
+      if (currentHsDom.className.includes(stayClass)) {
+        return false;
+      } else {
+        removeClass(currentHsDom, activeClass);
+      }
+
+      // 当选中一个元素后,开始移除背景色
+      if (selectedList.length === 1) {
+        for (let i = 0; i <= index; i++) {
+          removeClass(document.querySelector(".hs-select__item" + i), inRange);
+        }
+      }
+    };
+
+    const selectValue = (index, item) => {
+      let len = selectedList.length;
+
+      if (len < 2) {
+        selectedList.push({ item, index });
+        addClass(document.querySelector("." + voidClass + index), stayClass);
+
+        // let rangeDom = document.querySelector(".hs-select__item" + index)
+      } else {
+        nextTick(() => {
+          selectedList.forEach((v) => {
+            removeClass(
+              document.querySelector("." + voidClass + v.index),
+              activeClass,
+              stayClass
+            );
+          });
+          selectedList = [];
+
+          for (let i = 0; i <= props.max; i++) {
+            let currentDom = document.querySelector(".hs-select__item" + i);
+            if (currentDom) {
+              removeClass(currentDom, inRange);
+            }
+          }
+        });
+      }
+    };
+
+    return {
+      rateDisabled,
+      setCurrentValue,
+      resetCurrentValue,
+      selectValue,
+      classes,
+    };
+  },
+});
+</script>
+
+<style scoped>
+.hs-rate__icon {
+  font-size: 18px;
+  transition: 0.3s;
+}
+.hs-item {
+  width: 30px;
+  height: 30px;
+  box-sizing: border-box;
+  line-height: 30px;
+}
+.hs-on {
+  background-color: #409eff;
+  border-radius: 50%;
+}
+.hs-range {
+  background-color: #ccc;
+}
+</style>

+ 1 - 1
src/layout/components/tag/tagsHook.ts

@@ -35,7 +35,7 @@ export function useDynamicRoutesHook() {
           let pathConcat = parentPath + '/' + arrItem.path
           if (arrItem.path === value || pathConcat === value) {
             dynamic.dRoutes.push({ path: value, meta: arrItem.meta })
-            console.log(dynamic.dRoutes)
+            // console.log(dynamic.dRoutes)
           } else {
             if (arrItem.children && arrItem.children.length > 0) {
               concatPath(arrItem.children, value, parentPath)

+ 2 - 1
src/locales/ch.json

@@ -16,5 +16,6 @@
   "split-pane": "切割面板",
   "button": "按钮组件",
   "cropping": "图片裁剪",
-  "countTo": "数字动画"
+  "countTo": "数字动画",
+  "selector": "选择器组件"
 }

+ 2 - 1
src/locales/en.json

@@ -16,5 +16,6 @@
   "split-pane": "Split Pane",
   "button": "Button Components",
   "cropping": "Picture Cropping",
-  "countTo": "Digital Animation"
+  "countTo": "Digital Animation",
+  "selector": "Selector Components"
 }

+ 9 - 0
src/router/index.ts

@@ -94,6 +94,15 @@ const routes: Array<RouteRecordRaw> = [
           showLink: false,
           savedPosition: true
         }
+      },
+      {
+        path: '/components/selector',
+        component: () => import(/* webpackChunkName: "components" */ '../views/components/selector/index.vue'),
+        meta: {
+          title: 'selector',
+          showLink: false,
+          savedPosition: true
+        }
       }
     ],
     meta: {

+ 8 - 2
src/utils/operate/index.ts

@@ -6,9 +6,15 @@ export const addClass = (ele: Element, cls:string) :any =>  {
   if (!hasClass(ele, cls)) ele.className += ' ' + cls
 }
 
-export const removeClass =(ele: Element, cls:string) :any => {
+export const removeClass =(ele: Element, cls:string, extracls?: string) :any => {
   if (hasClass(ele, cls)) {
     const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
-    ele.className = ele.className.replace(reg, ' ')
+    ele.className = ele.className.replace(reg, ' ').trim()
+  }
+  if (extracls) {
+    if (hasClass(ele, extracls)) {
+      const regs = new RegExp('(\\s|^)' + extracls + '(\\s|$)')
+      ele.className = ele.className.replace(regs, ' ').trim()
+    }
   }
 }

+ 23 - 0
src/views/components/selector/index.vue

@@ -0,0 +1,23 @@
+<template>
+  <el-card class="box-card" style="margin:20px">
+    <template #header>
+      <div class="card-header">
+        <span>基本使用</span>
+      </div>
+    </template>
+    <Selector />
+  </el-card>
+</template>
+
+<script lang='ts'>
+import Selector from "../../../components/selector/index.vue";
+export default {
+  components: { Selector },
+  setup() {
+    return {};
+  },
+};
+</script>
+
+<style scoped>
+</style>