Menu vue3 h function to create components

Table of contents

 index/.view

<template>
  <div class="menu_table">
    <div
      class="table_row"
      v-for="(item, index) in menuList"
      @click="item.disabled !== true && itemClick(item)"
    >
      <!-- :style="{
             'border-top':item.line ===true?'solid 1px rgb(44, 44, 44)':'none'
        }" -->
      <div class="item_line" v-if="item.line === true"></div>
      <div
        :class="{
          item_disabled: item.disabled === true,
          item_denydisabled: item.disabled === false,
        }"
      >
        <!-- {
   
   {item.icon.value}} -->
        <!-- &nbsp&nbsp -->

        <div class="item_label"></div>
        <!-- <div class="icon_border"> -->
        <img
          v-if="item.icon && item.icon.show === true && item.icon.type === 'img'"
          :src="item.icon.value"
        />
        <div class="no_icon" v-if="item.icon === undefined" />
        <!-- </div> -->

        <div class="icon_blank"></div>
        <div class="icon_label" id="menu_item">{
   
   { item.label }}</div>
      </div>
    </div>
  </div>
</template>

<script>
import { removeMenu } from "./menu";
export default {
  data() {
    return {
      clientX: "0px",
      clientY: "0px",
    };
  },
  mounted() {
    this.init(this.locat.clientX, this.locat.clientY);
    window.onmousedown = (event) => {
      // event.button===2||

      if (event.button === 0) {
        if (event.target.id === "menu_item") {
          window.onmousedown = null;
        } else {
          removeMenu();
        }
      } else if (event.button === 2) {
        if ($store().state.window.isContext) {
          this.init(event.clientX, event.clientY);
          $store().state.window.isContext = false;
        }

        // this.clientX = event.clientX + "px";
        // this.clientY = event.clientY + "px";
      }
    };
  },
  props: {
    locat: {
      type: Object,
      default() {
        return {};
      },
    },
    params: {
      type: Object,
      default() {
        return {};
      },
    },
    menuList: {
      type: Array,
      default() {
        return [];
      },
    },
  },
  methods: {
    itemClick(item) {
      console.log(item);
      item.fn();

      removeMenu();
    },

    init(clientX, clientY) {
      const width = document.body.clientWidth;
      const height = document.body.clientHeight;
      const boxHeight = this.menuList.length * 25;
      const boxWidth = 130;
      if (clientY + boxHeight > height) {
        if (clientY - boxHeight > 0) {
          this.clientY = clientY - boxHeight + "px";
        } else {
          this.clientY = clientY - boxHeight / 2 + "px";
        }
      } else {
        this.clientY = clientY + "px";
      }
      if (clientX + boxWidth > width) {
        if (clientX - boxWidth > 0) {
          this.clientX = clientX - boxWidth + "px";
        } else {
          this.clientX = clientX - boxWidth / 2 + "px";
        }
      } else {
        this.clientX = clientX + "px";
      }
    },
  },
  unmounted() {
    window.onmousedown = null;
  },
};
</script>

<style scoped>
.table_row {
  /* border: solid 1px rgb(44, 44, 44); */
  width: 130px;
  height: 25px;
  background: white;
  line-height: 25px;
}
/* :hover {
  background: #4791db;
  color: white;
} */

.item_denydisabled:hover > .icon_label {
  background: #4791db;
  color: white;
}
.item_denydisabled:hover > .icon_border {
  /* border: ridge 1px #4791db;
  box-shadow: 0px 0px 5px 2px rgb(0 0 0 / 8%); */
}
.menu_table {
  position: absolute;
  top: v-bind(clientY);
  left: v-bind(clientX);
  z-index: 9999999;
  overflow: hidden;
  /* border: solid 1px #d7d7d7; */
  border-radius: 5px;
  box-shadow: 0px 0px 5px 2px rgb(0 0 0 / 8%);
}
.item_disabled {
  color: #bbcccc;
  width: 100%;
  height: 100%;
}
.item_denydisabled {
  /* text-align: left; */
  /* color: red; */
  width: 100%;
  height: 100%;
}
.item_label {
  height: 1px;
  display: inline-block;
  width: 9px;
  vertical-align: bottom;
}
.item_line {
  height: 1px;
  width: 100px;
  /* position:absolute;
  top:0; */
  /* margin-top:-1px; */
  margin-left: 15px;
  display: block;
  background-color: #e4e7ed;

  /* box-shadow: 0px 0px 10px #b9b9b9; */
}
img,
.no_icon {
  width: 14px;
  height: 14px;
  display: inline-block;
  vertical-align: middle;
  /* margin-top: -5px;
  margin-left: 3px; */
}
.icon_border {
  width: 17px;
  height: 17px;
  display: inline-block;
  /* border: groove  1px #4791db; */
  vertical-align: middle;
}
.icon_blank {
  height: 100%;
  display: inline-block;
  width: 5px;
  vertical-align: bottom;
}
.icon_label {
  height: 100%;
  display: inline-block;
  width: 95px;
  vertical-align: middle;
}
</style>

menu.js

import { createVNode, render } from "vue";
import menuElement from "./index.vue";

//      定义一个div容器
const div = document.createElement("div");
document.body.appendChild(div);
export default {
  addMenu(locat, menuList, params) {
    const vnode = createVNode(menuElement, { locat, menuList, params });
    //      调用渲染方法:将虚拟节点渲染到dom中
    render(vnode, div);
  },
};
export const removeMenu = function () {
  render(null, div);
};

menuData.js

export default {
    viewArr :  [
        {
          label: "左对齐",
          tips: "Stop",
          disabled: value >= 2 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 2
                ? "statics/icons/proicons/alignLeft_active.svg"
                : "statics/icons/proicons/alignLeft.svg",
          },
          line: false,
          fn: (row) => {
            this.alignLeft();
          },
        },
        {
          label: "水平居中对齐",
          tips: "Add",
          disabled: value >= 2 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 2
                ? "statics/icons/proicons/alignHorizontalCenter_active.svg"
                : "statics/icons/proicons/alignHorizontalCenter.svg",
          },
          line: false,
          fn: (row) => {
            this.horizontalCenter();
          },
        },
        {
          label: "右对齐",
          disabled: value >= 2 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 2
                ? "statics/icons/proicons/alignRight_active.svg"
                : "statics/icons/proicons/alignRight.svg",
          },
          tips: "Edit",
          line: false,
          fn: (row) => {
            this.alignRight();
          },
        },
        {
          label: "上对齐",
          tips: "Delete",
          disabled: value >= 2 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 2
                ? "statics/icons/proicons/alignTop_active.svg"
                : "statics/icons/proicons/alignTop.svg",
          },
          line: false,
          fn: (row) => {
            this.alignTop();
          },
        },
        {
          label: "垂直居中对齐",
          tips: "Stop",
          disabled: value >= 2 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 2
                ? "statics/icons/proicons/alignVerticalCenter_active.svg"
                : "statics/icons/proicons/alignVerticalCenter.svg",
          },
          line: false,
          fn: (row) => {
            this.verticalCenter();
          },
        },
        {
          label: "下对齐",
          tips: "Add",
          disabled: value >= 2 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 2
                ? "statics/icons/proicons/alignBottom_active.svg"
                : "statics/icons/proicons/alignBottom.svg",
          },
          line: false,
          fn: (row) => {
            this.alignBottom();
          },
        },
        {
          label: "中心对齐",
          disabled: value >= 2 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 2
                ? "statics/icons/proicons/centerAlignment_active.svg"
                : "statics/icons/proicons/centerAlignment.svg",
          },
          tips: "Edit",
          line: false,
          fn: (row) => {
            this.controlCenter();
          },
        },

        {
          label: "垂直等间距",
          tips: "Stop",
          disabled: value >= 3 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 3
                ? "statics/icons/proicons/verticalEqualSpacing_active.svg"
                : "statics/icons/proicons/verticalEqualSpacing.svg",
          },
          line: true,
          fn: (row) => {
            this.verticallyEquallySpaced();
          },
        },
        {
          label: "水平等间距",
          tips: "Add",
          disabled: value >= 3 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 3
                ? "statics/icons/proicons/horizontalEqualSpacing_active.svg"
                : "statics/icons/proicons/horizontalEqualSpacing.svg",
          },
          line: false,
          fn: (row) => {
            this.horizontallEquidistant();
          },
        },
        {
          label: "垂直无间距",
          disabled: value >= 2 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 2
                ? "statics/icons/proicons/verticalNoSpace_active.svg"
                : "statics/icons/proicons/verticalNoSpace.svg",
          },
          tips: "Edit",
          line: false,
          fn: (row) => {
            this.nohorizontallEquidistant();
          },
        },
        {
          label: "水平无间距",
          tips: "Delete",
          disabled: value >= 2 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 2
                ? "statics/icons/proicons/horizontalNoSpace_active.svg"
                : "statics/icons/proicons/horizontalNoSpace.svg",
          },
          line: false,
          fn: (row) => {
            this.noverticallyEquallySpaced();
          },
        },
        {
          label: "等宽",
          tips: "Add",
          disabled: value >= 2 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 2
                ? "statics/icons/proicons/sameWidth_active.svg"
                : "statics/icons/proicons/sameWidth.svg",
          },
          line: true,
          fn: (row) => {
            this.sameHeight();
          },
        },
        {
          label: "等高",
          disabled: value >= 2 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 2
                ? "statics/icons/proicons/sameHeight_active.svg"
                : "statics/icons/proicons/sameHeight.svg",
          },
          tips: "Edit",
          line: false,
          fn: (row) => {
            this.sameWidth();
          },
        },
        {
          label: "等大小",
          tips: "Delete",
          disabled: value >= 2 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 2
                ? "statics/icons/proicons/sameSize_active.svg"
                : "statics/icons/proicons/sameSize.svg",
          },
          line: false,
          fn: (row) => {
            this.sameSize();
          },
        },
        {
          label: "上移一层",
          tips: "Stop",
          disabled: value >= 1 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 1
                ? "statics/icons/proicons/bringForward_active.svg"
                : "statics/icons/proicons/bringForward.svg",
          },
          line: true,
          fn: (row) => {
            this.putOnTop();
          },
        },
        {
          label: "下移一层",
          tips: "Add",
          disabled: value >= 1 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 1
                ? "statics/icons/proicons/bringBackward_active.svg"
                : "statics/icons/proicons/bringBackward.svg",
          },
          line: false,
          fn: (row) => {
            this.putOnBottom();
          },
        },
        {
          label: "移到最上层",
          disabled: value === 1 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value === 1
                ? "statics/icons/proicons/bringToTop_active.svg"
                : "statics/icons/proicons/bringToTop.svg",
          },
          tips: "Edit",
          line: false,
          fn: (row) => {
            this.moveUpOneLevel();
          },
        },
        {
          label: "移到最下层",
          tips: "Delete",
          disabled: value === 1 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value === 1
                ? "statics/icons/proicons/bringToBack_active.svg"
                : "statics/icons/proicons/bringToBack.svg",
          },
          line: false,
          fn: (row) => {
            this.moveDownOneLevel();
          },
        },
        {
          label: "编辑",
          disabled: spValue ? false : true,
          icon: {
            show: true,
            type: "img",
            value: spValue
              ? "statics/icons/proicons/edit_active.svg"
              : "statics/icons/proicons/edit.svg",
          },
          tips: "Edit",
          line: true,
          fn: (row) => {
            this.changeNone();
          },
        },
        {
          label: "打组",
          disabled: value >= 2 ? false : true,
          icon: {
            show: true,
            type: "img",
            value:
              value >= 2
                ? "statics/icons/proicons/group_active.svg"
                : "statics/icons/proicons/group.svg",
          },
          tips: "Edit",
          line: false,
          fn: (row) => {
            this.packGroup();
          },
        },
        {
          label: "解组",
          tips: "Delete",
          disabled: spValue ? false : true,
          icon: {
            show: true,
            type: "img",
            value: spValue
              ? "statics/icons/proicons/ungroup_active.svg"
              : "statics/icons/proicons/ungroup.svg",
          },
          line: false,
          fn: (row) => {
            this.unpackGroup();
          },
        },
      ]
}

Guess you like

Origin blog.csdn.net/qq_51389137/article/details/132014862