If is possible, how can I integrate it in my custom module?
3 Answers
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>
-
1Any chance to provide an answer without using an inline script and require() function? Commented Apr 20, 2020 at 18:55
-
@MaxPronko updated the answer with both declarative and imperative implementation approaches. Note that the declarative approach is not considered an "inline script", as the VueJS component is still instantiated with RequireJS. Both approaches are acceptable, and the usage of each depends upon the implementation requirements. Commented Apr 20, 2020 at 21:08
-
1
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... });
-
Sir is it works on M1 as well??? n after adding this
vue.js
code my eCommerce shop speed will be increased? n all I need to add only this code? Commented May 29, 2019 at 11:44 -
I don't know if this code works on M1, this code only add the framework Vue, after this you can develop vue components– chdzmaCommented Jun 3, 2019 at 10:36
-
@AsadKhan Your ecommerce shop speed won't increase using this above snippet, you can however use something like Vue Storefront which replaces the frontend of your site, and is noticeably faster. vuestorefront.io Commented Sep 16, 2019 at 7:39
I did some research and found solution. Write below code in your phtml file.
<html>
<head>
<title>VueJs Introduction</title>
<script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id = "intro" style = "text-align:center;">
<h1>{{ message }}</h1>
</div>
<script type = "text/javascript">
var vue_det = new Vue({
el: '#intro',
data: {
message: 'My first VueJS Task'
}
});
</script>
</body>
</html>
-
2this doesn't answer anything. It's just a random vue snippet. Commented Aug 7, 2019 at 15:11
-
Adding the VueJS script globally in the header is not the best practice. You'll want to use RequireJS so that VueJS is only loaded when it is needed. Commented Apr 20, 2020 at 21:26