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 intoJS_PROPERTYThe 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