Vue.js

Vue.js is being evaluated as an official library for building UI within the MediaWiki ecosystem. It's currently experimental (based on v2.x) and not ready for wide use as there are a number of unknowns but more importantly, no well thought out conventions yet. This page documents best practices and other knowledge that surfaces during evaluation. In general, this documentation should be minimal because it defines only MediaWiki-specific pieces, and largely refers to the official documentation.

Shared components library Wikimedia Vue UI
As part of the Vue.js Search Widget Case Study and in course of interest by a number of teams in prototyping Vue.js based projects with goal of later in-production use, we've setup shared components library Wikimedia Vue UI (WVUI).

Pre-built (bandwidth and client performant at the expense of extra initial set up)
For professional developers building high performance experiences, pre-compilation and minificiation is recommended. However, this requires extra per-repo configuration changes which are currently undocumented. This extra configuration will be eliminated or formalized and minimized if the deploy build step RFC succeeds.

On the fly compilation (less performant but easy to develop)
ResourceLoader has built-in support for parsing single-file components. This lets you write Vue.js with very little configuration in the context of a MediaWiki installation which may be valuable in some contexts as well as for developers uncomfortable with compilers. Please note the following limitations:
 * Scoped styles are unsupported.
 * What you write is what you ship--No ES6, TypeScript, or language compilation support. At time of writing, this means ES5 only.
 * Vue.js directive shorthands are unsupported  for   and   for.
 * The version of Less used must match MediaWiki's version (very old). However, everything that works in normal MediaWiki styles works here (e.g., CSSJanus, relative URLs, imports, etc).

How to use on the fly compilation
You can add a .vue file to any package module as if it were a script file: The .vue file must contain a template and JavaScript code that exports a component registration object. It can also (optionally) contain styles: You can then  the .vue file just like any other script file. For example, you can use it as a root component as follows: Or you can use it as a nested component inside another component: Some modules have an init script as their main file (usually called ) that creates a new Vue instance to take over a DOM element on the page and replace it with a Vue component. Other modules just export one or more reusable components; their main file is either a  file with the component that's exported, or a script file that exports several components, e.g.:

The module in ResourceLoader
MediaWiki core comes with a copy of Vue (v2.x) and some small MediaWiki-specific plugins for Vue. These live in the  module. In code that sets up a new Vue instance, (i.e. calls ), you should make the   module a dependency of your module, then obtain the Vue object using. You do not have to call  to register the MediaWiki-specific plugins; this is done for you.

The i18n plugin
The  module comes with a small i18n plugin that wraps MediaWiki's i18n system, so you can use MediaWiki i18n messages in your templates. This plugin creates an  function that you can use inside templates, which is an alias for. For plain text messages (most cases), you can simply use: You can pass parameters either variadically, or as an array: The  function returns a Message object, so you can use it in all the same ways that you can use   in "normal" JS code. Remember that all message keys you use have to be added to the  array in the ResourceLoader module definition.

Parsed messages
One important limitation of  is that you can't use it for parsed messages that return HTML. This is because template interpolations ( syntax) can only return plain text, and are always HTML-escaped: The code above displays , as plain text. To get Vue to accept raw HTML, you have to use the  directive. Because writing  is verbose and annoying, the i18n plugin provides a shortcut using the   directive, which you'll want to use instead unless you need to pass message parameters or reference the message name from a variable. See the documentation comments in  for a more detailed explanation.

Parsed messages with parameters
The  directive does not currently support passing parameters to the message. Support for this may be added in the future. The recommended way to pass a parameter to a parsed message (or to do other complicated things) is to put the parsed message in a computed property. It's possible to do these kinds of things inline, but using a computed property is recommended for readability.

Guidelines

 * Avoid globals of all kinds. Instead, pass the dependencies needed in from the outermost to the part that needs it.
 * Avoid jQuery as a dependency. There are several reasons for limiting jQuery usage including:
 * jQuery is a large dependency both in terms of bytes shipped to users (performance) and comprehension (API) but its usefulness is less and less. For libraries, jQuery as a dependency especially limits reusability by third parties.
 * The jQuery API is invasive--any usage returns jQuery specific types that are cumbersome to pick apart and usually results in further usage whether it’s truly necessary or not.
 * Usage of jQuery has encouraged construction of entire user interfaces by manually assembling bits and pieces of HTML wrapped in jQuery parser calls. This imperative style is challenging to read, verbose, difficult to maintain, unwieldy to compose, and doesn’t scale well to application development. For user interface development especially, Vue.js is the greatly preferred alternative.
 * Since the need for jQuery is diminishing, it is perceived as a redundant technology (e.g., GitHub removed its usage in 2018 and close proximity to or, worse, dependency on it makes our code appear out of fashion which is unbecoming to newcomers.

External resources
Most important:


 * Official guide
 * Official API documentation
 * Official style guide
 * Official devtools browser extensions

Additional

 * Vue.js News (weekly newsletter)
 * Mozilla Developer Network (MDN) Vue.js documentation

Training vendors

 * Vue School
 * Frontend Masters
 * Vue Mastery (includes some free courses too)

GitLab

 * Vue.js frontend development guidelines
 * Why we chose Vue.js
 * How we do Vue: one year later

Testing
You should write tests! The current recommendation is to use Jest.

More information about how to test Vue components in a MediaWiki environment can be found in this guide.

Error reporting
Client side errors can be monitored in Logstash. Dedicated documentation forthcoming in T248884.

Projects using Vue
Please list any MediaWiki projects that are utilizing Vue here.
 * WMDE/Wikibase
 * "microfrontends" "termbox" (currently on mobile only)
 * Wikidata Bridge (currently on selected Wikipedias only), code: https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/extensions/Wikibase/+/refs/heads/master/client/data-bridge/
 * Tainted References: https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/extensions/Wikibase/+/refs/heads/master/view/lib/wikibase-tainted-ref/
 * Wikit (Design System and Component Library): https://github.com/wmde/wikit
 * Simple Query Builder (An easier way than SPARQL of querying Wikidata): https://github.com/wmde/query-builder/ / https://query-builder-test.toolforge.org/
 * New Searchbar for Desktop Improvements (part of WVUI)
 * Synthetic performance tests were also setup as part of this project that compare the lazy load time, query to render time, etc between legacy search and the Vue search implementation. The dashboard can be seen at https://grafana-rw.wikimedia.org/d/GivPpdsGk/vue-vs-legacy-search?orgId=1
 * Extension:MachineVision
 * Extension:WikibaseMediaInfo (Special:MediaSearch UI)
 * Extension:GlobalWatchlist
 * Extension:NearbyPages
 * Content Translation's new dashboard and section translation
 * Extension:WikiLambda
 * The Toolhub catalogue