初めまして。イメージ・マジックのスズキです。
いきなりですが、本稿は『SymfonyとVue.jsを組み合わせるときは「Symfony Forms」の機能を使うのは諦めた方がいいかもしれない』ということを伝えたい、ただそれだけの記事です。『エンジニアたる者、どんなときでもまずは結論から話せ』と、物心ついた頃(嘘)から聞かされてきましたしね。
Symfonyで一般的なデータの入力や保存を行う画面をつくるなら、「Symfony Forms」という機能を利用するのが基本のようです。
公式ドキュメントでも、基本的な実装方法として紹介されています。
Symfony Formsを使うことで、コントローラー側でフォームと画面項目の定義をしておいて、画面側(テンプレート側)では自力でタグを書いたりせずに表示することができます。
試しに、テキスト項目が2つあるだけの画面を作る場合、こういう感じになるでしょうか。
// エンティティ
namespace App\Entity;
class Master
{
private string $name = '';
private string $description = '';
public function getName(): string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getDescription(): string
{
return $this->description;
}
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
}
// フォーム
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class MasterEditType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('name', TextType::class)
->add('desctiption', TextType::class)
;
}
}
// コントローラー
namespace App\Controller;
use App\Entity\Master;
use App\Form\Type\MasterEditType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class MasterEditController extends AbstractController
public function edit(Request $request) : Response
{
$master = new Master();
// ...
$form = $this->createForm(MasterEditType::class, $master);
return $this->render('master/edit.html.twig', [
'form' => $form->createView(),
]);
}
}
<!-- 画面テンプレート(Symfony Form使用) -->
<div>
<div>
<label>名称</label>
{{ form_widget(form.name) }}
</div>
<div>
<label>説明</label>
{{ form_widget(form.description) }}
</div>
</div>
画面のテンプレートには
<input type="text">
といったごく普通のHTMLタグが登場しません。Symfony formsがタグを生成してくれるのですね。
ただ、リッチなフロント画面をVue.jsでごりごり書きたいときは、
<input type="text" v-model="master.name">
などとVue.jsのディレクティブを入れることになるのですが、Symfony Formsを使っているとそれがしにくくなります。
そんなわけで、Vue.jsでいろいろやりたいならば、Symfonyは使ったとしてもSymfony Formsの機能は使わない方が良さそう、といった印象です。
Symfony Formsを使わずに書くなら、サーバ側ではSymfony Formの代わりに単純なオブジェクトを作ってリターンし、画面側ではVue.jsのお作法でそれを表示するような作りが良さそうです。
先ほどのコードを、Symfony Formsを使わずに(Vue.jsを使えるように)書き直すと、こんな感じでしょうか。
// 変更後のコントローラー(Symfony Formを使わない)
namespace App\Controller;
use App\Entity\Master;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class MasterEditController extends AbstractController
public function edit(Request $request) : Response
{
$master = new Master();
// ...
return $this->render('master/edit.html.twig', [
'master' => [
'name' => $master->getName(),
'description' => $master->getDescription(),
],
]);
}
}
// 変更後の画面テンプレート(Vue.js使用)
<div>
<div>
<label>名称</label>
<input type="text" v-model="mst.name">
</div>
<div>
<label>説明</label>
<input type="text" v-model="mst.description">
</div>
</div>
<!-- Vue.jsのスクリプト部分 -->
<script>
export default {
props: {
master: {},
},
setup(props) {
const mst = ref(props.master);
return {
mst,
};
},
}
</script>
ということで今回は、SymfonyとVue.jsを組み合わせるときのお話でした。Symfony単体やVue.js単体での使い方は情報があっても、組み合わせ方の情報はなかなか無いので書いてみました。
Web界隈はフレームワークやライブラリがたくさんあって、組み合わせるときは試行錯誤が要りますね。