You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

210 lines
7.6 KiB

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformModel = void 0;
const shared_1 = require("@vue/shared");
const compiler_core_1 = require("@vue/compiler-core");
const compiler_dom_1 = require("@vue/compiler-dom");
const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared");
const runtimeHelpers_1 = require("../runtimeHelpers");
const codegen_1 = require("../codegen");
const vOn_1 = require("./vOn");
const transformModel = (dir, node, _context) => {
const context = _context;
const baseResult = (0, compiler_core_1.transformModel)(dir, node, _context);
// base transform has errors OR component v-model (only need props)
if (!baseResult.props.length || node.tagType === 1 /* ElementTypes.COMPONENT */) {
return transformComponentVModel(baseResult.props, node, context);
}
if (dir.arg) {
context.onError((0, compiler_dom_1.createDOMCompilerError)(56 /* DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));
}
function checkDuplicatedValue() {
const value = (0, compiler_core_1.findProp)(node, 'value');
if (value) {
context.onError((0, compiler_dom_1.createDOMCompilerError)(58 /* DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
}
}
const { tag } = node;
if (tag === 'input' || tag === 'textarea') {
checkDuplicatedValue();
}
else {
context.onError((0, compiler_dom_1.createDOMCompilerError)(55 /* DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
}
if (dir.modifiers.length) {
const arg = dir.arg;
const modifiers = dir.modifiers
.map((m) => ((0, compiler_core_1.isSimpleIdentifier)(m) ? m : JSON.stringify(m)) + `: true`)
.join(`, `);
const modifiersKey = arg
? (0, compiler_core_1.isStaticExp)(arg)
? `${arg.content}Modifiers`
: (0, compiler_core_1.createCompoundExpression)([arg, ' + "Modifiers"'])
: `modelModifiers`;
baseResult.props.push((0, compiler_core_1.createObjectProperty)(modifiersKey, (0, compiler_core_1.createSimpleExpression)(`{ ${modifiers} }`, false, dir.loc, 2 /* ConstantTypes.CAN_HOIST */)));
}
return transformElementVModel(baseResult.props, node, context);
};
exports.transformModel = transformModel;
function findInputDirectiveNode(props) {
return props.find((prop) => prop.type === 7 /* NodeTypes.DIRECTIVE */ &&
prop.name === 'on' &&
prop.arg?.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ &&
prop.arg.content === 'input');
}
function transformElementVModel(props, node, context) {
const dirs = transformVModel(props, node, context, {
isComponent: false,
binding: 'value',
event: 'input',
formatEventCode(code) {
return code.replace(/=\s\$event/g, `= $event.detail.value`);
},
});
if (dirs.length === 2) {
// 快手小程序的 input v-model 被转换到 data-e-o 中,补充到 data-e-o 中
const inputExp = findDatasetEventOpts(node);
if (inputExp) {
inputExp.children[2] = combineVOn(dirs[1].exp, inputExp.children[2], node, context);
dirs.length = 1;
}
else {
const inputDir = findInputDirectiveNode(node.props);
if (inputDir && inputDir.exp) {
// 合并到已有的 input 事件中
inputDir.exp = combineVOn(dirs[1].exp, inputDir.exp, node, context);
dirs.length = 1;
}
}
}
return { props: dirs };
}
/**
* {
* "type": 7,
* "name": "bind",
* "loc": {},
* "modifiers": [],
* "arg": {
* "type": 4,
* "loc": {},
* "content": "data-e-o",
* "isStatic": true,
* "constType": 3
* },
* "exp": {
* "type": 8,
* "loc": {},
* "children": ["{", {
* "type": 8,
* "loc": {},
* "children": ["'input'", ": ", {
* "type": 8,
* "loc": {},
* "children": ["_o(", {
* "type": 4,
* "content": "_ctx.input",
* "isStatic": false,
* "constType": 0,
* "loc": {}
* }, ")"]
* }, ","]
* }, "}"]
* }
* }
* @param node
* @returns
*/
function findDatasetEventOpts(node) {
const eventOptsProp = (0, compiler_core_1.findProp)(node, uni_cli_shared_1.ATTR_DATASET_EVENT_OPTS, true, false);
if (!eventOptsProp) {
return;
}
const { exp } = eventOptsProp;
if (exp?.type !== 8 /* NodeTypes.COMPOUND_EXPRESSION */) {
return;
}
for (let i = 0; i < exp.children.length; i++) {
const childExp = exp.children[i];
if ((0, shared_1.isSymbol)(childExp) || (0, shared_1.isString)(childExp)) {
continue;
}
if (childExp.type !== 8 /* NodeTypes.COMPOUND_EXPRESSION */) {
continue;
}
if (childExp.children[0] !== `'input'`) {
continue;
}
const inputExp = childExp.children[2];
if ((0, shared_1.isSymbol)(inputExp) ||
(0, shared_1.isString)(inputExp) ||
inputExp.type !== 8 /* NodeTypes.COMPOUND_EXPRESSION */) {
continue;
}
return childExp;
}
}
function parseVOn(exp, context) {
return (0, codegen_1.genExpr)(exp).slice(context.helperString(runtimeHelpers_1.V_ON).length + 1, -1);
}
function combineVOn(exp1, exp2, node, context) {
return (0, vOn_1.wrapperVOn)((0, compiler_core_1.createCompoundExpression)([
`[`,
parseVOn(exp1, context),
',',
parseVOn(exp2, context),
`]`,
]), node, context);
}
function transformComponentVModel(props, node, context) {
return {
props: transformVModel(props, node, context, {
isComponent: true,
formatEventCode(code) {
return code;
},
}),
};
}
function transformVModel(props, node, context, { isComponent, binding, event, formatEventCode, }) {
if (props.length < 2) {
return [];
}
const { key: modelValueArg, value: modelValeExpr } = props[0];
const { key: onUpdateArg, value: onUpdateExpr } = props[1];
if (modelValueArg.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */) {
return [];
}
if (onUpdateArg.type !== 4 /* NodeTypes.SIMPLE_EXPRESSION */ ||
!onUpdateArg.content.startsWith('onUpdate:')) {
return [];
}
const vBindModelValue = (0, uni_cli_shared_1.createBindDirectiveNode)(binding || modelValueArg.content, (0, codegen_1.genExpr)(modelValeExpr));
const modifiers = parseVModelModifiers(props[2]);
// onUpdateExpr 通常是 ExpressionNode 或者被 cache 的 ExpressionNode
const vOnValue = (onUpdateExpr.type === 20 /* NodeTypes.JS_CACHE_EXPRESSION */
? onUpdateExpr.value
: onUpdateExpr);
const vOnUpdate = (0, uni_cli_shared_1.createOnDirectiveNode)(event || (0, shared_1.camelize)(onUpdateArg.content.replace('onUpdate:', 'update-')), formatEventCode((0, codegen_1.genExpr)((0, vOn_1.wrapperVOn)(modifiers
? wrapperVModelModifiers(vOnValue, modifiers, context, isComponent)
: vOnValue, node, context))));
return [vBindModelValue, vOnUpdate];
}
function parseVModelModifiers(property) {
if (property &&
(0, uni_cli_shared_1.isSimpleExpressionNode)(property.key) &&
property.key.content.endsWith('Modifiers') &&
(0, uni_cli_shared_1.isSimpleExpressionNode)(property.value)) {
return property.value.content;
}
}
function wrapperVModelModifiers(exp, modifiers, context, isComponent = false) {
return (0, compiler_core_1.createCompoundExpression)([
`${context.helperString(runtimeHelpers_1.WITH_MODEL_MODIFIERS)}(`,
exp,
',',
modifiers,
`${isComponent ? `, true` : ``}`,
`)`,
]);
}