fabriziocaldarelli / yii2-vueapp
一个用于在Yii2中创建Vue应用的帮助程序,无需webpack或类似工具
Requires
- npm-asset/vue: ^2.6
Requires (Dev)
- phpunit/phpunit: <7
- yiisoft/yii2: ~2.0
- yiisoft/yii2-coding-standards: ~2.0
This package is auto-updated.
Last update: 2024-09-28 20:09:22 UTC
README
这是一个组件,它帮助创建Vue.js应用,而无需使用webpack或类似工具。
所有资源(js、css和模板)都直接注入到html中,并且这个组件提供了分割代码(js、css和模板)以及从html根元素加载参数的功能。
此组件嵌入两个默认包:Axios和Moment。有一个示例演示了如何在代码中使用这两个包。
安装
通过 composer 安装此扩展是首选方式。
运行以下命令:
php composer.phar require --prefer-dist fabriziocaldarelli/yii2-vueapp "^1.0"
或者将以下内容添加到您的 composer.json
文件的require部分:
"fabriziocaldarelli/yii2-vueapp": "^1.0"
工作原理
此组件将js、css和tpl(php或html)文件注入到返回的html中。
这些文件从操作视图文件相同的文件夹开始读取,添加vueapp/actionName/js或vueapp/actionName/css或vueapp/actionName/tpl。
VueApp::begin主要支持三个参数:
- id:vue应用html标签id选择器;
- propsData:小部件使用此元素将数据从html/php传递到js脚本;
- packages:应该加载到js vue脚本中的包列表
注意:propsData 键在php和js文件中具有相同的名称(和相同的字母大小写)。
用法
1) 视图文件
在视图内部调用VueApp小部件
<?php use \sfmobile\vueapp\VueApp; /* - Css files are automatically loaded from vueapp/test/css/ - Template files are automatically loaded from vueapp/test/tpl/ - Js files are automatically loaded from vueapp/test/css/ - Passing packages parameter we require Axios and Moment package To pass data from php/html to js vue app we defined propsApp attribute data in VueApp configuration and the we fill in html converting from camel case to dash */ VueApp::begin([ 'id' => 'vueAppTest', 'propsData' => [ 'kParam1' => 'value_1', 'kParam2' => 'value_2', 'kParam3' => 'value_3', 'kParamObj' => ['a' => 10], ], /* 'jsFiles' => [ ... ], // list of other js files, that have precedente over js contents path files 'cssFiles' => [ ... ], // list of other css files, that have precedente over css contents path files 'tplFiles' => [ ... ], // list of other tpl files, that have precedente over tpl contents path files */ 'assets' => [ \sfmobile\vueapp\assets\axios\AxiosAsset::class, \sfmobile\vueapp\assets\moment\MomentAsset::class, \sfmobile\vueapp\assets\vue_select\VueSelectAsset::class \sfmobile\vueapp\assets\uid\UivAsset::class \sfmobile\vueapp\assets\vue_bootstrap_datetime_picker\VueBootstrapDatetimePickerAsset::class ] ]); ?> kParam1: {{ propsApp.kParam1 }} <br /> kParam2: {{ propsApp.kParam2 }} <br /> kParam3: {{ propsApp.kParam3 }} <br /> kParamObj: {{ propsApp.kParamObj ? propsApp.kParamObj.a : null }} <br /> <!-- Refer to https://github.com/charliekassel/vuejs-datepicker --> <vuejs-datepicker></vuejs-datepicker> <br /> clock datetime: {{ clock_datetime | formatDateTime('DD/MM/YYYY HH:mm') }} <br /> <date-picker name="date" v-model="datePickerValue" :config="vueBootstrapDatetimePickerOptions"></date-picker> <?php VueApp::end();
最重要的参数是packages,它加载嵌入的包,如Axios和Moment。
您必须安装在assets
属性中声明的所有包
$ php composer.phar require --prefer-dist fabriziocaldarelli/yii2-vueapp-uiv "^1.0"
$ php composer.phar require --prefer-dist fabriziocaldarelli/yii2-vueapp-vue-select "^1.0"
$ php composer.phar require --prefer-dist fabriziocaldarelli/yii2-vueapp-vuejs-datepicker "^1.0"
$ php composer.phar require --prefer-dist fabriziocaldarelli/yii2-vueapp-vue-bootstrap-datetime-picker "^1.0"
$ php composer.phar require --prefer-dist fabriziocaldarelli/yii2-vueapp-moment "^1.0"
$ php composer.phar require --prefer-dist fabriziocaldarelli/yii2-vueapp-axios "^1.0"
2) Vue应用js文件
从视图路径文件夹开始,应用和组件的js文件位于vueapp/test/js/actionName/ .。
例如,主vue应用js的路径可能是vueapp/test/js/test.js
// Uix package asset - To avoid conflits: // Vue.use(uiv, {prefix: 'uiv'}) : Components such as <alert> becomes <uiv-alert> // Vue Select asset - To avoid conflicts: // Vue.component('v-select', VueSelect.VueSelect); var ___VUEAPP_APP_ID___ = new Vue({ el: '#___VUEAPP_APP_ID___', // If you need a date picker, // add VueApp::PKG_VUEJS_DATEPICKER to 'packages' VueApp widget config // Refer to https://github.com/charliekassel/vuejs-datepicker components: { vuejsDatepicker, // using VueJsDatePicker "date-picker": VueBootstrapDatetimePicker, // using VueBootstrapDatetimePicker - https://github.com/ankurk91/vue-bootstrap-datetimepicker 'v-select' : VueSelect.VueSelect // using VueSelect - https://vue-select.org/guide/install.html#yarn-npm }, data: { /** * propsApp is used to collect attribute related to root container element. * This is the suggested way to pass data from php to js vue app. * All parameter are converted from dash to camel case (html k-param-1 become kParam1) */ propsApp: { kParam1: null, kParam2: null, kParam3: null, kParamObj: null, }, clock_datetime: null, datePickerValue: null, vueBootstrapDatetimePickerOptions: { // https://moment.js.cn/docs/#/displaying/ format: "DD/MM/YYYY HH:mm", locale: 'it', useCurrent: false, showClear: true, showClose: true } }, filters: { formatDateTime: function (value, format) { return value ? moment(value).format(format) : null } }, mounted() { this.readPropsApp(); // Because kParamObj is an object, we have to parse to serialized version of kParamObj this.propsApp.kParamObj = JSON.parse(this.propsApp.kParamObj); this.loadAtomicClock(); }, methods: { readPropsApp: function () { for (var k in this.propsApp) { // Taken from: https://github.com/sindresorhus/decamelize/blob/master/index.js var attr = k .replace(/([a-z\d])([A-Z])/g, '$1-$2') .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1-$2') .toLowerCase(); console.log(k, attr); if (this.$el.attributes[attr] != undefined) { this.propsApp[k] = this.$el.attributes[attr].value; } } } loadAtomicClock: function () { var self = this; axios .get('http://worldtimeapi.org/api/ip') .then(function (response) { console.log(response); self.clock_datetime = response.data.datetime; }) .catch(error => console.log(error)); }, } })
3) Vue应用css文件
从视图路径文件夹开始,应用和组件的css文件位于vueapp/test/css/actionName/ .。
例如,主vue应用css的路径可能是vueapp/test/css/test.css
[v-cloak] { display: none }
技巧与窍门
1. 将数据从html/php传递到js
要将数据从html/php传递到js vue应用,我使用了名为propsApp的属性,在其中定义了传递到html根元素的属性。例如,html根元素 "vueAppTest"
<div id="vueAppTest" v-cloak k-param-1="value_1" k-param-2="value_2" k-param-3="value_3" > ... </div>
当应用挂载时(调用readPropsApp方法),会读取data.propsApp中定义的所有参数
var vueAppTest = new Vue({ el: '#vueAppTest', data: { /** * propsApp is used to collect attribute related to root container element. * This is the suggested way to pass data from php to js vue app. * All parameter are converted from dash to camel case (html k-param-1 become kParam1) */ propsApp: { kParam1: null, kParam2: null, kParam3: null, }, }, mounted() { this.readPropsApp(); }, methods: { readPropsApp: function () { for (var k in this.propsApp) { // Taken from: https://github.com/sindresorhus/decamelize/blob/master/index.js var attr = k .replace(/([a-z\d])([A-Z])/g, '$1-$2') .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1-$2') .toLowerCase(); console.log(k, attr); if (this.$el.attributes[attr] != undefined) { this.propsApp[k] = this.$el.attributes[attr].value; } } }, } }
2. 组件注册
当应用js文件依赖于其他js文件时,js文件加载顺序很重要。
因此,我建议所有组件文件使用'_'前缀或使用'.component.'后缀,以便首先加载组件js文件。
3. 将对象数据从html/php传递到js
将对象/数组从html/php传递到js的方式与原始数据类型相同(提示和技巧#1)。唯一的区别是在mounted()函数中需要将json字符串解析为对象。
因此,如果kObject是从php传递的对象,mounted()方法将是
mounted() { this.readPropsApp(); // Because kParamObj is an object, we have to parse to serialized version of kParamObj this.propsApp.kParamObj = JSON.parse(this.propsApp.kParamObj); },