Draft/Vue
From CODECS Dev
Ideas for features to implement using Vue
Simple ideas:
- Simple button using cdx styling, with ability to click another input. {{#v-button: text= |href= |class= |targetid= |targetclass= }},
Parser function used twice
Guide to setting a Vue widget
By way of an extension.
File structure
- extension.json - ResourceLoader modules using packageFiles method
- PHP files for parser functions
- modules/ext.codecsvue.widget.js - File where one or multiple 'App's are created and mounted, optionally with values to be passed from data-* set by the parser function
- modules/components folder containing
- single-file component(s) with a .vue extension
- index.js containing the module objects (module.exports) for these components.
extension.json
...
PHP Files
The purpose of the parser function in this example is twofold:
- To create a bit of HTML that uses a class for Vue to mount on. Let's say vue-widget.
- If the parser function needs to be configurable, make it accept arguments that will get translated to data attributes for the Vue application. The values are used only to set up a basic configuration.
- An alternative to the use of data attributes is to use ResourceLoader's mw.config, but this will be covered separately.
modules/ext.name.foo.js
This is our startimg point where the Vue application gets initialised and mounted on the HTML element.
( function () { const Vue = require( 'vue' ); // Make it compatible with Vue 2 Vue.configureCompat( { MODE: 3 } ); // Many examples out there assume you want to select a single elememt by its id // but we need to be able to select multiple elements const vueWidgets = document.querySelectorAll(".vue-widget"); vueWidgets.forEach( function(item) { // 'ext.wsvue.components' is the module name we defined in extension.json // ButtonLink is a single-component file whose module name is defined in index.js. var MyApp = require( 'ext.wsvue.components' ).ButtonLink; // Create MyApp with config passed to props, and mount! var configProps = item.dataset; Vue.createMwApp( MyApp, { configProps } ).mount( item ); }); }() );
main App.vue
- The main SFC is conventionally called App, but it is not a requirement.
<template> // ... </template> <script> const { defineComponent } = require( 'vue' ); const { CdxButton, CdxCheckbox, CdxIcon, // ... } = require( '@wikimedia/codex' ); module.exports = defineComponent( { // module.exports = exports = { name: 'ButtonLink', components: { CdxButton, CdxTextInput }, props: { configProps: { type: Array, default: [] } }, data() { return { config: this.configProps, // no need for this.$props.configProps['label'] label: this.configProps['label'] ?? "...", } }, methods: { doSomething() { // } }, computed: { // mySettings() { return this.config.mySettings; } }, mounted() { // ... } }); </script>
- Although it may not be strictly necessary, MW recommends using defineComponent ("type helper for defining a Vue component with type inference.").