mirror of
https://github.com/sahadev/vue-component-creater-ui.git
synced 2025-12-18 00:14:30 +08:00
init
This commit is contained in:
24
src/utils/common.js
Normal file
24
src/utils/common.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import isEqual from "lodash/isEqual";
|
||||
|
||||
export function getRawComponentKey(__rawVueInfo__) {
|
||||
return Object.keys(__rawVueInfo__)[0];
|
||||
}
|
||||
|
||||
export function getRawComponentContent(__rawVueInfo__) {
|
||||
return __rawVueInfo__[getRawComponentKey(__rawVueInfo__)];
|
||||
}
|
||||
|
||||
/**
|
||||
* 比较两个对象是否完全相等
|
||||
*/
|
||||
export function compareTwoObjectIsEqual(o1, o2) {
|
||||
return isEqual(o1, o2);
|
||||
}
|
||||
|
||||
export function isArray(arr) {
|
||||
return Object.prototype.toString.apply(arr) === "[object Array]";
|
||||
}
|
||||
|
||||
export function isObject(obj) {
|
||||
return Object.prototype.toString.apply(obj) === "[object Object]";
|
||||
}
|
||||
262
src/utils/forCode.js
Normal file
262
src/utils/forCode.js
Normal file
@@ -0,0 +1,262 @@
|
||||
|
||||
import { isObject, isArray, getRawComponentKey } from '@/utils/common';
|
||||
import presetAttribute from "../libs/presetAttribute";
|
||||
const cryptoRandomString = require("crypto-random-string");
|
||||
|
||||
// 将预生成的ID替换,否则当有两个组件挂在同一个树上时,后一个会将前一个的属性覆盖
|
||||
export function replaceRowID(codeObj, html) {
|
||||
// 生成一个唯一的ID,使Code和Dom一一对应,与原代码脱离关系
|
||||
let newHtml = html;
|
||||
function deep(obj) {
|
||||
if (isObject(obj)) {
|
||||
for (const key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
const element = obj[key];
|
||||
if (key == "lc_id") {
|
||||
const oldID = obj[key];
|
||||
const newID = cryptoRandomString({
|
||||
length: 10,
|
||||
type: "base64",
|
||||
});
|
||||
newHtml = newHtml.replace(oldID, newID);
|
||||
obj[key] = newID;
|
||||
} else if (isObject(element)) {
|
||||
deep(element);
|
||||
} else if (isArray(element)) {
|
||||
element.forEach((item) => deep(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
deep(codeObj);
|
||||
return newHtml;
|
||||
}
|
||||
|
||||
|
||||
/** 在这里维护一棵以ID为KEY的树 */
|
||||
export function updateLinkTree(codeObj) {
|
||||
if (!window.tree) {
|
||||
window.tree = {};
|
||||
}
|
||||
if (!window.treeWithID) {
|
||||
const innerObj = {};
|
||||
Object.defineProperty(window, 'treeWithID', {
|
||||
get: function () {
|
||||
return innerObj;
|
||||
},
|
||||
set: function (newValue) {
|
||||
innerObj = newValue;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
flatCodeObj(codeObj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取这个元素所对应的代码结构
|
||||
*/
|
||||
export function findRawVueInfo(element) {
|
||||
// 这里对于form这样的怪物来说会导致指向错乱的问题 2020年12月07日14:39:30
|
||||
// if (element.__rawVueInfo__) {
|
||||
// return element.__rawVueInfo__;
|
||||
// } else
|
||||
if (window.tree[element.attributes.lc_id.nodeValue]) {
|
||||
return window.tree[element.attributes.lc_id.nodeValue];
|
||||
} else {
|
||||
return findRawVueInfo(element.parentNode);
|
||||
}
|
||||
}
|
||||
|
||||
export function flatCodeObj(codeObj) {
|
||||
function deep(object) {
|
||||
for (const key in object) {
|
||||
if (object.hasOwnProperty(key)) {
|
||||
const element = object[key];
|
||||
|
||||
// 如果对__children的子属性遍历时,它内部的元素需要指向外层的节点作为父节点
|
||||
if (
|
||||
object.hasOwnProperty("__key__") &&
|
||||
object["__key__"] === "__children" &&
|
||||
isObject(element)
|
||||
) {
|
||||
delete object["__key__"];
|
||||
}
|
||||
|
||||
if (key === "lc_id" && object.hasOwnProperty("__key__")) {
|
||||
const outerKey = object["__key__"];
|
||||
const newObj = {
|
||||
[outerKey]: object
|
||||
};
|
||||
|
||||
// 这个关系也需要链接
|
||||
newObj.__proto__ = object.__proto__;
|
||||
delete object.__key__;
|
||||
window.tree[element] = newObj;
|
||||
|
||||
// 这个备份用于生成兄弟组件时获取原始代码所用,需要保留ID的信息才可以实现DOM与代码对象的关联
|
||||
const copy = Object.create(newObj.__proto__);
|
||||
Object.assign(copy, JSON.parse(JSON.stringify(newObj)));
|
||||
window.treeWithID[element] = copy;
|
||||
|
||||
} else if (key === "__children") {
|
||||
object.__children.forEach((child) => {
|
||||
child["__key__"] = key;
|
||||
deep(child);
|
||||
});
|
||||
} else if (isObject(element)) {
|
||||
element["__key__"] = key;
|
||||
deep(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
deep(codeObj);
|
||||
}
|
||||
|
||||
// 将所有子节点指向其父节点,父节点指向子节点容易,而子节点找到具体的父节点不容易
|
||||
export function linkRelationShip(unitRootCodeObj) {
|
||||
function deep(obj) {
|
||||
if (isObject(obj)) {
|
||||
for (const key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
const element = obj[key];
|
||||
if (isObject(element)) {
|
||||
element.__proto__ = { parentCodeNode: obj };
|
||||
deep(element);
|
||||
} else if (isArray(element) && key === "__children") {
|
||||
element.forEach((item) => {
|
||||
item.__proto__ = { parentCodeNode: obj };
|
||||
|
||||
deep(item);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deep(unitRootCodeObj);
|
||||
}
|
||||
|
||||
// 使生成的代码不携带ID属性
|
||||
export function removeAllID(codeObj) {
|
||||
function deep(obj) {
|
||||
if (isObject(obj)) {
|
||||
for (const key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
const element = obj[key];
|
||||
if (key == "lc_id" || key == "lc-mark") {
|
||||
delete obj[key];
|
||||
} else if (isObject(element)) {
|
||||
deep(element);
|
||||
} else if (isArray(element)) {
|
||||
element.forEach((item) => deep(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deep(codeObj);
|
||||
}
|
||||
|
||||
export function generateRawInfo(target) {
|
||||
if (target.attributes.lc_id) {
|
||||
// 获取源代码结构
|
||||
const rowCode = window.templateSourceMap[target.attributes.lc_id.nodeValue];
|
||||
return rowCode;
|
||||
} else if (target.__vue__) {
|
||||
// 代表这是一个Vue组件组成的元素,这里的逻辑渐渐不再使用
|
||||
const temp = findVueInfo(target.__vue__.$vnode);
|
||||
return temp;
|
||||
} else {
|
||||
// 这是一个普通的元素
|
||||
const temp = {
|
||||
[target.localName]: {
|
||||
__text__: target.innerText,
|
||||
class: target.className,
|
||||
}
|
||||
};
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过运行时查找这个VNODE的关键信息
|
||||
*/
|
||||
export function findVueInfo(vnode) {
|
||||
const obj = {};
|
||||
if (vnode.text) {
|
||||
obj["__text__"] = vnode.text;
|
||||
} else if (vnode.componentOptions) {
|
||||
const nodeBaseInfo = vnode.componentOptions;
|
||||
if (nodeBaseInfo.tag) {
|
||||
obj[nodeBaseInfo.tag] = nodeBaseInfo.propsData;
|
||||
}
|
||||
if (nodeBaseInfo.children && nodeBaseInfo.children.length > 0) {
|
||||
for (let index = 0; index < nodeBaseInfo.children.length; index++) {
|
||||
const child = nodeBaseInfo.children[index];
|
||||
merge(obj[nodeBaseInfo.tag], findVueInfo(child));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 这里需要将o2作为o1的子值 这里使用回调方法而不是用Promise的原因为需要严格保证外部的调用时序
|
||||
*/
|
||||
export function merge(o1, o2, currentPointPositionAfterIndex = -1, onFinish = () => { }) {
|
||||
if (o1 && o2) {
|
||||
if (!o1["__children"]) {
|
||||
o1["__children"] = [];
|
||||
}
|
||||
// 更新结构关系,将插入到指定的位置
|
||||
if (currentPointPositionAfterIndex > -1) {
|
||||
o1["__children"].splice(currentPointPositionAfterIndex, 0, o2);
|
||||
} else {
|
||||
o1["__children"].push(o2);
|
||||
}
|
||||
onFinish();
|
||||
|
||||
// 这里踩了一个坑,所有的对象的默认属性__proto__都指向同一个对象,会引起意外的问题
|
||||
o2.__proto__ = { parentCodeNode: o1 };
|
||||
}
|
||||
}
|
||||
|
||||
// 特殊分隔符
|
||||
export function getSplitTag() {
|
||||
return "@#$!";
|
||||
}
|
||||
|
||||
export function insertPresetAttribute(vueInfo) {
|
||||
const key = getRawComponentKey(vueInfo);
|
||||
const value = vueInfo[key];
|
||||
const presetAttr = presetAttribute[key];
|
||||
if (presetAttr) {
|
||||
for (const key in presetAttr) {
|
||||
if (presetAttr.hasOwnProperty(key)) {
|
||||
// 将原先的属性做新增或者替换操作
|
||||
const element = presetAttr[key];
|
||||
value[key] = element;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 寻找实际的可以代表整个复合组件Dom,这是个核心方法,根据某个元素查找实际的以Vue组件为单位的最小元素
|
||||
*/
|
||||
export function findCodeElemNode(element) {
|
||||
if (element.attributes && element.attributes.lc_id) {
|
||||
return element;
|
||||
} else if (element.parentNode) {
|
||||
return findCodeElemNode(element.parentNode);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
18
src/utils/get-imports.js
Normal file
18
src/utils/get-imports.js
Normal file
@@ -0,0 +1,18 @@
|
||||
export default function(code, { imports }) {
|
||||
return {
|
||||
name: 'get-imports',
|
||||
|
||||
visitor: {
|
||||
ImportDeclaration(path) {
|
||||
imports.push({
|
||||
variables: path.node.specifiers.map(spec => ({
|
||||
local: spec.local.name,
|
||||
imported: spec.imported ? spec.imported.name : 'default'
|
||||
})),
|
||||
module: path.node.source.value
|
||||
});
|
||||
path.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
40
src/utils/get-pkgs.js
Normal file
40
src/utils/get-pkgs.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import parsePackageName from 'parse-package-name';
|
||||
|
||||
export default async function(code, imports, scripts) {
|
||||
const replacements = [];
|
||||
|
||||
for (const [index, item] of imports.entries()) {
|
||||
const moduleName = `__npm_module_${index}`;
|
||||
const pkg = parsePackageName(item.module);
|
||||
const version = pkg.version || 'latest';
|
||||
scripts.push({
|
||||
path: pkg.path ? `/${pkg.path}` : '',
|
||||
name: moduleName,
|
||||
module:
|
||||
pkg.name === 'vue' && !pkg.path
|
||||
? `vue@${version}/dist/vue.esm.js`
|
||||
: `${pkg.name}@${version}`
|
||||
});
|
||||
let replacement = '\n';
|
||||
for (const variable of item.variables) {
|
||||
if (variable.imported === 'default') {
|
||||
replacement += `var ${
|
||||
variable.local
|
||||
} = ${moduleName}.default || ${moduleName};\n`;
|
||||
} else {
|
||||
replacement += `var ${variable.local} = ${moduleName}.${
|
||||
variable.imported
|
||||
};\n`;
|
||||
}
|
||||
}
|
||||
if (replacement) {
|
||||
replacements.push(replacement);
|
||||
}
|
||||
}
|
||||
|
||||
if (replacements.length > 0) {
|
||||
code = replacements.join('\n') + code;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
59
src/utils/iframe.js
Normal file
59
src/utils/iframe.js
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* From: https://github.com/egoist/codepan/blob/2c22bb3d7a7a4e31fd99fc640d320f7ec24d2951/src/utils/iframe.js
|
||||
*/
|
||||
import { Loading } from 'element-ui';
|
||||
class Iframe {
|
||||
constructor({ container, el, sandboxAttributes = [] }) {
|
||||
if (!el) {
|
||||
throw new Error('Expect "el" to mount iframe to!');
|
||||
}
|
||||
this.$container = container;
|
||||
this.$el = el;
|
||||
this.sandboxAttributes = sandboxAttributes;
|
||||
}
|
||||
|
||||
setHTML(obj) {
|
||||
let html;
|
||||
|
||||
if (typeof obj === 'string') {
|
||||
html = obj;
|
||||
} else {
|
||||
const { head = '', body = '' } = obj;
|
||||
html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
|
||||
}
|
||||
|
||||
// 关闭上一个实例引起的loading
|
||||
if (this.loadingInstance) {
|
||||
this.loadingInstance.close();
|
||||
}
|
||||
|
||||
this.loadingInstance = Loading.service({
|
||||
target: this.$container,
|
||||
text: '渲染中,请稍后...'
|
||||
});
|
||||
|
||||
const iframe = this.createIframe();
|
||||
iframe.addEventListener('load', () => {
|
||||
this.loadingInstance.close();
|
||||
})
|
||||
|
||||
this.$el.parentNode.replaceChild(iframe, this.$el);
|
||||
iframe.contentWindow.document.open();
|
||||
iframe.contentWindow.document.write(html);
|
||||
iframe.contentWindow.document.close();
|
||||
|
||||
this.$el = iframe;
|
||||
}
|
||||
|
||||
createIframe() {
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('sandbox', this.sandboxAttributes.join(' '));
|
||||
iframe.setAttribute('scrolling', 'yes');
|
||||
iframe.style.width = '100%';
|
||||
iframe.style.height = '100%';
|
||||
iframe.style.border = '0';
|
||||
return iframe;
|
||||
}
|
||||
}
|
||||
|
||||
export default (...args) => new Iframe(...args);
|
||||
67
src/utils/initRawComponent.js
Normal file
67
src/utils/initRawComponent.js
Normal file
@@ -0,0 +1,67 @@
|
||||
import { generateRawInfo, getSplitTag } from './forCode';
|
||||
import { getRawComponentKey } from './common';
|
||||
|
||||
|
||||
// 遍历DOM树,初始化lc-mark标记的元素
|
||||
export function deepLCEle(rootElement, onCountIncrease = () => { }) {
|
||||
// 对dragParent下所有含有lc-mark属性的Element实现可拖拽能力
|
||||
function deep(ele) {
|
||||
if (ele.attributes["lc-mark"]) {
|
||||
// 统计标记组件数量
|
||||
onCountIncrease();
|
||||
initElement(ele);
|
||||
}
|
||||
|
||||
if (ele.children.length > 0) {
|
||||
const length = ele.children.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
deep(ele.children.item(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deep(rootElement);
|
||||
}
|
||||
|
||||
// 对组件初始化,使组件可以拖拽
|
||||
export function initElement(element) {
|
||||
element.draggable = true;
|
||||
// 给每个组件添加拖拽事件
|
||||
element.addEventListener("dragstart", function (event) {
|
||||
event.dataTransfer.effectAllowed = "copy";
|
||||
const raw = generateRawInfo(element);
|
||||
const str = `${element.localName}${getSplitTag()}${element.innerText
|
||||
}${getSplitTag()}${0}${getSplitTag()}${element.style.cssText
|
||||
}${getSplitTag()}${JSON.stringify(raw)}`;
|
||||
event.dataTransfer.setData("text/plain", str);
|
||||
|
||||
try {
|
||||
const tag = getRawComponentKey(raw);
|
||||
window.trackManager.track("lc_on_start_drag", {
|
||||
tag,
|
||||
});
|
||||
} catch (error) { }
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
// 处理组件标记
|
||||
element.addEventListener("mouseenter", (event) => {
|
||||
const parentClassList = element.parentElement.classList;
|
||||
if (parentClassList && parentClassList.contains("mark-element-unit")) {
|
||||
parentClassList.remove("mark-element-unit");
|
||||
element.isRemoveParentStyle = true;
|
||||
}
|
||||
|
||||
element.classList.add("mark-element-unit");
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
element.addEventListener("mouseleave", (event) => {
|
||||
element.classList.remove("mark-element-unit");
|
||||
if (element.isRemoveParentStyle) {
|
||||
element.parentElement.classList.add("mark-element-unit");
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
});
|
||||
}
|
||||
177
src/utils/lineHelper.js
Normal file
177
src/utils/lineHelper.js
Normal file
@@ -0,0 +1,177 @@
|
||||
let currentPostion = null,
|
||||
currentTarget = null,
|
||||
preSelectTarget = null; // 记录上一次鼠标所在位置
|
||||
const TOP = 1,
|
||||
MIDDLE = 2,
|
||||
BOTTOM = 3;
|
||||
|
||||
import { findCodeElemNode, findRawVueInfo } from "@/utils/forCode";
|
||||
import { getRawComponentContent } from "@/utils/common";
|
||||
|
||||
export function initContainerForLine(targetElement, _currentPointer = () => {}) {
|
||||
const crossX = document.querySelector(".x");
|
||||
|
||||
const currentPointer = (...args) => {
|
||||
_currentPointer(...args);
|
||||
};
|
||||
|
||||
targetElement.addEventListener("dragover", (event) => {
|
||||
event.preventDefault();
|
||||
drawLine(event);
|
||||
});
|
||||
|
||||
targetElement.addEventListener("dragleave", (event) => {
|
||||
if (event.target === targetElement) {
|
||||
targetElement.classList.remove("in-element");
|
||||
crossX.style = "display: none;";
|
||||
} else {
|
||||
clearTargetOutline();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 获得一个元素在父元素中的索引
|
||||
* @param {*} element
|
||||
* @returns
|
||||
*/
|
||||
function findElementIndex(element) {
|
||||
// 根据代码结构查找
|
||||
const parentElementNode = findCodeElemNode(element.parentElement);
|
||||
const lc_id = element.getAttribute("lc_id");
|
||||
|
||||
if (parentElementNode) {
|
||||
const parentRawInfo = findRawVueInfo(parentElementNode);
|
||||
|
||||
const attributes = getRawComponentContent(parentRawInfo);
|
||||
if (attributes) {
|
||||
const childrenArray = attributes.__children;
|
||||
|
||||
const index = childrenArray.findIndex((item) => {
|
||||
return getRawComponentContent(item).lc_id == lc_id;
|
||||
});
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
function clearTargetOutline() {
|
||||
if (preSelectTarget) {
|
||||
preSelectTarget.classList.remove("in-element");
|
||||
}
|
||||
}
|
||||
|
||||
function drawLine(event) {
|
||||
const realTarget = event.target;
|
||||
|
||||
// 2021年03月26日15:56:35 新的逻辑是:只有上下定位辅助线,不再计算左右辅助线
|
||||
const directionObj = judgeTopOrBottom(realTarget, event.clientX, event.clientY);
|
||||
const position = getElCoordinate(realTarget);
|
||||
|
||||
// 如果鼠标点在目标的上部分则绘制上部分辅助线
|
||||
if (directionObj.top && targetElement !== realTarget) {
|
||||
if (currentPostion === TOP && currentTarget === realTarget) {
|
||||
return;
|
||||
}
|
||||
currentPostion = TOP;
|
||||
currentTarget = realTarget;
|
||||
|
||||
clearTargetOutline();
|
||||
|
||||
crossX.style = `top:${position.top}px;width:${position.width}px;left:${position.left}px;display:block;`;
|
||||
|
||||
currentPointer(realTarget.parentElement, findElementIndex(realTarget));
|
||||
} else if (directionObj.bottom && targetElement !== realTarget) {
|
||||
// 如果鼠标点在目标的下部分,则绘制下部分辅助线
|
||||
if (currentPostion === BOTTOM && currentTarget === realTarget) {
|
||||
return;
|
||||
}
|
||||
currentPostion = BOTTOM;
|
||||
currentTarget = realTarget;
|
||||
|
||||
clearTargetOutline();
|
||||
|
||||
crossX.style = `top:${position.bottom}px;width:${position.width}px;left:${position.left}px;display:block;`;
|
||||
|
||||
currentPointer(realTarget.parentElement, findElementIndex(realTarget) + 1);
|
||||
} else {
|
||||
currentPostion = MIDDLE;
|
||||
currentTarget = realTarget;
|
||||
|
||||
realTarget.classList.add("in-element");
|
||||
preSelectTarget = realTarget;
|
||||
|
||||
crossX.style = `display:none;`;
|
||||
|
||||
currentPointer(realTarget, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取一个元素在屏幕上的坐标点
|
||||
function getElCoordinate(e) {
|
||||
const rect = e.getBoundingClientRect();
|
||||
return rect;
|
||||
}
|
||||
|
||||
// 判断一个点是否在该元素内
|
||||
function judgeEleIsContentPoint(e, x, y) {
|
||||
const position = getElCoordinate(e);
|
||||
|
||||
return x >= position.left && x <= position.right && y >= position.top && y <= position.bottom;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断上还是下
|
||||
* @param {*} e
|
||||
* @param {*} x
|
||||
* @param {*} y
|
||||
* @returns
|
||||
*/
|
||||
function judgeTopOrBottom(e, x, y) {
|
||||
const position = getElCoordinate(e);
|
||||
|
||||
const cutDistance = Math.round((position.bottom - position.top) / 3);
|
||||
|
||||
return {
|
||||
top: y < position.top + cutDistance,
|
||||
middle: y >= position.top + cutDistance && y <= position.top + cutDistance * 2,
|
||||
bottom: y > position.top + cutDistance * 2,
|
||||
};
|
||||
}
|
||||
|
||||
// 判断点在元素的方向
|
||||
function direction(e, x, y) {
|
||||
const position = getElCoordinate(e);
|
||||
|
||||
// 基本方向判定
|
||||
const direction = {
|
||||
left: x < position.left ? position.left - x : 0,
|
||||
right: x > position.right ? x - position.right : 0,
|
||||
top: y < position.top ? position.top - y : 0,
|
||||
bottom: y > position.bottom ? y - position.bottom : 0,
|
||||
};
|
||||
|
||||
// 判定方向更靠近哪个
|
||||
let count = 0;
|
||||
let directionStrArray = [];
|
||||
for (const key in direction) {
|
||||
const element = direction[key];
|
||||
if (element) {
|
||||
directionStrArray.push(key);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count === 2) {
|
||||
// 进一步判定更靠近哪个方向
|
||||
const num1 = direction[directionStrArray[0]];
|
||||
const num2 = direction[directionStrArray[1]];
|
||||
|
||||
direction[directionStrArray[0]] = num1 > num2;
|
||||
direction[directionStrArray[1]] = num2 > num1;
|
||||
}
|
||||
|
||||
direction.position = position;
|
||||
|
||||
return direction;
|
||||
}
|
||||
55
src/utils/params.js
Normal file
55
src/utils/params.js
Normal file
@@ -0,0 +1,55 @@
|
||||
import qs from 'query-string';
|
||||
import deepmerge from 'deepmerge';
|
||||
|
||||
const DEFAULT_PARAMS = {
|
||||
pkgs: ['https://static.imonkey.xueersi.com/vue-creater-platform/resource/vue.js', 'https://static.imonkey.xueersi.com/vue-creater-platform/resource/element-ui/index.js'],
|
||||
css: ['https://static.imonkey.xueersi.com/vue-creater-platform/resource/element-ui/index.css'],
|
||||
};
|
||||
|
||||
let params = DEFAULT_PARAMS;
|
||||
|
||||
function getArr(str) {
|
||||
if (Array.isArray(str)) {
|
||||
return str;
|
||||
}
|
||||
if (typeof str === 'string') {
|
||||
return str.split(',');
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
export function clear() {
|
||||
params = DEFAULT_PARAMS;
|
||||
}
|
||||
|
||||
export function parse(str) {
|
||||
try {
|
||||
merge(JSON.parse(str));
|
||||
} catch (e) {
|
||||
console.error('error', e.message);
|
||||
}
|
||||
}
|
||||
|
||||
export function queryParse(str) {
|
||||
const query = qs.parse(str);
|
||||
const pkgs = getArr(query.pkg);
|
||||
const css = getArr(query.css);
|
||||
const options = { pkgs, css };
|
||||
|
||||
if (query.cdn) {
|
||||
options.cdn = query.cdn;
|
||||
}
|
||||
if (query.vue) {
|
||||
options.vue = query.vue;
|
||||
}
|
||||
|
||||
merge(options);
|
||||
}
|
||||
|
||||
export function get() {
|
||||
return deepmerge(DEFAULT_PARAMS, params);
|
||||
}
|
||||
|
||||
export function merge(opts) {
|
||||
params = deepmerge(params, opts);
|
||||
}
|
||||
35
src/utils/store.js
Normal file
35
src/utils/store.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import Vue from 'vue';
|
||||
import { stringify } from 'query-string';
|
||||
|
||||
const API = 'https://text.cinwell.xyz';
|
||||
|
||||
export async function upload(text) {
|
||||
Vue.toasted.show('Saving...');
|
||||
|
||||
try {
|
||||
const result = await fetch(API, {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
|
||||
},
|
||||
body: stringify({
|
||||
text,
|
||||
hash: 1
|
||||
})
|
||||
});
|
||||
|
||||
Vue.toasted.clear();
|
||||
|
||||
return await result.text();
|
||||
} catch (e) {
|
||||
Vue.toasted.clear();
|
||||
Vue.toasted.show('Failed: ' + e.message, {
|
||||
type: 'error',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function downloadURL(hash) {
|
||||
return `${API}/${hash}`;
|
||||
}
|
||||
Reference in New Issue
Block a user