Using Vue.compile() to activate Vue component’s data and method in Mezzio Application
In previous post, we already tried create an SPA application with template rendered via Fetch for XHR purpose. What if we want to call data or/and method in template? With v-html, we can’t! The way we can do is make it compiled with Vue.compile()
. Let’s check the JS part:
createPage = (name, object = {}, methods = {}) => { return Vue.component('page-' + name, { data : () => Object.assign({content: ''}, object), methods : methods, mounted () { (new Promise( (resolve) => { fetch( this.$route.path, { method: 'GET', headers: { 'X-Requested-With': 'XMLHttpRequest', } } ).then(response => resolve(response.text())); })).then(result => this.content = result); }, render : function (c) { if (this.content == '') { return; } return c(Vue.compile('<div>' + this.content + '</div>')); } }); } const routes = [ { path: '/', component: createPage('home'), meta: { title: 'Home' } }, { path: '/about', component: createPage( 'about', { name: 'Abdul Malik Ikhsan' }, { hit: () => alert('This alert already proof that I am a web developer!') } ), meta: { title: 'About Me' } }, { path: '/contact', component: createPage('contact'), meta: { title: 'Contact Me' } }, { path: "*", component: createPage('404'), meta: { title: '404 Not Found' } } ]; const router = new VueRouter({ routes, base: '/', mode: 'history', linkExactActiveClass: "active" }); router.afterEach(to => document.title = to.meta.title); vue = new Vue({ router }).$mount('#root');
In above JS, first, I create a createPage
function that in 2nd parameter, can pass custom data besides the current content
data, and in 3rd parameter, can pass custom methods definition. With content fetched that assigned to content
data, finally, we use it in the Vue.compile() on render.
The another special part is in the template part, it requires to use this.$parent
to get parent attribute/method. For example, on the ‘about’ page above, we need to get name
data, and can call the hit
method, we can do like the following:
<!-- src/templates/app/about-page.phtml --> <h1>About Me</h1> <p> I'm a web developer. My name is {{ this.$parent.name }}. <br /> <button v-on:click="this.$parent.hit">Click this as a proof</button> </p>
That’s it, now you can open the about page and can see like the following:
I uploaded the sample source code at github, if you need to see what the diff between my previous post and this, you can check this PR https://github.com/samsonasik/mezzio-vue/pull/1 😉
Refs:
– https://vuejs.org/v2/api/#Vue-compile
– https://vuejs.org/v2/guide/render-function.html#Functional-Components
– https://stackoverflow.com/questions/51548729/vuejs-vue-app-render-method-with-dynamic-template-compiled-is-throwing-some/51552701
I am new to this, so, naive questions. You’re actually serving, as in fetching from the server, markup that has Vue directives in it, right? That is really cool. There have been many times that I’ve wished PHP and Javascript could really communicate in both directions and this feels like it’s going in that direction.
LIne 18, the c parameter, what is that exactly? I infer that it’s a function but where does it come from?
`c` is a createElement argument, you can read in the doc for it https://vuejs.org/v2/guide/render-function.html#createElement-Arguments
[…] Using Vue.compile() to activate Vue component’s data and method in Mezzio Application […]
[…] in previous JavaScript posts, I posted how to use Vue.js in Mezzio Application. Now, in this post, I will show you how to […]