Skip to content

v-text ディレクティブ

以下のようなコンポーネントを考えます.

vue
<script setup>
import { ref } from "vue";
const message = ref("Hello, v-text!");
</script>

<template>
  <p v-text="message" />
</template>

コンパイル結果と概要

コンパイル結果は以下のようになります.

js
const _sfc_main = {
  vapor: true,
  __name: "App",
  setup(__props, { expose: __expose }) {
    __expose();

    const message = ref("Hello, v-text!");

    const __returned__ = { message, ref };
    Object.defineProperty(__returned__, "__isScriptSetup", {
      enumerable: false,
      value: true,
    });
    return __returned__;
  },
};

import {
  renderEffect as _renderEffect,
  setText as _setText,
  template as _template,
} from "vue/vapor";

const t0 = _template("<p></p>");

function _sfc_render(_ctx) {
  const n0 = t0();
  _renderEffect(() => _setText(n0, _ctx.message));
  return n0;
}

v-text を指定した要素が renderEffectsetText によって構築されるようになりました.

コンパイラを読む

transformElement -> buildProps -> transformProps -> directiveTransform -> transformVText と辿っていきます.

非常にシンプルなので全文載せてしまいます.

1import { DOMErrorCodes, createDOMCompilerError } from '@vue/compiler-dom'
2import { IRNodeTypes } from '../ir'
3import { EMPTY_EXPRESSION } from './utils'
4import type { DirectiveTransform } from '../transform'
5import { getLiteralExpressionValue } from '../utils'
6
7export const transformVText: DirectiveTransform = (dir, node, context) => {
8  let { exp, loc } = dir
9  if (!exp) {
10    context.options.onError(
11      createDOMCompilerError(DOMErrorCodes.X_V_TEXT_NO_EXPRESSION, loc),
12    )
13    exp = EMPTY_EXPRESSION
14  }
15  if (node.children.length) {
16    context.options.onError(
17      createDOMCompilerError(DOMErrorCodes.X_V_TEXT_WITH_CHILDREN, loc),
18    )
19    context.childrenTemplate.length = 0
20  }
21
22  const literal = getLiteralExpressionValue(exp)
23  if (literal != null) {
24    context.childrenTemplate = [String(literal)]
25  } else {
26    context.registerEffect([exp], {
27      type: IRNodeTypes.SET_TEXT,
28      element: context.reference(),
29      values: [exp],
30    })
31  }
32}

registerEffect しているだけです.
transformText の時と似たような処理を行っています.

ランタイムは特に読むところがないので今回もこれでおしまいです. サクサクいきましょう!