Vueのディレクティブとは、v- で始まる特別な属性で、テンプレートに「条件で表示する」「繰り返す」「イベントを受け取る」などの動きを付ける仕組みです。 Vue 3.5 のビルトインディレクティブは15種類あり、よく使うのは v-if・v-for・v-on(@)・v-bind(:)・v-model の5つです。

この記事では、15種すべてを用途・省略記法・Vue 2 との違いの一覧表にまとめ、コピペで動く例を載せています。さらに、v-if と v-show の切り替え時間と DOM の有無、v-for の key を付けない/index にしたときの入力欄のずれ、イベント修飾子の動きを Playwright(ブラウザ自動操作ツール)で実際に確かめた結果を載せました。後半では v-focus とクリック外判定のカスタムディレクティブも実装します。

Vueディレクティブの早見表

ディレクティブ 用途 省略記法 Vue 2 との違い
v-text 要素のテキストを置き換える なし 同じ
v-html HTML文字列をそのまま挿入 なし 同じ(信頼できる値だけに使う)
v-show CSS の display で表示/非表示 なし 同じ
v-if 条件が真のときだけ要素を作る なし v-for と同じ要素では v-if が先に評価(Vue 2 は逆)
v-else-if v-if の続きの条件 なし 同じ
v-else v-if の残り なし 同じ(分岐ごとの key は自動で付く)
v-for 配列・オブジェクト・数値の繰り返し なし <template v-for> の key は <template> に書く
v-on イベントを受け取る @ .native 修飾子と数値キーコード(@keyup.13)がなくなった
v-bind 属性・props に値を渡す :(.prop は .) .sync がなくなり v-model に統合
v-model 入力欄と値を双方向に結ぶ なし コンポーネントでは modelValue / update:modelValue。複数指定できる
v-slot スロットに渡す中身を指定 # 2.6 で導入。旧 slot / slot-scope 属性は Vue 3 で削除
v-pre 中身をコンパイルせずそのまま表示 なし 同じ
v-once 初回だけ描画し、以後は更新しない なし 同じ
v-memo 依存値が変わらなければ再描画をスキップ なし 3.2 で追加
v-cloak コンパイル前のテンプレートを隠す なし 同じ(ビルドなしの構成でだけ必要)

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Vueのディレクティブ一覧|全15種の使い方とv-if・v-forの実測」

検証した環境

項目 バージョン
Vue 3.5.43
Vite / @vitejs/plugin-vue 8.3.1 / 6.0.9
vue-tsc / TypeScript 3.3.11 / 6.0.3
Playwright(Chromium) 1.56.1
Node.js 22.22.2

すべて <script setup lang="ts"> の単一ファイルコンポーネント(SFC)で書いています。

表示を切り替える:v-if・v-else-if・v-else・v-show

<script setup lang="ts">
import { ref } from 'vue'
const stock = ref(3)
const open = ref(true)
</script>

<template>
  <p v-if="stock === 0">在庫切れ</p>
  <p v-else-if="stock < 5">残りわずか({{ stock }} 個)</p>
  <p v-else>在庫あり</p>

  <!-- 複数の要素をまとめて切り替えるときは template を使う(template 自体は描画されない) -->
  <template v-if="open">
    <h2>お知らせ</h2>
    <p>本日の発送は締め切りました</p>
  </template>

  <div v-show="open">v-show は display: none で隠すだけ</div>
</template>

v-else-if と v-else は、直前の兄弟要素に v-if(または v-else-if)がないと働きません。 間にほかの要素を挟むとコンパイルエラーになります。

v-ifとv-showの違いを実測

3,000 行のリストを v-if と v-show でそれぞれ包み、Playwright から切り替えて DOM の数と時間を測りました。

<!-- ToggleCostPage.vue -->
<script setup lang="ts">
import { ref, nextTick } from 'vue'
const rows = Array.from({ length: 3000 }, (_, i) => ({ id: i, name: `備品 ${i}` }))
const showIf = ref(true)
const showShow = ref(true)

// 計測用:kind のフラグを times 回切り替えて、DOM 更新完了までの時間を測る
;(window as any).__bench = async (kind: 'if' | 'show', times: number) => {
  const flag = kind === 'if' ? showIf : showShow
  const t0 = performance.now()
  for (let i = 0; i < times; i++) {
    flag.value = !flag.value
    await nextTick()
  }
  return performance.now() - t0
}
</script>

<template>
  <section id="by-if">
    <ul v-if="showIf"><li v-for="r in rows" :key="r.id">{{ r.name }}</li></ul>
  </section>
  <section id="by-show">
    <ul v-show="showShow"><li v-for="r in rows" :key="r.id">{{ r.name }}</li></ul>
  </section>
</template>

実行結果(開発モード、Chromium ヘッドレス):

初期 li数 if/show: 3000 3000
非表示時 li数 if/show: 0 3000 | v-show の ul style: display: none;
試行1 20回切替: v-if 255.6ms / v-show 55.5ms
試行2 20回切替: v-if 127.3ms / v-show 57.7ms
試行3 20回切替: v-if 129.7ms / v-show 33.3ms

v-if は非表示にすると要素を DOM から取り除き(li が 0 個)、v-show は display: none を付けるだけで 3,000 個が残ります。 そのため、何度も切り替えるときは v-show のほうが速く、この計測では v-if の 2〜4 倍ほどの差が出ました(時間は環境によって変わるので、比率の目安として見てください)。

観点 v-if v-show
非表示のときの DOM ない(コンポーネントも破棄) ある(display: none)
切り替えのコスト 大きい(作り直す) 小さい(style の変更だけ)
最初に false のときのコスト 小さい(何も作らない) 大きい(隠した状態で作る)
中のコンポーネントの状態 切り替えるたびにリセット 保たれる
<template> に使う できる できない
v-else と組み合わせ できる できない
向いている場面 権限で出し分ける、滅多に変わらない タブ、開閉メニューなど頻繁に切り替える

繰り返す:v-forとkey

<script setup lang="ts">
const items = [{ id: 1, name: 'ペン' }, { id: 2, name: 'ノート' }]
const profile = { name: '山田', role: '編集' }
</script>

<template>
  <!-- 配列(index も受け取れる) -->
  <li v-for="(item, index) in items" :key="item.id">{{ index }}: {{ item.name }}</li>
  <!-- オブジェクト(値, キー, 番号) -->
  <li v-for="(value, key, i) in profile" :key="key">{{ i }} {{ key }}={{ value }}</li>
  <!-- 数値(1 から始まる) -->
  <span v-for="n in 3" :key="n">{{ n }}</span>
  <!-- 複数要素の繰り返し:key は template に書く(Vue 3) -->
  <template v-for="item in items" :key="item.id">
    <dt>{{ item.name }}</dt><dd>ID: {{ item.id }}</dd>
  </template>
</template>

keyを付けない・indexにしたときのずれを再現

key は「どの行がどのデータか」を Vue に伝える目印です。 key がない、または index のときに、入力欄の値がずれる現象を再現しました。3行のリストで先頭の入力欄に「ペンのメモ」と入力し、先頭の行を削除します。

<!-- KeyBugPage.vue(抜粋) -->
<script setup lang="ts">
import { ref } from 'vue'
const make = () => [
  { id: 1, name: 'ペン' }, { id: 2, name: 'ノート' }, { id: 3, name: 'ホチキス' },
]
const a = ref(make()), b = ref(make()), c = ref(make())
</script>

<template>
  <ul id="nokey"><li v-for="item in a">{{ item.name }} <input /></li></ul>
  <button id="del-nokey" @click="a.shift()">先頭を削除</button>

  <ul id="index"><li v-for="(item, i) in b" :key="i">{{ item.name }} <input /></li></ul>
  <button id="del-index" @click="b.shift()">先頭を削除</button>

  <ul id="id"><li v-for="item in c" :key="item.id">{{ item.name }} <input /></li></ul>
  <button id="del-id" @click="c.shift()">先頭を削除</button>
</template>

実行結果(名前=[入力欄の値]):

key=nokey: ノート=[ペンのメモ] ホチキス=[]
key=index: ノート=[ペンのメモ] ホチキス=[]
key=id: ノート=[] ホチキス=[]

key なし・index の場合、削除したはずの「ペン」のメモが「ノート」の行に残りました。 Vue は同じ key(または位置)の要素を使い回し、テキストだけを書き換えるためです。入力欄の中身のように Vue が管理していない DOM の状態は、そのまま次のデータに引き継がれます。一意な id を key にすると、正しく「ペン」の行ごと消えます。

key の指定 並び替え・先頭削除 使ってよい場面
なし 状態がずれる 基本は付ける(vue/require-v-for-key で検出できる)
index 状態がずれる 追加・削除・並び替えがない固定の表示だけ
一意な id 正しく追従 いつでも

v-ifとv-forを同じ要素に書いたとき(Vue 3で変わった点)

<!-- Vue 2 では動いたが、Vue 3 では t が未定義になる -->
<ul id="bad"><li v-for="t in tasks" v-if="!t.done" :key="t.id">{{ t.title }}</li></ul>

実行結果(ブラウザのコンソール):

[warning] [Vue warn]: Property "t" was accessed during render but is not defined on instance.
[warning] [Vue warn]: Unhandled error during execution of render function
[pageerror] Cannot read properties of undefined (reading 'done')

Vue 3 では v-if が v-for より先に評価されるため、v-if の中からはループ変数 t が見えません。 vue-tsc でも事前に検出できます。

src/dir/VIfForPage.vue(12,46): error TS2339: Property 't' does not exist on type '{ tasks: ...; open: ...; ... }'.

直し方は2通りです。

<script setup lang="ts">
import { ref, computed } from 'vue'
const tasks = ref([{ id: 1, title: '発注', done: false }, { id: 2, title: '棚卸し', done: true }])
const open = computed(() => tasks.value.filter(t => !t.done))  // ① 先に絞り込む
</script>

<template>
  <ul><li v-for="t in open" :key="t.id">{{ t.title }}</li></ul>

  <!-- ② template で入れ子にする -->
  <ul>
    <template v-for="t in tasks" :key="t.id">
      <li v-if="!t.done">{{ t.title }}</li>
    </template>
  </ul>
</template>

① の computed で絞り込む方法が、読みやすさと再描画の少なさの両面でおすすめです。

イベントを受け取る:v-onと修飾子一覧

<script setup lang="ts">
import { ref } from 'vue'
const log = ref<string[]>([])
const add = (s: string) => log.value.push(s)
</script>

<template>
  <form id="form" @submit.prevent="add('submit')">
    <button id="submit">送信</button>
  </form>
  <div id="outer" @click="add('outer')">
    <button id="stop" @click.stop="add('stop')">.stop</button>
    <button id="normal" @click="add('normal')">通常</button>
  </div>
  <button id="once" @click.once="add('once')">.once</button>
  <div id="self" @click.self="add('self')">
    <span id="self-child">子要素</span>
  </div>
  <input id="key" @keyup.enter="add('enter')" @keyup.ctrl.enter="add('ctrl+enter')" @keyup.esc="add('esc')" />
  <input id="exact" @keyup.enter.exact="add('exact-enter')" />
  <p id="log">{{ log.join(',') }}</p>
</template>

Playwright で「送信 → .stop → 通常 → .once を2回 → 子要素 → 親の余白 → Enter → Ctrl+Enter → Esc」の順に操作しました。

URL: http://localhost:7420/#dir/ModifiersPage
log: submit,stop,normal,outer,once,self,enter,enter,ctrl+enter,esc
  • .prevent:送信してもページ遷移せず、URL がそのまま
  • .stop:stop の後に outer が出ない(通常ボタンは normal,outer と親にも伝わる)
  • .once:2回押しても once は1回だけ
  • .self:子要素のクリックでは反応せず、親の余白のクリックで self
  • Ctrl+Enter で enter と ctrl+enter の両方が出た:.enter は Ctrl を押していても反応します

「Enter だけ」に限定したいときは .exact を付けます。 別の入力欄で Ctrl+Enter → Enter と押した結果、記録されたのは exact-enter の1回だけでした。

種類 修飾子 意味
イベント .stop 親への伝わり(伝播)を止める(stopPropagation())
イベント .prevent 既定の動作を止める(preventDefault())
イベント .self 要素自身がクリックされたときだけ
イベント .capture キャプチャフェーズで受け取る
イベント .once 1回だけ
イベント .passive スクロールを妨げない(.prevent と同時に使わない)
キー .enter .tab .delete .esc .space .up .down .left .right よく使うキーの別名
キー .page-down など KeyboardEvent.key をケバブケースにしたもの
システムキー .ctrl .alt .shift .meta 押しながらのとき
完全一致 .exact 指定以外の修飾キーが押されていないとき
マウス .left .right .middle 押されたボタン

.stop と .prevent は @click.stop.prevent のようにつなげられます。 つなぐ順番どおりに処理されるので、.prevent.self と .self.prevent では止める範囲が変わります。Vue 2 にあった .native と数値キーコード(@keyup.13)は Vue 3 でなくなっています。

値を渡す:v-bindと.prop・.camel

<script setup lang="ts">
import { ref } from 'vue'
const url = ref('/items/1')
const active = ref(true)
const attrs = { id: 'spread', title: 'まとめて渡す', 'data-kind': 'demo' }
const key = ref('title')
</script>

<template>
  <a :href="url">詳細</a>
  <div :class="{ active }" :style="{ fontSize: '14px' }">class と style はオブジェクトで</div>
  <div v-bind="attrs">v-bind にオブジェクト</div>
  <div :[key]="'動的な属性名'">動的引数</div>
  <!-- 3.4+:同名の変数なら値を省略できる -->
  <a :href>同名省略</a>
</template>

実行結果(各要素の outerHTML):

<a id="a1" href="/items/1">詳細</a>
<div id="c" class="active" style="font-size: 14px;">x</div>
<div id="dyn" title="動的な属性名">動的引数</div>
<a id="same" href="/same">同名省略</a>

v-bind="オブジェクト"と個別の属性が重なったとき

Vue 3 では、v-bind="obj" と個別の属性が重なると、後に書いたほうが優先されます(Vue 2 は個別の属性が常に優先)。順番だけを変えた2つの要素で確かめました。

<div class="o1" title="個別" v-bind="attrs">A</div>
<div class="o2" v-bind="attrs" title="個別">B</div>
<div class="o1" title="まとめて渡す" id="spread" data-kind="demo">A</div>
<div class="o2" id="spread" title="個別" data-kind="demo">B</div>

vue-tsc も、先に書いた属性が上書きされる箇所を error TS2783: 'title' is specified more than once, so this usage will be overwritten. として知らせてくれます。上書きしたい属性は v-bind="obj" の後ろに書くと覚えておくと迷いません。

.propと.attrの違いを確認

.prop は DOM 属性ではなく DOM プロパティ(JavaScript のオブジェクトのプロパティ)として設定します。 オブジェクトを渡した結果を比べました。

<div id="as-default" :settings="conf"></div>
<div id="as-prop" :settings.prop="conf"></div>
<!-- conf = { size: 3 } -->
default: [ '<div id="as-default" settings="[object Object]"></div>', 'undefined' ]
prop   : [ '<div id="as-prop"></div>', '{"size":3}' ]

既定では属性として文字列化され [object Object] になりましたが、.prop では属性は付かず、el.settings にオブジェクトのまま入りました。 Web Components(カスタム要素)にオブジェクトを渡すときに役立ちます。.title="msg" のように . で始めると :title.prop の省略形になります。

修飾子 意味 使う場面
.prop DOM プロパティとして設定(省略形 .) カスタム要素にオブジェクトを渡す
.attr DOM 属性として設定 プロパティと同名の属性を明示したい
.camel ケバブケースの属性名をキャメルケースに変換 HTML に直接書くテンプレートで SVG の viewBox など

.camel は、ブラウザが属性名を小文字にしてしまう「DOM 内テンプレート」で使うものです。 SFC や文字列テンプレートでは :viewBox と書けばそのまま届くので、通常は不要です。

入力と値を結ぶ:v-model

<script setup lang="ts">
import { ref } from 'vue'
const name = ref('')
const qty = ref(1)
const agree = ref(false)
</script>

<template>
  <input v-model.trim="name" />
  <input v-model.number="qty" type="number" />
  <input v-model="agree" type="checkbox" />
  <input v-model.lazy="name" /> <!-- input ではなく change で更新 -->
</template>
修飾子 意味
.lazy change イベントで更新(入力確定時)
.number 数値に変換
.trim 前後の空白を取り除く

コンポーネントに v-model を使うと、modelValue の props と update:modelValue のイベントの組み合わせになります。 Vue 3 では v-model:title のように名前を付けて複数指定でき、Vue 2 の .sync はこれに置き換わりました。子側は defineModel() で1行で書けます。

スロットに中身を渡す:v-slot

<BaseModal>
  <template #header>削除の確認</template>
  <p>本文はデフォルトスロットへ</p>
  <template #footer="{ close }"><button @click="close">閉じる</button></template>
</BaseModal>

v-slot:header は #header と省略できます。 #footer="{ close }" のように書くと、子から渡された値を受け取れます(スコープ付きスロット)。

描画を制御する:v-text・v-html・v-pre・v-once・v-memo・v-cloak

<script setup lang="ts">
import { ref } from 'vue'
const msg = ref('こんにちは')
const count = ref(0)
const html = '<b>太字</b>'
</script>

<template>
  <p id="text" v-text="msg"></p>
  <p id="html" v-html="html"></p>
  <p id="pre" v-pre>{{ msg }} はそのまま表示</p>
  <p id="once" v-once>初回: {{ count }}</p>
  <p id="now">現在: {{ count }}</p>
  <button id="inc" @click="count++">+1</button>
</template>

ボタンを2回押した後の各要素の中身(innerHTML):

#text こんにちは
#html <b>太字</b>
#pre {{ msg }} はそのまま表示
#once 初回: 0
#now 現在: 2

v-once の要素は count が 2 になっても 0 のまま、v-pre の要素は {{ msg }} が文字のまま表示されました。

v-htmlは信頼できる値だけに使う

v-html は文字列を HTML として挿入するため、利用者の入力をそのまま渡すとスクリプトが実行されます。 次の値で確かめました。

const userInput = '<img src=x onerror="window.__xss = 1">'
mustache: &lt;img src=x onerror="window.__xss = 1"&gt;
v-html  : <img src="x" onerror="window.__xss = 1">
window.__xss = 1

{{ }}(マスタッシュ構文)はエスケープされて文字として表示され、v-html では onerror が実行されました。 v-html に渡すのは自分で用意した HTML か、DOMPurify などのサニタイズ(危険な部分を取り除く処理)を通した値に限ると安心です。

v-memo

v-memo は、依存値の配列が前回と同じなら、その要素以下の再描画をまるごとスキップします(3.2+)。 大きなリストで「選択状態が変わった行だけ描き直したい」ときに使います。

<div v-for="item in list" :key="item.id" v-memo="[item.id === selectedId]">
  <p>ID: {{ item.id }} - 選択中: {{ item.id === selectedId }}</p>
</div>

selectedId が変わっても、item.id === selectedId の真偽が変わらない行は再描画されません。依存配列に入れ忘れた値は変わっても画面に反映されないので、テンプレート内で使う値は漏れなく入れます。この挙動は公式リファレンスに沿った説明で、この記事では v-memo の計測は行っていません。

v-cloak

v-cloak は、ビルドなしで HTML に直接テンプレートを書く構成で、コンパイル前の {{ }} を一瞬見せないためのものです。 Vite などでビルドする SFC では不要です。

[v-cloak] { display: none; }

カスタムディレクティブを作る

カスタムディレクティブは、DOM を直接操作する処理を再利用したいときに使います。 <script setup> では、v で始まるキャメルケースの変数(vFocus)がそのまま v-focus として使えます。

<!-- CustomPage.vue -->
<script setup lang="ts">
import { ref, type Directive } from 'vue'

// v-focus:マウントされたら自動でフォーカス
const vFocus: Directive<HTMLElement> = {
  mounted: (el) => el.focus(),
}

// v-click-outside:要素の外側をクリックしたら関数を呼ぶ
type Handler = (e: MouseEvent) => void
const handlers = new WeakMap<HTMLElement, (e: MouseEvent) => void>()
const vClickOutside: Directive<HTMLElement, Handler> = {
  mounted(el, binding) {
    const listener = (e: MouseEvent) => {
      if (!el.contains(e.target as Node)) binding.value(e)
    }
    handlers.set(el, listener)
    document.addEventListener('click', listener)
  },
  unmounted(el) {
    const listener = handlers.get(el)
    if (listener) document.removeEventListener('click', listener)
  },
}

const open = ref(true)
const closedCount = ref(0)
function close() {
  if (open.value) { open.value = false; closedCount.value++ }
}
</script>

<template>
  <input id="focus" v-focus placeholder="自動でフォーカス" />
  <div v-if="open" id="menu" v-click-outside="close">
    <button id="inside">メニュー内</button>
  </div>
  <button id="reopen" @click.stop="open = true">開く</button>
  <p id="outside">外側の領域</p>
  <p id="closed">閉じた回数: {{ closedCount }}</p>
</template>

実行結果:

focus: focus
内側クリック後 menu: 1 閉じた回数: 0
外側クリック後 menu: 0 閉じた回数: 1
再度: 閉じた回数: 2

読み込み直後に入力欄へフォーカスが当たり、メニュー内のクリックでは閉じず、外側のクリックで閉じました。 「開く」ボタンに .stop を付けているのは、開いたクリック自体が document まで伝わって即座に閉じるのを防ぐためです。unmounted でリスナーを外しているので、v-if で消えた後にイベントが残りません。

フック 呼ばれるタイミング Vue 2 での名前
created 属性やイベントが付く前 なし
beforeMount DOM に挿入される前 bind
mounted 要素と子が DOM に挿入された後 inserted
beforeUpdate 親コンポーネントの更新前 なし
updated 親と子の更新後 componentUpdated
beforeUnmount 取り除かれる前 なし
unmounted 取り除かれた後 unbind

アプリ全体で使うときは app.directive('focus', vFocus) で登録します。同じ処理が「データの加工」や「状態の共有」であればカスタムディレクティブではなく composable(use〜 関数)が向いています。 ディレクティブは DOM 要素そのものに触る処理に絞ると、役割がはっきりします。

よくある質問

Q. v-ifとv-showはどちらを使えばよいですか? A. 頻繁に切り替えるなら v-show、ほとんど切り替えない・最初は非表示が多いなら v-if が目安です。この記事の計測では 3,000 行の切り替えで v-show が数倍速く、一方で v-if は非表示時に DOM を持たないので初期表示が軽くなります。

Q. v-forのkeyにindexを使ってもよいですか? A. 並び替え・追加・削除がない固定のリストなら問題ありません。行の削除があると、この記事の再現のように入力欄の値が別の行にずれるので、データの一意な id を使うのが確実です。

Q. Vue 2のディレクティブの書き方はVue 3でもそのまま動きますか? A. 多くはそのまま動きますが、v-if と v-for の優先順位、.native・.sync・数値キーコード、slot / slot-scope 属性、カスタムディレクティブのフック名が変わっています。早見表の「Vue 2 との違い」列を移行時のチェックリストとして使えます。

Q. ディレクティブは全部で何種類ありますか? A. Vue 3.5 のビルトインは v-text・v-html・v-show・v-if・v-else・v-else-if・v-for・v-on・v-bind・v-model・v-slot・v-pre・v-once・v-memo・v-cloak の15種類です。これに加えて、自分でカスタムディレクティブを定義できます。

まとめ

  • Vue 3.5 のビルトインディレクティブは15種類。省略記法は @(v-on)、: と .(v-bind)、#(v-slot)
  • v-if は DOM を作り直し、v-show は display を切り替えるだけ。頻繁な切り替えは v-show が速い
  • v-for の key は一意な id に。key なし・index では削除時に入力欄の値がずれる
  • Vue 3 は v-if が v-for より先に評価される。computed で絞り込んでから v-for に渡す
  • .enter は Ctrl を押していても反応する。限定したいときは .exact
  • v-html はスクリプトも実行される。信頼できる値かサニタイズ済みの値だけに使う
  • カスタムディレクティブは DOM 操作専用に。unmounted で後片付けをする

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Vueのディレクティブ一覧|全15種の使い方とv-if・v-forの実測」

株式会社RJCでは、フレームワークの細かな挙動を実際に動かして確かめ、チームで共有する文化を大切にしています。こうした知識を共有しながら、日々技術を磨いています。

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?