Source location: vue – next/packages/compile – core/SRC/transforms/vOn ts vue – next/packages/compile – core/SRC/transforms/vBind ts
So far the transform module is basically implemented, but we need to deal with v-ON and V-bind as a simple example of what instruction compilation does. Okay
explain
DirectiveTransforms directiveTransforms is a class of transform plugins that include some transformOn and transformBind instruction handlers. This article transforms these two commands to do trivial tasks. Just to summarize
- Different processing is performed for different instructions
- V-on requires humping event listeners, handling event listener caches, and application extension plug-ins
- V-bind needs to handle some pre-modifiers and do some fault tolerance
- Wrap the instruction content into
JS_PROPERTY
The object returned
Write a transformOn
Two utility functions
So let’s write two utility functions here
capitalize
When it comes to humping event listeners, you need a utility function
function camelize(str) {
return str.replace(
/-(\w)/g.(neverUse, c) = > (c ? c.toUpperCase() : ' ')); }Copy the code
The first argument to replace takes a regular expression, while the second argument takes a callback that looks a lot like the result returned by regexp.exec (). The first argument is the matched substring, and the second argument starts with capturing the contents of the group. Here’s an example
const str = 'yes-this-is-my-handler';
// In the example above
// nerverUse is ['-t', '-i', '-m', '-h']
// c is ['t', 'I ', 'm', 'h']
camelize(str); // yesThisIsMyHandler
Copy the code
toHandlerKey
Here is a tool function to convert XXX-xx to onxxxXx, it is very simple
const toHandlerKey = str= > (str ? `on${capitalize(str)}` : ' ')
Copy the code
transformOn
What we do in transformOn is pretty cumbersome, but what we do in transformOn is very simple, we just need to hump the event listener and return it wrapped as an object of type JS_PROPERTY
const transformOn = dir= > {
const { arg } = dir;
/ / the hump
let eventName;
if (arg.type === NodeTypes.SIMPLE_EXPRESSION) {
if (arg.isStatic) {
const rawName = arg.content;
eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true);
}
// The source code here handles dynamic event names into composite expressions
} else {
eventName = arg;
}
// Process the expression
let exp = dir.exp;
if(exp && ! exp.content.trim()) { exp =undefined;
}
// The source code handles event caching here
// The source code handles the external plug-in extended Compiler augmentor
// Wrap and return the JS_PROPERTY node
let ret = {
props: [
createObjectProperty(
eventName,
exp || createSimpleExpression('() = > {}'.false)),]};return ret;
};
Copy the code
Write a transformBind
TransformBind does a lot of simple things: fault tolerance, adding prefixes, wrapping nodes, just look at the code
const transformBind = dir= > {
const { exp, modifiers } = dir;
const arg = dir.arg;
// Error tolerance, output an empty string if null
if(arg.type ! == NodeTypes.SIMPLE_EXPRESSION) { arg.children.unshift('(');
arg.children.push(') | | "" ');
} else if(! arg.isStatic) { arg.content =`${arg.content}| | "" `;
}
// prop adds a "." prefix
// attr adds the "^" prefix
if (modifiers.includes('prop')) {
injectPrefix(arg, '. ');
}
if (modifiers.includes('attr')) {
injectPrefix(arg, A '^');
}
// Wrap and return the JS_PROPERTY node
if(! exp || (exp.type === NodeTypes.SIMPLE_EXPRESSION && ! exp.content.trim()) ) {return {
props: [createObjectProperty(arg, createSimpleExpression(' '.true))]}; }return {
props: [createObjectProperty(arg, exp)],
};
};
// prefix handlers
const injectPrefix = (arg, prefix) = > {
if (arg.type === NodeTypes.SIMPLE_EXPRESSION) {
if (arg.isStatic) {
arg.content = prefix + arg.content;
} else {
arg.content = ` \ `${prefix}\ ${${arg.content}} \ ` `; }}else {
arg.children.unshift(` '${prefix}'+ (`);
arg.children.push(`) `); }};Copy the code
conclusion
These are implementations of transformOn and transformBind, both of which are directiveTransforms called when we transform elements. These transforms only process args directives because no ARgs directives are already processed inside transformElements. They are very similar to nodeTransforms. In fact, other instructions, such as V-Model and V-for, will be packaged. The rest instructions will not be implemented due to the author’s limited level and energy