Browse Source

📦 新增qrcode 指令引用 "v-qrcode='[string]'"

晓晓晓晓丶vv 4 years ago
parent
commit
308164c7fe
2 changed files with 50 additions and 0 deletions
  1. 2 0
      src/plugins/install.ts
  2. 48 0
      src/plugins/vue-qrcode.ts

+ 2 - 0
src/plugins/install.ts

@@ -16,6 +16,7 @@ import {
 
 import VueClipboard3 from "./vue-clipboard";
 import VueConfirmDirective from "./vue-confirm";
+import VueQrCode from "./vue-qrcode";
 
 import { ModalConfirmKey } from "./injectionKey";
 
@@ -27,6 +28,7 @@ const install = (app: App<Element>) => {
   return app
     .use(VueClipboard3)
     .use(VueConfirmDirective)
+    .use(VueQrCode)
     .use(ConfigProvider)
     .use(Layout)
     .use(Menu)

+ 48 - 0
src/plugins/vue-qrcode.ts

@@ -0,0 +1,48 @@
+import { DirectiveBinding, VNode, App } from "vue";
+import QRCode from "qrcode";
+
+const insertQrCode2Element = (el: HTMLElement | Element, qrCode: string) => {
+  if (el.nodeName === "IMG") el.setAttribute("src", qrCode);
+  else {
+    // 判断原来的node是否存在 存在就删除
+    const prevChild = el.lastElementChild;
+    if (prevChild) el.removeChild(prevChild);
+    const imgElement = document.createElement("img");
+    imgElement.src = qrCode;
+    el.appendChild(imgElement);
+  }
+};
+
+const bind = async (
+  el: HTMLElement | Element,
+  binding: DirectiveBinding,
+  vnode: VNode
+) => {
+  console.log("mounted:", binding);
+  const qrText = binding.value;
+  if (typeof qrText === "string") {
+    const code = await QRCode.toDataURL(qrText);
+    insertQrCode2Element(el, code);
+  } else console.log("v-qrode 需要一个string类型的值");
+};
+
+const update = async (el: HTMLElement | Element, binding: DirectiveBinding) => {
+  if (binding.oldValue === binding.value) return;
+  console.log("update:", binding);
+  const qrText = binding.value;
+  if (typeof qrText === "string") {
+    const code = await QRCode.toDataURL(qrText);
+    insertQrCode2Element(el, code);
+  } else console.log("v-qrode 需要一个string类型的值");
+};
+
+const VueQrCode = {
+  install: (app: App<Element>) => {
+    app.directive("qrcode", {
+      mounted: bind,
+      updated: update,
+    });
+  },
+};
+
+export default VueQrCode;