Magento 2.2: Is it possible to use Vue.js in Magento?
Finally I've done as follows:
Copy all content of this url insaid you custom module
/Custom/Module/view/frontend/web/js/vue.js
Configure requirejs-config.js
/Custom/Module/view/frontend/requirejs-config.js
var config = { map: { '*': { vue: 'Custom_Module/js/vue'> } } };
And to use it:
define([ 'jquery', 'vue' ], function ($, Vue) { "use strict"; // code... });
The accepted answer is correct however it really isn't a full example of how to implement VueJS within a Magento store.
There are two different approaches that you can take depending upon your situation & implementation requirements to insert & initialize your VueJS component, Declarative or Imperative. Both of them are acceptable methods of implementation according to Magento's coding guidelines.
Declarative Implementation
This approach is recommended for instantiating one-off Vue components within your Magento store and is a simpler approach.
First, assuming your module is named Macademy_JsFun
, create a file at app/code/Macademy/JsFun/view/frontend/requirejs-config.js
with the following contents:
var config = {
"paths": {
"vue": "https://cdn.jsdelivr.net/npm/vue/dist/vue"
}
}
Note that the external URL does not have a .js
extension. You can alternatively download the file to your local module, please it at app/code/Macademy/JsFun/view/frontend/web/js/vue.js
, and then instead reference it like so:
var config = {
"paths": {
"vue": "Macademy_JsFun/js/vue"
}
}
Create a new PHTML template file which will represent your VueJS component at app/code/Macademy/JsFun/view/frontend/templates/vue-test.phtml
, renaming vue-test.phtml
to whatever you want to name your VueJS component:
<div id="vue-test">
<h1>{{ message }}</h1>
</div>
<script>
require(['vue'], function(Vue) {
'use strict';
new Vue({
el: '#vue-test',
data: {
message: 'This is a test'
}
});
});
</script>
Finally, include the PHTML file into your layout XML. For example, if you wanted to load this VueJS component on your home page, add it to app/code/Macademy/JsFun/view/frontend/layout/cms_index_index.xml
:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<block name="vue.test" template="Macademy_JsFun::vue-test.phtml"/>
</referenceContainer>
</body>
</page>
Once you flush the caches and reload the home page, the new Vue component should show on the home page:
Imperative Implementation
You'll want to use an imperative approach for a larger implementation, or if you have different requirements that do not align with using a declarative approach. This approach uses the same requirejs-config.js
file as above, but the PHTML is updated and a new JavaScript file is created for JavaScript component initialization.
Rather than instantiating your Vue component directly within the PHTML file, you will create a new file at app/code/Macademy/JsFun/view/frontend/web/js/vue-test.js
with the following contents:
define(['vue'], function(Vue) {
'use strict';
return function(config, element) {
return new Vue({
el: '#' + element.id,
data: {
message: 'This is a test'
}
});
}
});
Note how require
changed to define
, as we are really "defining" a new JavaScript component using this approach. When you define a JavaScript component, you can return a callback function which contains two arguments, a config
and an element
. We can grab the element id from the element argument so it is more dynamic.
Next, that JavaScript component can then be instantiated with the data-mage-init
HTML attribute within the app/code/Macademy/JsFun/view/forntend/templates/vue-test.phtml
file:
<div id="vue-test" data-mage-init='{ "Macademy_JsFun/js/vue-test": {} }'>
<h1>{{ message }}</h1>
</div>
Sometimes this method can get a bit hard to read, so there is an alternative format that can be used which has the exact same result. Note that you need to specify an element selector to target in the first JavaScript object property. You can also specify *
, however if you do so, the function callback of the JavaScript component will contain a null
response for the element
argument, so your code needs to be updated appropriately.
<div id="vue-test">
<h1>{{ message }}</h1>
</div>
<script type="text/x-magento-init">
{
"#vue-test": {
"Macademy_JsFun/js/vue-test": {}
}
}
</script>