k3ssen / symfony-vuetified
用于 Symfony 4.4, 5+, 6+ 应用程序的 Vuetify 扩展包
Requires
- php: >=7.1.3
- symfony/webpack-encore-bundle: >=1.9.0
README
将 Vuetify 集成到您的 Symfony 应用程序中,通过 Twig 容易地将服务器端数据传递给 Vue。
入门指南
假设您已经在服务器上安装了 composer、yarn(或 npm)和所需模块的 Symfony 4.4、5+ 或 6+ 应用程序
- 运行
composer require k3ssen/symfony-vuetified
- 如果您刚刚创建了一个新的 symfony 项目,请运行
php bin/console symfony-vuetified:setup
。否则,请参阅 手动设置 文档。 - 安装依赖项
- 首先运行
yarn install
。 - 请确保同时添加 peer-dependencies。最好检查控制台输出,尽管以下内容可能足够
yarn --dev add vue@^2.5 vue-class-component@^7.2 vue-property-decorator@^9.1 vue-template-compiler@^2.6.10 vuetify@^2.4 vuetify-loader@^1.7
- 运行
yarn dev
当您看到缺失所需捆绑的错误时,请安装该捆绑并再次运行yarn dev
。重复此过程(约 5 次)直到完成。
- 首先运行
概念/用法
此捆绑包旨在快速实现以下目标
- 通过不使用 API 或 HTML 中的
data-
属性,从 Twig 传递服务器端数据到 Vue。 - 使用 Vuetify、Typescript 和 vue-property-decorator 构建 vue 组件。
- 通过客户端表单渲染在 Vuetify 中渲染 Symfony 表单。
- 渲染通过 twig 文件获取和加载的动态 vue 组件。
全局 Vue 对象
基本概念是您可以使用一个全局 Vue 对象。此对象将用于创建 Vue 实例。
{% extends 'base.html.twig' %} {% block body %} <p> @{ seconds } seconds have passed. </p> {% endblock %} {% block script %} <script> vue = { data: () => ({ seconds: 0, }), mounted() { setInterval(() => { this.seconds++; }, 1000); }, }; </script> {% endblock %}
注意:Vue 和 Twig 默认都使用
{{
和}}
定界符,因此在这里使用@{
和}
代替 Vue。如果您想指定不同的定界符,则可以这样做,但请避免使用${
,如 Symfony 的示例:当您在花括号( ` )内部使用${something}
时,它被解析为 JavaScript 变量,这可能会非常令人困惑。
将服务器端数据传递给 Vue:vue_data
在传递数据时,您通常会执行以下操作
{% block script %} <script> vue = { data: () => ({ someObject: {{ someObject | json_encode | raw }}, anotherObject: {{ anotherObject | json_encode | raw }}, }) } </script> {% endblock %}
如果您需要将服务器数据传递给 Vue,则可以使用 vue_data
{% block body %} {{ vue_data('someObject', someObject) }} {{ vue_data('anotherObject', anotherObject) }} <div v-if="someObject && anotherObject"> This text is only shown if both objects have a value. </div> {% endblock %}
以这种方式添加的数据将被 json 编码并合并到全局 Vue 对象中。
全局可观察数据:$store
和 vue_store
除了将数据添加到 Vue 实例之外,还可以将数据添加到 Vue $store 可观察数据中,使数据对所有 Vue 组件可用。
{% block body %} {{ vue_store('someObject', someObject) }} {{ vue_store('anotherObject', anotherObject) }} <div v-if="$store.someObject && $store.anotherObject"> This text is only shown if both objects have a value. </div> {% endblock %}
全局 Vue 组件
默认情况下,自定义和供应商 Vue 组件不是全局的,因此它们不能在 Twig 中使用。
globalComponents.ts
文件使 Vuetify 和此捆绑包的组件全局可用。这样,您几乎可以在任何地方使用这些组件,包括 Twig。
缺点是这将增加您的 JavaScript 资源大小。如果您不想使所有这些组件都全局可用,可以选择使用 vue-object.init.ts
文件而不是使用 import '@k3ssen/symfony-vuetified'
。在您的 app.ts
中,它可能看起来像以下内容
//... other stuff in your app.js file import Vue from 'vue'; import vueObject from '@k3ssen/symfony-vuetified/vue-object-init'; if (document.getElementById('sv-app') && typeof window.vue === 'object') { new Vue(vueObject); }
现在只有vue-core的组件能在twig中使用,因此你无法在twig文件中使用如<sv-form>
和<v-alert>
等组件。如果你想使特定的组件在twig中可用,例如<sv-app>
,可以使用以下方式:
Vue.component('SvApp', () => import('@k3ssen/symfony-vuetified/components/SvApp'));
获取组件
由于动态Vue组件可以在运行时渲染,因此可以使用相同的原理与fetch
一起加载组件中的响应。
本项目包含一个FetchComponent,这使得操作变得非常简单。
<sv-fetch url="/url-to-controller-action"></sv-fetch>
如果你在base.html.twig
中使用了{% extends '@SymfonyVuetified/base.html.twig' %}
,则将使用合适的文件进行扩展:如果你使用fetch,则只加载模板和脚本。否则,将加载整个页面。
注意:此组件需要加载获取到的javascript。如果获取一个已定义了变量/常量的页面,将导致javascript错误。因此,此包使用
window
将全局对象(如全局的vue
)放入。sv-fetch
组件特别考虑了全局对象vue、vueData、vueStoreData,在获取新内容之前清除这些对象。
Vue中渲染的Symfony表单
在Twig中使用表单函数或form_themes创建Vuetify表单比较困难,尤其是在处理边缘情况时。此包允许你客户端渲染Symfony的FormView
。
{% block body %}
<sv-form :form="{{ form | vue}}"></sv-form>
{% endblock %}
你可以完全控制并单独渲染部分。这需要一些习惯,因为显然Vue的工作方式与Twig的表单方法不同,但它非常强大。
阅读表单文档以获取更多信息。