/css folders
20 | */
21 | class VueApp extends Widget
22 | {
23 | /**
24 | * @deprecated Use assets property: php composer.phar require --prefer-dist fabriziocaldarelli/yii2-vueapp-axios "@dev"
25 | */
26 | const PKG_AXIOS = 'axios';
27 | /**
28 | * @deprecated Use assets property: php composer.phar require --prefer-dist fabriziocaldarelli/yii2-vueapp-moment "@dev"
29 | */
30 | const PKG_MOMENT = 'moment';
31 | /**
32 | * @deprecated Use assets property: php composer.phar require --prefer-dist fabriziocaldarelli/yii2-vueapp-vuejs-datepicker "@dev"
33 | */
34 | const PKG_VUEJS_DATEPICKER = 'vuejs_datepicker';
35 | /**
36 | * @deprecated Use assets property: php composer.phar require --prefer-dist fabriziocaldarelli/yii2-vueapp-uiv "@dev"
37 | */
38 | const PKG_UIV = 'uiv';
39 | /**
40 | * @deprecated Use assets property: php composer.phar require --prefer-dist fabriziocaldarelli/yii2-vueapp-vue-bootstrap-datetime-picker "@dev"
41 | */
42 | const PKG_VUE_BOOTSTRAP_DATETIME_PICKER = 'vue_bootstrap_datetime_picker';
43 | /**
44 | * @deprecated Use assets property: https://github.com/FabrizioCaldarelli/yii2-vueapp-select
45 | */
46 | const PKG_VUE_SELECT = 'vue_select';
47 |
48 | /**
49 | * id of vue app
50 | */
51 | public $id = null;
52 |
53 | /**
54 | * tag of vue app container
55 | */
56 | public $tag = 'div';
57 |
58 | /**
59 | * add v-cloak options to tag vue app container
60 | */
61 | public $vCloak = true;
62 |
63 | /**
64 | * props data to pass to js script
65 | */
66 | public $propsData = [];
67 |
68 | /**
69 | * other options appended to tag vue app container
70 | */
71 | public $options = [];
72 |
73 | /**
74 | * path of /js, /css and /tpl files
75 | */
76 | public $contentsPath = null;
77 |
78 | /**
79 | * js files passed from user
80 | */
81 | public $jsFiles = [];
82 |
83 | /**
84 | * css files passed from user
85 | */
86 | public $cssFiles = [];
87 |
88 | /**
89 | * tpl files passed from user
90 | */
91 | public $tplFiles = [];
92 |
93 | /**
94 | * @deprecated Use assets property
95 | * packages to load from assets
96 | */
97 | public $packages = [ self::PKG_AXIOS ];
98 |
99 | /**
100 | * assets to load
101 | */
102 | public $assets = [];
103 |
104 | /**
105 | * Position registration js file. Default is View::POS_READY
106 | */
107 | public $positionJs = \yii\web\View::POS_READY;
108 |
109 | /**
110 | * debug mode
111 | */
112 | public $debug = false;
113 |
114 | /**
115 | * js files from contents path
116 | */
117 | private $contentsPathJsFiles = null;
118 |
119 | /**
120 | * tpl files from contents path
121 | */
122 | private $contentsPathTplFiles = null;
123 |
124 | /**
125 | * css files from contents path
126 | */
127 | private $contentsPathCssFiles = null;
128 |
129 | private function checkInit()
130 | {
131 | if($this->id == null)
132 | {
133 | throw new \Exception("Missing 'id' parameter");
134 | }
135 |
136 | if($this->contentsPath == null)
137 | {
138 | throw new \Exception("Missing contentsPath (usually __DIR__)");
139 | }
140 | else
141 | {
142 | if(file_exists($this->contentsPath) == false)
143 | {
144 | throw new \Exception( sprintf("contentsPath %s does not exist", $this->contentsPath) );
145 | }
146 | }
147 |
148 | }
149 |
150 | public function init()
151 | {
152 | parent::init();
153 |
154 | if($this->contentsPath == null)
155 | {
156 | $folderName = basename($this->view->viewFile, '.php');
157 | $this->contentsPath = sprintf('%s/vueapp/%s', dirname($this->view->viewFile), $folderName);
158 | }
159 |
160 | $this->checkInit();
161 |
162 | if(($this->assets != null)&&(is_array($this->assets))&&(count($this->assets)>0))
163 | {
164 | foreach($this->assets as $asset)
165 | {
166 | $asset::register($this->view);
167 | }
168 | }
169 | else
170 | {
171 | // Load packages
172 | if(in_array(self::PKG_AXIOS, $this->packages)) \sfmobile\vueapp\assets\axios\AxiosAsset::register($this->view);
173 | if(in_array(self::PKG_MOMENT, $this->packages)) \sfmobile\vueapp\assets\moment\MomentAsset::register($this->view);
174 | if(in_array(self::PKG_VUEJS_DATEPICKER, $this->packages)) \sfmobile\vueapp\assets\vuejs_datepicker\VueJsDatepickerAsset::register($this->view);
175 | if(in_array(self::PKG_UIV, $this->packages)) \sfmobile\vueapp\assets\uiv\UivAsset::register($this->view);
176 | if(in_array(self::PKG_VUE_BOOTSTRAP_DATETIME_PICKER, $this->packages)) \sfmobile\vueapp\assets\vue_bootstrap_datetime_picker\VueBootstrapDatetimePickerAsset::register($this->view);
177 | if(in_array(self::PKG_VUE_SELECT, $this->packages)) \sfmobile\vueapp\assets\vue_select\VueSelectAsset::register($this->view);
178 | }
179 |
180 | VueAsset::register($this->view);
181 |
182 | $this->loadFilesContentsPath();
183 |
184 | ob_start();
185 | }
186 |
187 | public function run()
188 | {
189 | $outContent = '';
190 |
191 | // Prepare js files
192 | foreach ($this->jsFiles as $jsFile) {
193 | $jsContent = $this->replaceJsTokens(file_get_contents(\Yii::getAlias($jsFile)));
194 | $this->view->registerJs($jsContent, $this->positionJs);
195 | }
196 | foreach ($this->contentsPathJsFiles as $jsFile) {
197 | $jsContent = $this->replaceJsTokens(file_get_contents(\Yii::getAlias($jsFile)));
198 | $this->view->registerJs($jsContent, $this->positionJs);
199 | }
200 |
201 | // Prepare css files
202 | foreach ($this->cssFiles as $cssFile) {
203 | $cssContent = file_get_contents(\Yii::getAlias($cssFile));
204 | $this->view->registerCss($cssContent);
205 | }
206 | foreach ($this->contentsPathCssFiles as $cssFile) {
207 | $cssContent = file_get_contents(\Yii::getAlias($cssFile));
208 | $this->view->registerCss($cssContent);
209 | }
210 |
211 | // Prepare template files
212 | foreach ($this->tplFiles as $tplFile) {
213 | $tplName = pathinfo($tplFile, PATHINFO_FILENAME);
214 |
215 | $tplContent = $this->view->renderFile($tplFile);
216 | $outContent .= Html::tag('script', $tplContent, ['type' => 'text/x-template', 'id' => $tplName]);
217 | }
218 | foreach ($this->contentsPathTplFiles as $tplFile) {
219 | $tplName = pathinfo($tplFile, PATHINFO_FILENAME);
220 |
221 | $tplContent = $this->view->renderFile($tplFile);
222 | $outContent .= Html::tag('script', $tplContent, ['type' => 'text/x-template', 'id' => $tplName]);
223 | }
224 |
225 | // Get inside widget content, between begin() ... end() method
226 | $insideWidgetContent = ob_get_clean();
227 |
228 | // Add options to html tag
229 | $htmlTagOptions = ['id' => $this->id];
230 | foreach($this->propsData as $key => $val)
231 | {
232 | $htmlTagOptions[\yii\helpers\Inflector::camel2id($key)] = $val;
233 | }
234 | if($this->vCloak) $htmlTagOptions['v-cloak'] = '';
235 | $htmlTagOptions = array_merge($htmlTagOptions, $this->options);
236 |
237 | // Fill output content
238 | $outContent .= Html::beginTag($this->tag, $htmlTagOptions);
239 | $outContent .= $insideWidgetContent;
240 | $outContent .= Html::endTag($this->tag);
241 |
242 | return $outContent;
243 | }
244 |
245 | /**
246 | * Replace all tokens occurrences in js files
247 | * Token:
248 | * ___VUE_APP_ID___ : app id
249 | */
250 | private function replaceJsTokens($content)
251 | {
252 | $content = str_replace('___VUEAPP_APP_ID___', $this->id, $content);
253 | return $content;
254 | }
255 |
256 | private function loadFilesContentsPath()
257 | {
258 | if($this->contentsPath != null)
259 | {
260 | $basePath = \Yii::getAlias($this->contentsPath);
261 |
262 | $jsPath = $basePath.'/js';
263 | $this->contentsPathJsFiles = $this->loadFilesFromPath($jsPath);
264 | $tplPath = $basePath.'/tpl';
265 | $this->contentsPathTplFiles = $this->loadFilesFromPath($tplPath);
266 | $cssPath = $basePath.'/css';
267 | $this->contentsPathCssFiles = $this->loadFilesFromPath($cssPath);
268 | }
269 | }
270 |
271 | private function loadFilesFromPath($path)
272 | {
273 | $arrOut = [];
274 |
275 | if(file_exists($path))
276 | {
277 | $scandir = scandir($path);
278 | foreach($scandir as $file)
279 | {
280 | $pathFile = sprintf('%s/%s', $path, $file);
281 | if(is_file($pathFile)) $arrOut[] = $pathFile;
282 | }
283 | }
284 | else
285 | {
286 | if($this->debug)
287 | {
288 | throw new \Exception( sprintf('path %s does not exist', $path) );
289 | }
290 | }
291 |
292 | return $arrOut;
293 | }
294 |
295 |
296 | }
297 |
--------------------------------------------------------------------------------
/src/assets/VueAsset.php:
--------------------------------------------------------------------------------
1 | js[] = YII_DEBUG ? 'dist/vue.js' : 'dist/vue.min.js';
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/ExampleTest.php:
--------------------------------------------------------------------------------
1 | mockWebApplication([
12 | 'components' => [
13 | 'assetManager' => [
14 | 'class' => \yii\web\AssetManager::class,
15 | 'hashCallback' => function ($path) {
16 | $basePath = realpath(\Yii::$app->basePath . '/../');
17 | $path = str_replace($basePath, '', $path);
18 | return hash('md5', $path);
19 | }
20 | ]
21 | ]
22 | ]);
23 | }
24 |
25 | /**
26 | * Example without using render. Property 'contentsPath' is passed to the widget
27 | */
28 | public function testPositionEndWithoutRender()
29 | {
30 | ob_start();
31 | VueApp::begin([
32 | 'id' => 'vueAppTest',
33 | 'contentsPath' => __DIR__ . '/views/site',
34 | 'propsData' => [
35 | 'kParam1' => 'value_1',
36 | 'kParam2' => 'value_2',
37 | 'kParam3' => 'value_3',
38 | 'kParamObj' => ['a' => 10],
39 | ],
40 | /*
41 | 'jsFiles' => [ ... ], // list of other js files, that have precedente over js contents path files
42 | 'cssFiles' => [ ... ], // list of other css files, that have precedente over css contents path files
43 | 'tplFiles' => [ ... ], // list of other tpl files, that have precedente over tpl contents path files
44 | */
45 | 'packages' => [VueApp::PKG_AXIOS, VueApp::PKG_MOMENT, VueApp::PKG_VUEJS_DATEPICKER, VueApp::PKG_VUE_BOOTSTRAP_DATETIME_PICKER],
46 | 'positionJs' => \yii\web\View::POS_END
47 | ]);
48 | VueApp::end();
49 | $out = ob_get_clean();
50 |
51 | $expected = <<
53 | HTML;
54 |
55 |
56 | $this->assertEqualsWithoutLE($expected, $out);
57 |
58 | }
59 |
60 | /**
61 | * Example using renderPartial, only view content is rendered
62 | */
63 | public function testPositionEndRenderPartial()
64 | {
65 | $this->mockAction('site', 'example1');
66 | $out = \Yii::$app->controller->renderPartial('example1');
67 |
68 | $expected = <<<'HTML'
69 | kParam1: {{ propsApp.kParam1 }}
70 |
71 | kParam2: {{ propsApp.kParam2 }}
72 |
73 | kParam3: {{ propsApp.kParam3 }}
74 |
75 | kParamObj: {{ propsApp.kParamObj ? propsApp.kParamObj.a : null }}
76 |
77 |
78 |
79 |
80 | clock datetime: {{ clock_datetime | formatDateTime('DD/MM/YYYY HH:mm') }}
81 |
82 |
83 |
84 |
85 | HTML;
86 |
87 | $this->assertEqualsWithoutLE($expected, $out);
88 |
89 | $this->removeMockedAction();
90 | }
91 |
92 |
93 | /**
94 | * Example using render, fully template
95 | */
96 | public function testPositionEndRenderTemplate()
97 | {
98 | $this->mockAction('site', 'example1');
99 | $out = \Yii::$app->controller->render('example1');
100 |
101 | $expected = <<<'HTML'
102 |
103 |
104 |
105 |
106 | kParam1: {{ propsApp.kParam1 }}
107 |
108 | kParam2: {{ propsApp.kParam2 }}
109 |
110 | kParam3: {{ propsApp.kParam3 }}
111 |
112 | kParamObj: {{ propsApp.kParamObj ? propsApp.kParamObj.a : null }}
113 |
114 |
115 |
116 |
117 | clock datetime: {{ clock_datetime | formatDateTime('DD/MM/YYYY HH:mm') }}
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
202 |
203 |
204 | HTML;
205 |
206 | $this->assertEqualsWithoutLE($expected, $out);
207 |
208 | $this->removeMockedAction();
209 |
210 | }
211 |
212 |
213 |
214 | /**
215 | * Example using render, fully template
216 | */
217 | public function testPositionJsReady()
218 | {
219 | $this->mockAction('site', 'example1-js-ready');
220 | $out = \Yii::$app->controller->render('example1-js-ready');
221 |
222 | $expected = <<<'HTML'
223 |
224 |
225 |
226 |
227 | kParam1: {{ propsApp.kParam1 }}
228 |
229 | kParam2: {{ propsApp.kParam2 }}
230 |
231 | kParam3: {{ propsApp.kParam3 }}
232 |
233 | kParamObj: {{ propsApp.kParamObj ? propsApp.kParamObj.a : null }}
234 |
235 |
236 |
237 |
238 | clock datetime: {{ clock_datetime | formatDateTime('DD/MM/YYYY HH:mm') }}
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
326 |
327 |
328 | HTML;
329 |
330 | $this->assertEqualsWithoutLE($expected, $out);
331 |
332 | $this->removeMockedAction();
333 | }
334 |
335 |
336 | }
337 |
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | mockWebApplication();
21 | }
22 |
23 | /**
24 | * Clean up after test.
25 | * By default the application created with [[mockApplication]] will be destroyed.
26 | */
27 | protected function tearDown()
28 | {
29 | parent::tearDown();
30 | $this->destroyApplication();
31 | }
32 |
33 | /**
34 | * @param array $config
35 | * @param string $appClass
36 | */
37 | protected function mockWebApplication($config = [], $appClass = '\yii\web\Application')
38 | {
39 | new $appClass(ArrayHelper::merge([
40 | 'id' => 'testapp',
41 | 'basePath' => __DIR__,
42 | 'vendorPath' => dirname(__DIR__) . '/vendor',
43 | 'aliases' => [
44 | '@bower' => '@vendor/bower-asset',
45 | '@npm' => '@vendor/npm-asset',
46 | ],
47 | 'components' => [
48 | 'request' => [
49 | 'cookieValidationKey' => 'wefJDF8sfdsfSDefwqdxj9oq',
50 | 'scriptFile' => __DIR__ . '/index.php',
51 | 'scriptUrl' => '/index.php',
52 | ],
53 | ]
54 | ], $config));
55 | }
56 |
57 | /**
58 | * Mocks controller action with parameters
59 | *
60 | * @param string $controllerId
61 | * @param string $actionID
62 | * @param string $moduleID
63 | * @param array $params
64 | */
65 | protected function mockAction($controllerId, $actionID, $moduleID = null, $params = [])
66 | {
67 | Yii::$app->controller = $controller = new Controller($controllerId, Yii::$app);
68 | $controller->actionParams = $params;
69 | $controller->action = new Action($actionID, $controller);
70 |
71 | if ($moduleID !== null) {
72 | $controller->module = new Module($moduleID);
73 | }
74 | }
75 |
76 | /**
77 | * Removes controller
78 | */
79 | protected function removeMockedAction()
80 | {
81 | Yii::$app->controller = null;
82 | }
83 |
84 | /**
85 | * Destroys application in Yii::$app by setting it to null.
86 | */
87 | protected function destroyApplication()
88 | {
89 | Yii::$app = null;
90 | Yii::$container = new Container();
91 | }
92 |
93 | /**
94 | * Asserting two strings equality ignoring line endings
95 | *
96 | * @param string $expected
97 | * @param string $actual
98 | */
99 | public function assertEqualsWithoutLE($expected, $actual)
100 | {
101 | $expected = str_replace("\r\n", "\n", $expected);
102 | $actual = str_replace("\r\n", "\n", $actual);
103 |
104 | $this->assertEquals($expected, $actual);
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/tests/assets/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | */
3 | !.gitignore
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 | setExpectedException($exception);
21 | }
22 |
23 | /**
24 | * @param string $message
25 | */
26 | public function expectExceptionMessage($message)
27 | {
28 | $this->setExpectedException($this->getExpectedException(), $message);
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/views/layouts/main.php:
--------------------------------------------------------------------------------
1 | beginPage() ?>
2 |
3 |
4 | head() ?>
5 |
6 |
7 | beginBody() ?>
8 | = $content ?>
9 | endBody() ?>
10 |
11 |
12 | endPage() ?>
13 |
--------------------------------------------------------------------------------
/tests/views/site/example1-js-ready.php:
--------------------------------------------------------------------------------
1 | 'vueAppTest',
16 | 'propsData' => [
17 | 'kParam1' => 'value_1',
18 | 'kParam2' => 'value_2',
19 | 'kParam3' => 'value_3',
20 | 'kParamObj' => ['a' => 10],
21 | ],
22 | /*
23 | 'jsFiles' => [ ... ], // list of other js files, that have precedente over js contents path files
24 | 'cssFiles' => [ ... ], // list of other css files, that have precedente over css contents path files
25 | 'tplFiles' => [ ... ], // list of other tpl files, that have precedente over tpl contents path files
26 | */
27 | 'packages' => [VueApp::PKG_AXIOS, VueApp::PKG_MOMENT, VueApp::PKG_VUEJS_DATEPICKER, VueApp::PKG_UIV],
28 | ]);
29 | ?>
30 | kParam1: {{ propsApp.kParam1 }}
31 |
32 | kParam2: {{ propsApp.kParam2 }}
33 |
34 | kParam3: {{ propsApp.kParam3 }}
35 |
36 | kParamObj: {{ propsApp.kParamObj ? propsApp.kParamObj.a : null }}
37 |
38 |
39 |
40 |
41 | clock datetime: {{ clock_datetime | formatDateTime('DD/MM/YYYY HH:mm') }}
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/tests/views/site/example1.php:
--------------------------------------------------------------------------------
1 | 'vueAppTest',
16 | 'propsData' => [
17 | 'kParam1' => 'value_1',
18 | 'kParam2' => 'value_2',
19 | 'kParam3' => 'value_3',
20 | 'kParamObj' => ['a' => 10],
21 | ],
22 | /*
23 | 'jsFiles' => [ ... ], // list of other js files, that have precedente over js contents path files
24 | 'cssFiles' => [ ... ], // list of other css files, that have precedente over css contents path files
25 | 'tplFiles' => [ ... ], // list of other tpl files, that have precedente over tpl contents path files
26 | */
27 | 'packages' => [VueApp::PKG_AXIOS, VueApp::PKG_MOMENT, VueApp::PKG_VUEJS_DATEPICKER, VueApp::PKG_UIV],
28 | 'positionJs' => \yii\web\View::POS_END
29 | ]);
30 | ?>
31 | kParam1: {{ propsApp.kParam1 }}
32 |
33 | kParam2: {{ propsApp.kParam2 }}
34 |
35 | kParam3: {{ propsApp.kParam3 }}
36 |
37 | kParamObj: {{ propsApp.kParamObj ? propsApp.kParamObj.a : null }}
38 |
39 |
40 |
41 |
42 | clock datetime: {{ clock_datetime | formatDateTime('DD/MM/YYYY HH:mm') }}
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/tests/views/site/vueapp/example1-js-ready/js/app.js:
--------------------------------------------------------------------------------
1 | var ___VUEAPP_APP_ID___ = new Vue({
2 | el: '#___VUEAPP_APP_ID___',
3 |
4 | // If you need a date picker,
5 | // add VueApp::PKG_VUEJS_DATEPICKER to 'packages' VueApp widget config
6 | // Refer to https://github.com/charliekassel/vuejs-datepicker
7 | components: {
8 | vuejsDatepicker,
9 | "date-picker": VueBootstrapDatetimePicker
10 | },
11 |
12 | data: {
13 |
14 | /**
15 | * propsApp is used to collect attribute related to root container element.
16 | * This is the suggested way to pass data from php to js vue app.
17 | * All parameter are converted from dash to camel case (html k-param-1 become kParam1)
18 | */
19 | propsApp: {
20 | kParam1: null,
21 | kParam2: null,
22 | kParam3: null,
23 | kParamObj: null,
24 | },
25 |
26 | clock_datetime: null
27 | },
28 |
29 | filters: {
30 | formatDateTime: function (value, format) {
31 | return value ? moment(value).format(format) : null
32 | }
33 | },
34 |
35 | mounted() {
36 | this.readPropsApp();
37 |
38 | // Because kParamObj is an object, we have to parse to serialized version of kParamObj
39 | this.propsApp.kParamObj = JSON.parse(this.propsApp.kParamObj);
40 |
41 | this.loadAtomicClock();
42 | },
43 |
44 | methods: {
45 |
46 | readPropsApp: function () {
47 | for (var k in this.propsApp) {
48 |
49 | // Taken from: https://github.com/sindresorhus/decamelize/blob/master/index.js
50 | var attr = k
51 | .replace(/([\p{Lowercase_Letter}\d])(\p{Uppercase_Letter})/gu, `$1-$2`)
52 | .replace(/(\p{Lowercase_Letter}+)(\p{Uppercase_Letter}[\p{Lowercase_Letter}\d]+)/gu, `$1-$2`)
53 | .toLowerCase();
54 |
55 | console.log(k, attr);
56 | if (this.$el.attributes[attr] != undefined) {
57 | this.propsApp[k] = this.$el.attributes[attr].value;
58 | }
59 | }
60 | },
61 |
62 | loadAtomicClock: function () {
63 |
64 | var self = this;
65 |
66 | axios
67 | .get('http://worldtimeapi.org/api/ip')
68 | .then(function (response) {
69 | console.log(response);
70 | self.clock_datetime = response.data.datetime;
71 | })
72 | .catch(error => console.log(error));
73 | },
74 |
75 | }
76 | })
--------------------------------------------------------------------------------
/tests/views/site/vueapp/example1/js/app.js:
--------------------------------------------------------------------------------
1 | var ___VUEAPP_APP_ID___ = new Vue({
2 | el: '#___VUEAPP_APP_ID___',
3 |
4 | // If you need a date picker,
5 | // add VueApp::PKG_VUEJS_DATEPICKER to 'packages' VueApp widget config
6 | // Refer to https://github.com/charliekassel/vuejs-datepicker
7 | components: {
8 | vuejsDatepicker,
9 | "date-picker": VueBootstrapDatetimePicker
10 | },
11 |
12 | data: {
13 |
14 | /**
15 | * propsApp is used to collect attribute related to root container element.
16 | * This is the suggested way to pass data from php to js vue app.
17 | * All parameter are converted from dash to camel case (html k-param-1 become kParam1)
18 | */
19 | propsApp: {
20 | kParam1: null,
21 | kParam2: null,
22 | kParam3: null,
23 | kParamObj: null,
24 | },
25 |
26 | clock_datetime: null
27 | },
28 |
29 | filters: {
30 | formatDateTime: function (value, format) {
31 | return value ? moment(value).format(format) : null
32 | }
33 | },
34 |
35 | mounted() {
36 | this.readPropsApp();
37 |
38 | // Because kParamObj is an object, we have to parse to serialized version of kParamObj
39 | this.propsApp.kParamObj = JSON.parse(this.propsApp.kParamObj);
40 |
41 | this.loadAtomicClock();
42 | },
43 |
44 | methods: {
45 |
46 | readPropsApp: function () {
47 | for (var k in this.propsApp) {
48 |
49 | // Taken from: https://github.com/sindresorhus/decamelize/blob/master/index.js
50 | var attr = k
51 | .replace(/([\p{Lowercase_Letter}\d])(\p{Uppercase_Letter})/gu, `$1-$2`)
52 | .replace(/(\p{Lowercase_Letter}+)(\p{Uppercase_Letter}[\p{Lowercase_Letter}\d]+)/gu, `$1-$2`)
53 | .toLowerCase();
54 |
55 | console.log(k, attr);
56 | if (this.$el.attributes[attr] != undefined) {
57 | this.propsApp[k] = this.$el.attributes[attr].value;
58 | }
59 | }
60 | },
61 |
62 | loadAtomicClock: function () {
63 |
64 | var self = this;
65 |
66 | axios
67 | .get('http://worldtimeapi.org/api/ip')
68 | .then(function (response) {
69 | console.log(response);
70 | self.clock_datetime = response.data.datetime;
71 | })
72 | .catch(error => console.log(error));
73 | },
74 |
75 | }
76 | })
--------------------------------------------------------------------------------