unique / yii2-vue
简化在 Yii2 框架中使用 Vue。
Requires
- php: >=8.0
- ext-json: *
- yiisoft/yii2: ~2.0.0
Requires (Dev)
- phpunit/phpunit: ^9.4
This package is auto-updated.
Last update: 2024-09-15 22:48:45 UTC
README
此包为 Yii2 框架上的 Vuejs v3 提供了一个非常基本的模型管理系统。此外,允许您通过 yii2 AssetBundle 容易地控制您的 Vue 应用资产。
安装
此组件需要 php >= 8.0。要安装它,请将以下内容添加到您的 composer.json 中
"require": {
...
"unique/yii2-vue": "@dev"
},
目前,此包依赖于 JQuery 进行 AJAX 调用和其他操作。可能将来会将其解耦...
用法
要使用此包,您需要创建自己的 AssetBundle 文件并在其中定义您的 VUE 应用程序。您可以使用包含的 \unique\yii2vue\assets\VueAssetBundle,以帮助进行一些资产加载,例如
class VueAppAssets extends VueAssetBundle { public $sourcePath = __DIR__ . '/vue-app'; public $jsOptions = [ 'position' => View::POS_HEAD ]; public $depends = [ Yii2VueComponentsAssets::class ]; public function init() { parent::init(); $this->loadPath( __DIR__ . DIRECTORY_SEPARATOR . 'vue-app' . DIRECTORY_SEPARATOR . 'js' . DIRECTORY_SEPARATOR . 'models' ); } }
VueAssetBundle 提供了一种轻松添加给定路径中所有 js 和 css 文件的方式。这对于加载所有模型很有用。如果您只想添加特定的模型、组件或应用程序,可以使用相应的 addModel()
、addComponents()
或 addApplication()
方法。
例如,在您的视图文件中,您可以注册您创建的包并添加一个特定的应用程序
( \app\assets\VueAppAssets::register( $this ) ) ->addApplication( 'accounts-index' ) ->addComponent( 'bootstrap-input' );
您可以通过覆盖相应的 VueAssetBundle
属性来自定义查找每个文件的位置。例如
class VueAppAssets extends VueAssetBundle { public string $sourcePath = __DIR__ . DIRECTORY_SEPARATOR . 'myassets'; public string $applications_path = 'myjs/apps/'; public string $mixins_path = 'myjs/mixins/'; public string $components_path = 'myjs/components/'; public string $models_path = 'myjs/models/'; }
路径是相对于资产文件所在的位置的。在这个特定的例子中,当调用 ( \app\assets\VueAppAssets::register( $this ) )->addApplication( 'accounts-index' )
时,这会转换为生成一个 script 标签
<script type="/assets/.../myjs/apps/accounts-index.js"
如果您依赖于提供的 Yii2VueComponentsAssets
类,这将提供一个类似于原生 Yii2 模型系统的非常基本的模型管理系统。
默认情况下,它还会加载 VueAssets
包,该包加载 vuejs。如果您想使用自己的 vuejs,您可以在 config/params.php
文件中禁用此行为
return [ 'use_vue_dependancy' => false, ... ];
模型和模型管理器的使用
一个基本的模型文件可能看起来像这样
/** * @property {int} id * @property {string} name * ... other attribute definition * * @property {Type} type * ... other relations definition */ class MyModel extends Model { /** * The data to be passed to the API to create or update the model. (like a serialization of the Model) * @returns {Object} */ toBody() { return { id: this.id, name: this.name, // ... other properties } } /** * Model Relationship definition. * @returns {Relation[]} */ relations() { return { type: new Relation( Relation.TYPE_HAS_ONE, Type ), } } /** * Sets the primary keys to the object, to be used when updating the model. * @param {Object} data * @returns {Object} */ setPrimaryKeys( data ) { data['id'] = this.id; return data; } }
要创建此模型,您可以使用提供的构造函数
let my_model = new MyModel( { id: 1, name: 'ABC', 'type': { type_name: 'Name', ... } } );
这传播了所有给定的属性并创建了所有关系。它专门设计用于与 Yii2 序列化模型一起使用。
要控制多个模型,您可以使用提供的 ModelsManager(或通过扩展它来创建一个新的 ModelsManager)
let my_models_manager = new ModelsManager( { access_token: '(string) An access token, that, if provided, will be sent with API requests' + 'as a basic Auth header. The string will be sent as a username.', url_create: '(string) A URL that will be used to create new Models', url_update: '(string) A URL that will be used to update Models', url_delete: '(string) A URL that will be used to delete Models', url_list: '(string) A URL that will be used to reload data', endpoint_model_class: '(string) A php class name of the model used in the backend. (can be' + 'used to update many managers data at once)', model_class: '(string) A JS model\'s class name, that will be created by this Manager', model_id: '(string, default="id") a property, which will be used to index models by' } ); my_models_manager.setData( serialized_php_models, // serialized data, which to use to create the models false // (bool) Are we setting models that are new (not in DB yet)? )
ModelsManager 方法
-
reloadData()
用来在管理器中重新加载数据。必须指定 url_list。 -
updateData( new_data: Object, delete_missing: boolean = true )
这将迭代此管理器管理的所有模型,并将它们的属性更新以反映给定的新数据。如果需要创建模型,它们将被创建。但是,只有当 delete_missing === true 时,对象才会从存储中删除new_data
和它的关系必须使用与ModelsManager.data
中相同的键进行索引。 -
setData( models: Array, new_records: bool )
从管理器中擦除旧数据并设置新数据,通过创建新模型。new_records
参数用于设置模型是否需要创建(当为 true 时),或更新(当为 false 时)。 -
addItem( item: Model, new_record: bool )
将模型添加到数据存储(不调用 API)。new_records
参数用于设置模型是否需要创建(当为 true 时),或更新(当为 false 时)。 -
static handleUnsuccessfulRequest( model: Model, data: Object, default_key: string )
根据响应的data
在 Model 的errors
字段上设置字段错误。data
- 具有以下结构
{ success: boolean, // was an operation successful. If it's given here, then usually this should be set to false., data: object, // either a serialized Yii2 Exception, or a serialized Model with validation errors. }
当 data.data
是序列化的 Yii2 异常时,它将具有以下字段
{ name: string, // Exception class name, message: string, // Exception message }
错误将被设置到模型提供的 default_key
属性。
当 data.data
是序列化的具有验证错误的 Yii2 Model 时,它将具有以下结构
[ { field: string, // Field name that violated a validation rule, message: string, // Validation message }, ... ]
通过在 field
中提供完整路径,也可以为 Model 的关系设置错误。例如,如果模型 Brand 有一个名为 cars 的 HAS_MANY 关系和 Car 类,以及一个与 Manufacturer 类的 HAS_ONE 关系 manufacturer,在向 API 发起失败的请求后,我们可能收到以下响应
{ success: false, data: [ { field: "name", message: "Bad name" }, // This is an error for Brand.name property { field: "cars.3.engine", message: "..." }, // This is an error for Brand.cars[3].engine property and will accordingly be set on a Car class { field: "manufacturer.year", message: "..." } // This is an error for Brand.manufacturer.year property and will be set on a Manufacturer class ] }
请注意,Yii2 本身没有原生的关系保存能力,因此,您需要自己实现后端逻辑。
-
deleteItem( item_id: string|int, remove_from_data: bool )
调用 API 来移除给定的 ID。如果remove_from_data
为 true,则成功调用后,数据也会从 Manager 中删除。 -
saveItem( item: Model, request_data: Object )
调用 API 来创建或更新给定的模型。可以通过提供request_data
对象来传递额外的数据。它将与要保存的 Model 的数据合并。(Model 的数据优先)。
ModelsManagerRegister
所有创建的 ModelsManager
实例都自动注册到 ModelsManagerRegister
的静态实例。可以使用 ModelsManagerRegister
同时更新多个 ModelsManger
。当您进行的 API 调用不仅更新给定的模型,还更新其他模型时,这很方便。
在这种情况下,API 调用可以返回 _list_changes_
来更新其他模型。例如,假设我们正在创建一个新的 Car 模型,该模型更新 Stats 模型以反映相同 make_id 的汽车数量。那么我们的 API 可能会返回如下数据
{ ..., "_list_changes_": { "\\app\\models\\Car": { "1067": { "id": 1067, "make_id": 3, ... } }, "\\app\\models\\Stat": { "3": { "count": 52 } } } }
现在我们可以调用 ModelsManagerRegister.updateListChanges( data )
,这将在我们创建了 Car
和 Stat
模型的 ModelsManager 的情况下更新它们中的数据。
使用 Yii2 命令创建 JS 模型文件
您可以通过调用以下内容轻松创建一个 JS 模型
yii vue-assets/generate-model [PHP_CLASS_NAME]
如果您跳过了 [PHP_CLASS_NAME],则在命令运行时您需要指定它。这应该是一个完全命名空间化的类名。
您还应该在您的 config/console.php 文件中指定生成的模型的位置
'controllerMap' => [ 'vue-assets' => [ 'class' => \unique\yii2vue\commands\VueAssetsController::class, 'vue_asset_models_path' => ... // path to directory where to put generated JS models, ] ],