mirror of
https://gitee.com/newgateway/vtj.git
synced 2026-06-30 23:45:12 +08:00
feat: ✨ parser支持自定义指令
This commit is contained in:
@@ -58,14 +58,16 @@ export async function parseVue(options: IParseVueOptions) {
|
||||
inject,
|
||||
handlers,
|
||||
imports,
|
||||
dataSources
|
||||
dataSources,
|
||||
directives
|
||||
} = parseScripts(sfc.script, project);
|
||||
|
||||
const { nodes, slots, context } = parseTemplate(id, name, sfc.template, {
|
||||
platform,
|
||||
handlers,
|
||||
styles,
|
||||
imports
|
||||
imports,
|
||||
directives
|
||||
});
|
||||
|
||||
const dsl: BlockSchema = {
|
||||
|
||||
@@ -18,7 +18,8 @@ import type {
|
||||
BlockEmit,
|
||||
BlockInject,
|
||||
DataSourceSchema,
|
||||
ProjectSchema
|
||||
ProjectSchema,
|
||||
JSExpression
|
||||
} from '@vtj/core';
|
||||
import {
|
||||
getJSExpression,
|
||||
@@ -47,6 +48,7 @@ export interface ParseScriptsResult {
|
||||
inject?: BlockInject[];
|
||||
handlers?: Record<string, JSFunction>;
|
||||
dataSources?: Record<string, DataSourceSchema>;
|
||||
directives?: Record<string, JSExpression>;
|
||||
errors: string[];
|
||||
}
|
||||
|
||||
@@ -109,6 +111,9 @@ export function parseScripts(content: string, project: ProjectSchema) {
|
||||
case 'expose':
|
||||
result.expose = processExpose(item.value as any);
|
||||
break;
|
||||
case 'directives':
|
||||
result.directives = processDirectives(item.value as any);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -560,3 +565,19 @@ function processExpose(expression: ArrayExpression) {
|
||||
function findApi(project: ProjectSchema, id: string) {
|
||||
return (project.apis || []).find((n) => n.id === id);
|
||||
}
|
||||
|
||||
function processDirectives(expression: ObjectExpression) {
|
||||
if (!expression?.properties) return {};
|
||||
const map: Record<string, JSExpression> = {};
|
||||
for (const item of expression.properties) {
|
||||
const { key, value } = item as any;
|
||||
if (key?.name && value?.name) {
|
||||
map[key.name] = map[key.name.toLowerCase()] = {
|
||||
type: 'JSExpression',
|
||||
value: value.name
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import { type ImportStatement } from './scripts';
|
||||
let __slots: BlockSlot[] = [];
|
||||
let __context: Record<string, Set<string>> = {};
|
||||
let __handlers: Record<string, JSFunction> = {};
|
||||
let __directives: Record<string, JSExpression> = {};
|
||||
let __styles: CSSRules = {};
|
||||
let __platform: PlatformType = 'web';
|
||||
let __imports: ImportStatement[] = [];
|
||||
@@ -46,6 +47,7 @@ export interface ParseTemplateOptions {
|
||||
imports?: ImportStatement[];
|
||||
handlers?: Record<string, JSFunction>;
|
||||
styles?: CSSRules;
|
||||
directives?: Record<string, JSExpression>;
|
||||
}
|
||||
|
||||
export function parseTemplate(
|
||||
@@ -60,6 +62,7 @@ export function parseTemplate(
|
||||
__styles = options?.styles || {};
|
||||
__platform = options?.platform || 'web';
|
||||
__imports = options?.imports || [];
|
||||
__directives = options?.directives || {};
|
||||
|
||||
const result = compileTemplate({
|
||||
id,
|
||||
@@ -213,6 +216,8 @@ function getDirectives(
|
||||
branches?: any[]
|
||||
) {
|
||||
const directives: NodeDirective[] = [];
|
||||
const builtIns = ['if', 'for', 'model', 'show', 'bind', 'html'];
|
||||
|
||||
// v-if
|
||||
if (
|
||||
branches &&
|
||||
@@ -249,6 +254,7 @@ function getDirectives(
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (node.type === NodeTypes.ELEMENT) {
|
||||
const directivProps = node.props.filter(
|
||||
(prop) => prop.type === NodeTypes.DIRECTIVE
|
||||
@@ -291,6 +297,28 @@ function getDirectives(
|
||||
value: getJSExpression(vHtml.exp?.loc.source || '')
|
||||
});
|
||||
}
|
||||
|
||||
const others = directivProps.filter((n) => !builtIns.includes(n.name));
|
||||
|
||||
for (const item of others) {
|
||||
const modifiers = (item.modifiers || []).reduce(
|
||||
(result, cur) => {
|
||||
result[cur.content] = true;
|
||||
return result;
|
||||
},
|
||||
{} as Record<string, boolean>
|
||||
);
|
||||
const arg: string = (item as any).arg?.content || undefined;
|
||||
const directiveName = __directives[item.name];
|
||||
if (directiveName) {
|
||||
directives.push({
|
||||
name: directiveName,
|
||||
value: getJSExpression(item.exp?.loc.source || ''),
|
||||
arg,
|
||||
modifiers
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return directives;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user