解决crud组件渲染无法双向绑定问题

This commit is contained in:
icssoa 2021-04-06 16:51:48 +08:00
parent eaf9be91bf
commit 9fcd212900
18 changed files with 113 additions and 118 deletions

View File

@ -9,6 +9,7 @@
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=0"
/>
<title>COOL-ADMIN</title>
<link rel="icon" href="favicon.ico" />
<style>
html,
@ -73,15 +74,11 @@
<div class="container">
<p class="name">COOL-ADMIN</p>
<p class="title">正在加载资源...</p>
<p class="sub-title">
初次加载资源可能需要较多时间 请耐心等待
</p>
<p class="sub-title">初次加载资源可能需要较多时间 请耐心等待</p>
</div>
<div class="footer">
<a href="https://cool-js.com/" target="_blank">
https://cool-js.com
</a>
<a href="https://cool-js.com/" target="_blank"> https://cool-js.com </a>
</div>
</div>
</div>

View File

@ -1,6 +1,6 @@
{
"name": "front-next",
"version": "0.2.3",
"version": "0.2.4",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit --skipLibCheck && vite build",

View File

@ -123,7 +123,6 @@ export default defineComponent({
// ids
function rowClick(e: any) {
ContextMenu.close();
const ids = e.children ? revDeepTree(e.children).map((e) => e.id) : [];
ids.unshift(e.id);
emit("row-click", { item: e, ids });

View File

@ -1,7 +1,6 @@
<template>
<div class="cl-menu-icons">
<el-popover
:visible="visible"
placement="bottom-start"
trigger="click"
width="480px"

View File

@ -39,5 +39,7 @@ export function createLink(url: string, id?: string) {
link.id = id;
}
document.getElementsByTagName("head")?.item(0)?.appendChild(link);
setTimeout(() => {
document.getElementsByTagName("head").item(0)?.appendChild(link);
}, 0);
}

View File

@ -1,4 +1,5 @@
import { defineComponent, nextTick, onMounted, reactive, ref } from "vue";
import type { PropType } from "vue";
import { useRefs } from "../../hooks/core";
import { contains } from "../../utils";
import { ContextMenuItem, ContextMenuOptions } from "../../types";
@ -7,7 +8,12 @@ export default defineComponent({
name: "cl-context-menu",
props: {
visible: Boolean
visible: Boolean,
options: {
type: Object as PropType<ContextMenuOptions>,
default: () => []
},
event: Object
},
setup(props) {
@ -134,6 +140,9 @@ export default defineComponent({
close();
}
});
// 默认打开
open(props.event, props.options);
}
});

View File

@ -2,24 +2,14 @@ import { h, render } from "vue";
import ContextMenuConstructor from "./context-menu";
class ContextMenu {
ctx: any = null;
open(event: any, options: any) {
const vm: any = h(ContextMenuConstructor, {
visible: true
visible: true,
event,
options
});
// 渲染节点
render(vm, document.createElement("div"));
this.ctx = vm.component.ctx;
return this.ctx?.open(event, options);
}
close() {
if (this.ctx) {
this.ctx.close();
}
}
}

View File

@ -47,9 +47,7 @@ export const bootstap = (crud: any, { fn }: any) => {
return ctx;
};
ctx.done = function () {
console.log("crud done");
};
ctx.done = function () {};
return { ctx, app };
};

View File

@ -179,6 +179,7 @@ export default defineComponent({
break;
case "props":
case "on":
case "op":
case "dialog":
case "_data":
conf[i] = deepMerge(conf[i], options[i] || {});

View File

@ -547,7 +547,7 @@
table {
th {
background-color: #ebeef5;
padding: 8px 0;
padding: 3px 0;
font-size: 14px;
}

View File

@ -34,7 +34,12 @@ export interface Form {
close?(done: Function): void;
submit?(data: any, { done, close }: any): void;
};
op?: any;
op?: {
hidden?: boolean;
saveButtonText?: string;
closeButtonText?: string;
buttons?: Array<"close" | "save">;
};
dialog?: {
props?: any;
hiddenControls?: boolean;

View File

@ -8,6 +8,7 @@ export interface TableOptions {
| ContextMenuItem
| Function
| "refresh"
| "check"
| "update"
| "delete"
| "order-desc"

View File

@ -1,12 +1,12 @@
import { isFunction, isString, isObject, isEmpty } from "./index";
import { h, resolveComponent, toRaw } from "vue";
import { h, resolveComponent } from "vue";
import { isFunction, isString, isObject } from "./index";
/**
*
* @param {*} vnode
* @param {{scope,prop,children}} options
*/
const parseNode = (vnode: any, options: any) => {
function parseNode(vnode: any, options: any) {
const { scope, prop, slots } = options || [];
// 插槽模式渲染
@ -24,23 +24,24 @@ const parseNode = (vnode: any, options: any) => {
const props = {
...vnode,
...vnode.attrs,
...vnode.props
...vnode.props,
scope
};
// 删除多余数据
delete props._children;
// 添加双向绑定
if (props && scope) {
// 添加双向绑定
props.modelValue = scope[prop];
props["onUpdate:modelValue"] = function (val: any) {
scope[prop] = val;
};
}
// 组件实例渲染,转普通对象
// 组件实例渲染
if (props.render) {
return h(toRaw(props));
return h(props, props);
}
// @ts-ignore
@ -49,7 +50,7 @@ const parseNode = (vnode: any, options: any) => {
return vnode._children;
}
});
};
}
/**
*

View File

@ -50,9 +50,10 @@
<script lang="ts">
import { defineComponent, ref, resolveComponent, h } from "vue";
import Test from "./test.vue";
import { TestService } from "../../utils/service";
import { CrudLoad, FormItem, FormRef } from "/$/crud/types";
import { TestService } from "../../utils/service";
import Test from "./render/test.vue";
import Test2 from "./render/test2";
export default defineComponent({
setup() {
@ -86,30 +87,10 @@ export default defineComponent({
component: Test
},
{
label: "jsx",
component: {
name: "render-jsx",
setup() {
const value = ref<string>("Hello");
return {
value
};
},
render(ctx: any) {
return h(
"p",
{},
{
default: () => {
return ctx.value;
}
}
);
}
}
label: "tsx",
prop: "tsx",
value: "Hello!",
component: Test2
},
{
props: {
@ -295,7 +276,13 @@ export default defineComponent({
props: {
labelWidth: "140px"
},
items
items,
on: {
submit(data, { done }) {
console.log(data);
done();
}
}
});
}

View File

@ -0,0 +1,30 @@
import { defineComponent, ref } from "vue";
export default defineComponent({
name: "test2",
props: {
modelValue: String,
scope: null
},
emits: ["update:modelValue", "change"],
setup(props, { emit }) {
const value = ref<string>(props.modelValue || "");
function onChange(val: string) {
emit("update:modelValue", val);
emit("change", val);
}
return {
value,
onChange
};
},
render(ctx: any) {
return <el-input v-model={ctx.value} size="mini" onChange={ctx.onChange} />;
}
});

View File

@ -5,9 +5,10 @@
</template>
<script lang="ts">
import { TableColumn } from "/$/crud/types";
import { defineComponent, onMounted, ref } from "vue";
import { TableColumn } from "/$/crud/types";
import { useRefs } from "/@/core";
import Test2 from "./render/test2";
export default defineComponent({
setup() {
@ -22,13 +23,7 @@ export default defineComponent({
label: "姓名",
prop: "name",
minWidth: 120,
component: {
name: "el-input",
props: {
size: "mini",
clearable: true
}
}
component: Test2
},
{
label: "存款",

View File

@ -1,25 +1,35 @@
Arguments:
F:\node\node.exe C:\Users\sss\AppData\Roaming\npm\node_modules\yarn\bin\yarn.js add @rollup/plugin-dynamic-import-vars -D
D:\node\node.exe C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\bin\yarn.js add 1.0.2-beta.35
PATH:
C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;F:\node\;F:\Git\cmd;F:\tortoiseSVN\bin;C:\Program Files\python;C:\Program Files\python\Scripts;;F:\BtSoft\panel\script;C:\Users\sss\AppData\Local\Microsoft\WindowsApps;;F:\Microsoft VS Code\bin;C:\Users\sss\AppData\Roaming\npm
C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\intel64\compiler;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\windows\System32\OpenSSH\;D:\Tortoise\bin;C:\Program Files\Git\cmd;C:\Program Files\python;C:\Program Files\python\Scripts;;D:\BtSoft\panel\script;D:\node\;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;;D:\cool\Microsoft VS Code\bin;C:\Users\Administrator\AppData\Roaming\npm
Yarn version:
1.22.10
1.22.5
Node version:
12.16.3
14.16.0
Platform:
win32 x64
Trace:
Error: EPERM: operation not permitted, unlink 'F:\project\cool-admin\front-next\node_modules\esbuild\esbuild.exe'
Error: https://registry.yarnpkg.com/1.0.2-beta.35: Not found
at Request.params.callback [as _callback] (C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\lib\cli.js:66988:18)
at Request.self.callback (C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\lib\cli.js:140662:22)
at Request.emit (events.js:315:20)
at Request.<anonymous> (C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\lib\cli.js:141634:10)
at Request.emit (events.js:315:20)
at IncomingMessage.<anonymous> (C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\lib\cli.js:141556:12)
at Object.onceWrapper (events.js:421:28)
at IncomingMessage.emit (events.js:327:22)
at endReadableNT (internal/streams/readable.js:1327:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21)
npm manifest:
{
"name": "front-next",
"version": "0.2.2",
"version": "0.2.3",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit --skipLibCheck && vite build",
@ -35,7 +45,7 @@ npm manifest:
"codemirror": "^5.60.0",
"core-js": "^3.6.5",
"echarts": "^5.0.2",
"element-plus": "1.0.2-beta.35",
"element-plus": "^1.0.2-beta.36",
"glob": "^7.1.6",
"js-beautify": "^1.13.5",
"lodash": "^4.17.21",
@ -58,7 +68,7 @@ npm manifest:
"@types/node": "^14.14.37",
"@typescript-eslint/eslint-plugin": "^4.20.0",
"@typescript-eslint/parser": "^4.20.0",
"@vitejs/plugin-vue": "^1.1.5",
"@vitejs/plugin-vue": "^1.2.1",
"@vitejs/plugin-vue-jsx": "^1.1.3",
"@vue/compiler-sfc": "^3.0.5",
"@vue/composition-api": "^1.0.0-rc.6",
@ -373,25 +383,6 @@ Lockfile:
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.9.1.tgz#7f554e7368c9ab679a11f4a042ca17149d70cf12"
integrity sha512-DvJbbn3dUgMxDnJLH+RZQPnXak1h4ZVYQ7CWiFWjQwBFkVajT4rfw2PdpHLTSTwxrYfnoEXkuBiwkDm6tPMQeA==
"@rollup/plugin-dynamic-import-vars@^1.1.1":
version "1.1.1"
resolved "https://registry.npmjs.org/@rollup/plugin-dynamic-import-vars/-/plugin-dynamic-import-vars-1.1.1.tgz#d72142fd9e450bcf5e17624adf4f4d4c25d7daec"
integrity sha512-PqdfEKlsyPx0hPSSuOigCHgrQbOLW+y09KRRCFeWiBBnkuh4LlV6mfrDefmLQijj8XCWzyLct2rK+q89qvRp7A==
dependencies:
"@rollup/pluginutils" "^3.1.0"
estree-walker "^2.0.1"
globby "^11.0.1"
magic-string "^0.25.7"
"@rollup/pluginutils@^3.1.0":
version "3.1.0"
resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b"
integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==
dependencies:
"@types/estree" "0.0.39"
estree-walker "^1.0.1"
picomatch "^2.2.2"
"@rollup/pluginutils@^4.1.0":
version "4.1.0"
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.1.0.tgz#0dcc61c780e39257554feb7f77207dceca13c838"
@ -405,11 +396,6 @@ Lockfile:
resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.10.tgz#ef5b1589b9f16544642e473db5ea5639107ef3ea"
integrity sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==
"@types/estree@0.0.39":
version "0.0.39"
resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
"@types/json-schema@^7.0.3":
version "7.0.7"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
@ -506,10 +492,10 @@ Lockfile:
"@vue/babel-plugin-jsx" "^1.0.3"
hash-sum "^2.0.0"
"@vitejs/plugin-vue@^1.1.5":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-1.2.0.tgz#f0a92470b74761f90afc8cda204fa3bec9df09f4"
integrity sha512-IhSJfJH6IDNEAnhr91+2vhLLe/1SqkA/2BP19jwtn54DGI+cNbZIxiPhHIdKUpdRo0QwErOh6Jy1Maxk2uVo7A==
"@vitejs/plugin-vue@^1.2.1":
version "1.2.1"
resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-1.2.1.tgz#6de49436fc346f829a56676066428e3f011522ac"
integrity sha512-TG+LbEUNwfFrx1VyN+iq+PsiGd9MT16hUdJY+BnMXj3MrLAF8m3VYUspTDM3aXoh48YDmAkMjG4gWFRg3lbG5A==
"@vue/babel-helper-vue-transform-on@^1.0.2":
version "1.0.2"
@ -1358,10 +1344,10 @@ Lockfile:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.701.tgz#5e796ed7ce88cd77bc7bf831cf311ef6b067c389"
integrity sha512-Zd9ofdIMYHYhG1gvnejQDvC/kqSeXQvtXF0yRURGxgwGqDZm9F9Fm3dYFnm5gyuA7xpXfBlzVLN1sz0FjxpKfw==
element-plus@1.0.2-beta.35:
version "1.0.2-beta.35"
resolved "https://registry.yarnpkg.com/element-plus/-/element-plus-1.0.2-beta.35.tgz#158890bddf28f8495f261d02789bf394c5c97123"
integrity sha512-T12EfxbWoNOrWE2bzXFPJdOU3cl4YWuLwxE5QKM40oPw1VYPMRrRB8Uy5TwF8h3itxzsJQ5iFj2rdDO+q3Jcdg==
element-plus@^1.0.2-beta.36:
version "1.0.2-beta.36"
resolved "https://registry.yarnpkg.com/element-plus/-/element-plus-1.0.2-beta.36.tgz#78a7e1be10b9622c4fc342fdce0801650f30bb01"
integrity sha512-5Qc54rH0GGtFRXpfA4ilpcOzdAw6t2m4mBXMXYjs9c5RSYP+EV+gJyfhyolXqZoOtYZ35ovBcqljlIJJD6Nz7g==
dependencies:
"@popperjs/core" "^2.4.4"
async-validator "^3.4.0"
@ -1608,11 +1594,6 @@ Lockfile:
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880"
integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==
estree-walker@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700"
integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==
estree-walker@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
@ -3751,7 +3732,7 @@ Lockfile:
vite@^2.1.5:
version "2.1.5"
resolved "https://registry.yarnpkg.com/vite/-/vite-2.1.5.tgz#4857da441c62f7982c83cbd5f42a00330f20c9c1"
resolved "https://registry.npmjs.org/vite/-/vite-2.1.5.tgz#4857da441c62f7982c83cbd5f42a00330f20c9c1"
integrity sha512-tYU5iaYeUgQYvK/CNNz3tiJ8vYqPWfCE9IQ7K0iuzYovWw7lzty7KRYGWwV3CQPh0NKxWjOczAqiJsCL0Xb+Og==
dependencies:
esbuild "^0.9.3"