New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
POC: Vue.js 3 migration path #17805
Closed
POC: Vue.js 3 migration path #17805
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sgiehl
added
the
RFC
Indicates the issue is a request for comments where the author is looking for feedback.
label
Jul 22, 2021
If you don't want this PR to be closed automatically in 28 days then you need to assign the label 'Do not close'. |
github-actions
bot
added
the
Stale
The label used by the Close Stale Issues action
label
Aug 6, 2021
diosmosis
added
Do not close
PRs with this label won't be marked as stale by the Close Stale Issues action
and removed
Stale
The label used by the Close Stale Issues action
labels
Aug 6, 2021
closing this one, as the migration is already in progress and the changes here are meanwhile outdated. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
Do not close
PRs with this label won't be marked as stale by the Close Stale Issues action
RFC
Indicates the issue is a request for comments where the author is looking for feedback.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description:
This is a POC of using Vue.js 3 to replace AngularJS directives & components in Matomo step by step.
It migrates most parts of the SitesManager admin interface, as well as some basic components like enriched-headline, content-block or alert and various related directives and filters.
Current State:
The SitesManager admin should be quite fully migrated, at least some small functional tests were working and also the UI tests are passing (apart from slight UI changes). All main directives of the SitesManager are converted, but some directives like the piwik-fields/piwik-form-fields, are still used and compiled with Angular S, once they are shown.
Making it possible to communicate between piwik-fields in AngularJS and a outer Vue.js component wasn't possible directly, as you can't pass a Vue.js variable into a AngularJS model with a two way data binding. I used a workaround by listening to the native change event, that is triggered when the field's value changes. The value can then be received in Vue.js by directly accessing the AngularJS scope of that element. Similar workarounds might be needed if we don't migrate all directives that are used on one page at once.
I have also changed the
content-block
to use a Vue.js component instead of the previous AngularJS implementation. This currently breaks most of the pages, as it causes problems on pages using twig templates containing other AngularJS directives within that component. But in general this should work when a page uses only Vue.js components.Core Concepts
In Vue.js there are actually mainly components.
Besides those components there are also directives, that are meant in another way than in AngularJS. Those can be used to register additional "attribute keywords" like
v-model
and could be used to implement something like thefocus-anywhere-but-here
directive.Other than AngularJS directives it's not possible to let Vue.js components parse by attribute. So something like
<div piwik-form-field ...>
would need to be converted to<matomo-form-field>
for Vue.Vue.js does not provide any special implementation for controller, model or service. Those can be implemented with native javascript objects if they need to be used in a global way. But there are also Vue.js extensions like https://vuemc.io/ that provide some kind of model feature or https://vuex.vuejs.org/, which provides some kind of state management.
Routing is actually not provided by Vue.js core, but it can be implemented in Vue.js using the official Vue Router (https://next.router.vuejs.org/) or even a custom implementation if needed, or it can be done using some other libraries.
Note: Currently I'm using jQuery within the Vue.js components. If at any point we want to get rid of jQuery as well, we could consider using VueQuery (https://github.com/phanan/vuequery) instead.
Modularization
Modularization is achieved in a way similar to the current AngularJS implementation. New VueJs Components or Methods can be placed in a plugin and need to be loaded using the
AssetManager.getJavaScriptFiles
event. VueJs 3 is actually meant to build real single page apps, that only have one Vue.js app element containing everything else. As we can't do that at least until AngularJS is removed we need to register the components and functions to all Vue.js elements we want to parse. To achieve that, there is a globalmatomo
javascript class that allows to register components and functions and serves acreateVue
method that automatically parses an element with Vue.js and registers all known components and methods.Migration Path
Smaller components can be converted quite simple and we can use the angular directives to render Vue.js components, which will not require any changes in the templates.
I guess the best strategy would be to convert components page by page. Once the page is done we can add a
vue-app
css-class to the parent element, which will then be parsed with Vue.js after the page is loaded.Pros & Cons
Pros
Cons