vue2企业级项目(九)

vue2企业级项目(九)

组件封装(三)

7、input-number
  • 创建components/input-number/index.js

    import XInputNumber from "./index.vue";
    export default XInputNumber;
    
    
  • 创建components/input-number/index.vue

    <template>
      <el-input :value="inputValue" @input="handleInput"></el-input>
    </template>
    
    <script>
    import Big from "big.js";
    
    /**
     * @param { String } value: 绑定value
     * @param { Number } min: 最小值
     * @param { Number } max: 最大值
     * @param { Boolean } permillage: 是否需要千分号
    */
    
    export default {
      name: "XInputNumber",
      props: {
        value: {
          type: String,
          default: "",
        },
        min: {
          type: Number,
          default: null,
        },
        max: {
          type: Number,
          default: null,
        },
        permillage: {
          type: Boolean,
          default: false,
        },
      },
      data() {
        return {
          inputValue: "",
        };
      },
      created() {
        this.inputValue = this.handleInput(this.value);
      },
      methods: {
        handleInput(val) {
          let num = val;
          if (this.permillage) num = num.replaceAll(",", "");
          if (isNaN(num)) return;
          num = num === "" ? num : new Big(num);
          if (this.min && num && this.min > num) num = this.min;
          if (this.max && num && this.max < num) num = this.max;
          num = num.toString();
          this.inputValue = num;
          if (this.permillage) {
            this.inputValue = this.inputValue.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
          }
          this.$emit("input", num);
        },
      },
    };
    </script>
    
    
8、update

主要适配xform,统一文件上传接口,其他作用不是特别大。

  • 创建components/updateFile/index.js

    import XUpload from "./index.vue";
    export default XUpload;
    
    
  • 创建components/updateFile/index.vue

    <template>
      <el-upload
        action="#"
        :multiple="multiple"
        :on-change="onChange"
        :http-request="httpRequest"
        :on-success="handleSuccess"
        v-bind="$attrs"
        v-on="$listeners"
      >
        <slot></slot>
    
        <template #trigger>
          <slot name="trigger"></slot>
        </template>
    
        <template #tip>
          <slot name="tip"></slot>
        </template>
      </el-upload>
    </template>
    
    <script>
    import { cloneDeep } from "lodash";
    import { checkDataType } from "@/utils/utils";
    
    export default {
      name: "XUpload",
      props: {
        value: {
          type: [Array, Object],
          default: null,
        },
        multiple: {
          type: Boolean,
          default: false,
        },
        api: {
          type: Function,
          default: null,
        },
      },
      data() {
        return {
          fileList: [],
        };
      },
      mounted() {
        this.init();
      },
      methods: {
        init() {
          if (!this.value) return;
    
          if (checkDataType(this.value, "array")) {
            this.fileList = cloneDeep(this.value);
          }
    
          if (checkDataType(this.value, "object")) {
            this.fileList = [this.value];
          }
        },
    
        onChange(file, fileList) {
          if (!this.api) {
            this.fileList = fileList;
            if (this.multiple) this.$emit("input", fileList);
            else this.$emit("input", fileList[0]);
          }
        },
    
        /* 存在固定的文件服务器是, 可以统一文件上传接口 */
        httpRequest() {
          return null;
          // return this.api({ file: obj.file });
        },
    
        handleSuccess(response, file, fileList) {
          this.fileList = fileList;
          if (this.multiple) this.$emit("input", fileList);
          else this.$emit("input", fileList[0]);
        },
      },
    };
    </script>
    
    
9、theme-color

切换主题色、使用上面的动态切换主题原理实现

  • 创建components/theme-color/index.js

    import XThemeColor from "./index.vue";
    export default XThemeColor;
    
    
  • 创建components/theme-color/index.vue

    <template>
      <el-color-picker v-model="color"></el-color-picker>
    </template>
    
    <script>
    import client from "webpack-theme-color-replacer/client";
    
    /**
     * @deprecated 目前先写变量,后期根据业务调整,看是放在本地存储,还是跟随用户配置信息
     */
    
    export default {
      name: "XThemeColor",
      data() {
        return {
          color: "#409EFF",
        };
      },
      watch: {
        color: {
          immediate: true,
          handler(color) {
            client.changer.changeColor({ newColors: ["" + color] });
          },
        },
      },
    };
    </script>
    
    
10、screenfull

全屏按钮、使用插件screenfull@4.2.0

npm install --save screenfull@4.2.0

请原谅我臭不要脸的抄袭了vue-element-admin的代码。捂脸

  • 创建components/screenfull/index.js

    import XScreenfull from "./index.vue";
    export default XScreenfull;
    
    
  • 创建components/screenfull/index.vue

    <template>
      <el-button
        icon="el-icon-full-screen"
        type="primary"
        circle
        @click="click"
      ></el-button>
    </template>
    
    <script>
    import screenfull from "screenfull";
    
    export default {
      name: "XScreenfull",
      data() {
        return {
          isFullscreen: false,
        };
      },
      mounted() {
        this.init();
      },
      beforeDestroy() {
        this.destroy();
      },
      methods: {
        click() {
          if (!screenfull.enabled) {
            this.$message({
              message: "you browser can not work",
              type: "warning",
            });
            return false;
          }
          screenfull.toggle();
        },
        change() {
          this.isFullscreen = screenfull.isFullscreen;
        },
        init() {
          if (screenfull.enabled) {
            screenfull.on("change", this.change);
          }
        },
        destroy() {
          if (screenfull.enabled) {
            screenfull.off("change", this.change);
          }
        },
      },
    };
    </script>
    
    
11、screenshot

截屏按钮、使用插件html2canvas

npm install --save html2canvas
  • 创建components/screenshot/index.js

    import XScreenshot from "./index.vue";
    export default XScreenshot;
    
    
  • 创建components/screenshot/index.vue

    <template>
      <el-button
        icon="el-icon-camera-solid"
        type="primary"
        circle
        @click="click"
      ></el-button>
    </template>
    
    <script>
    import html2canvas from "html2canvas";
    
    /**
     * @param { String } dom 截图的dom
     * @param { String } fileName 截图的文件名
    */
    
    export default {
      name: "XScreenshot",
      props: {
        dom: {
          type: String,
          default: "#app",
        },
        fileName: {
          type: String,
          default: "screenshot.png",
        },
      },
      methods: {
        click() {
          const screenshotContainer = document.querySelector(this.dom);
          console.log(screenshotContainer);
    
          html2canvas(screenshotContainer)
            .then((canvas) => {
              const eLink = document.createElement("a");
              eLink.download = this.fileName;
              eLink.style.display = "none";
              eLink.href = canvas.toDataURL();
              document.body.appendChild(eLink);
              eLink.click();
              document.body.removeChild(eLink);
            })
            .catch((error) => {
              console.error(error);
            });
        },
      },
    };
    </script>
    
    
12、navTabs
  • 目的:由于el-tabs并不具备左右拖动的功能,所以在某些业务需要添加这个功能

  • 推荐使用插件vue-tabs-chrome

  • 这里提供一个使用sortablejs封装的,仅针对el-tabs的扩展方法

    // src/utils/utils.js
    ...
    import Sortable from "sortablejs";
    
    ...
    
    /**
     * @deprecated 直接作用el-tabs,让el-tabs的标签可以拖拽重新排序
     *
     * @param { VNode } vnode: 获取到的ref对象,用来区分多个el-tabs
     * @param { Function } handleEnd: 拖拽完成后回调函数
     */
    export function initSortable(vnode, handleEnd) {
      if (!vnode) return;
      const el = vnode.$el.querySelector(".el-tabs__nav");
      Sortable.create(el, {
        draggable: ".el-tabs__item",
        handle: ".el-tabs__item",
        direction: "horizontal",
        onEnd: handleEnd || null,
      });
    }
    
  • 使用案例

    <template>
    	<el-tabs v-model="editableTabsValue" type="card" ref="navtabs">
            <el-tab-pane
              v-for="item in editableTabs"
              :key="item.name"
              :label="item.title"
              :name="item.name"
            >
              {{ item.content }}
            </el-tab-pane>
          </el-tabs>
    </template>
    
    <script>
    import { initSortable } from "@/utils/utils";
        
    export default {
        data() {
            return {
                editableTabsValue: "2",
                editableTabs: [
                    {
                      title: "Tab 1",
                      name: "1",
                      content: "Tab 1 content",
                    },
                    {
                      title: "Tab 2",
                      name: "2",
                      content: "Tab 2 content",
                    },
                ],
            }
        },
        mounted() {
            initSortable(this.$refs.navtabs);
        },
    }
    </script>
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值