Possible to use VueJS SFC components with with template in rendered html? Possible to use VueJS SFC components with with template in rendered html? vue.js vue.js

Possible to use VueJS SFC components with with template in rendered html?


One possible approach would be to set the template for the Vue Component inline. So this would be to have a Component File like

Home.vue:

<script>    export default {        data() {            return {                msg: 'text',            }        }    }</script>

import it as a global component for Vue (using require, import, etc.)

Vue.component('home', require('./components/Home.vue'));

and in your server generated HTML you'd have to use an inline template, which will have all the flexibility from normal templates

home.jsp:

<home inline-template>    <h2 v-text="msg"></h2></home>

Update

I've added an example on GitHub here


If I understand your question, you have want to make single file components out of HTML.

If this is the case, you should make use of the render() function and regular components.

The render function decides what to use as a template for a component:

<!DOCTYPE html><html><head>    <title>Vue</title></head><body><div id="app"></div><script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script><script type="text/javascript">    new Vue({        el: '#app',        render (createElement) {            return createElement({                template: '<div>Hello World</div>'            })        },    })</script></body></html>

will render Hello World to the screen.

Now, let's see how this function is reactive:

<script type="text/javascript">    new Vue({        el: '#app',        data: {            count: 0        },        render (createElement) {            return createElement({                template: '<div>Hello World ' + this.count + '</div>'            })        },        created () {            setTimeout(() => {                this.count++            }, 2000)        }    })</script>

Here, after 2 seconds, the counter in <div>Hello World ' + this.count + '</div> will increment from 0 to 1.

Now, what if we want to separate the template from the data?

<script type="text/javascript">    new Vue({        el: '#app',        render (createElement) {            return createElement({                template: '<div>Hello World {{ count }}</div>',                data () {                    return {foo: 'bar'}                }            })        }    })</script>

This code will display Hello World bar.

Now, let's see what happen if we try to load our template over http. We'll use the axios library to do so. Let's create a remote.html file to contain our html code:

<div>    I'm a remote component {{ foo }}</div>

Now, let's try to load it via Ajax:

<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.2/axios.min.js"></script><script type="text/javascript">    new Vue({        el: '#app',        data: {            template: null        },        render (createElement) {            return createElement({                template: this.template ? this.template : '<div>Hello World {{ foo }}</div>',                data () {                    return {foo: 'bar'}                }            })        },        created () {            axios({                url: '/remote.html',                method: 'get'            }).then(response => {                this.template = response.data            })        }    })</script>

This code will display I'm a remote component {{ foo }} as soon as remote.html has been loaded from the browser.

Note that the object passed to the createElement function is actually a component structure. You can use the same methods on it:

render (createElement) {    return createElement({        template: this.template ? this.template : '<div>Hello World {{ foo }}</div>',        data () {            return {foo: 'bar'}        },        mounted () {            alert('Hello from mounted')        }    })}

will trigger an alert on the browser.

Anyway, here is a complete example with nested components:

Index.html

<!DOCTYPE html><html><head>    <title>Vue</title></head><body><div id="app"></div><script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.2/axios.min.js"></script><script type="text/javascript">    const headerComponent = {        data () {            return {                template: '<div>Loading...</div>'            }        },        render (createElement) {            return createElement({                template: this.template,                data () {                    return {                        search: ''                    }                }            })        },        created () {            axios('/header.html').then(response => {                this.template = response.data            })        }    }    new Vue({        el: '#app',        data: {            template: null        },        render (createElement) {            return createElement({                template: this.template ? this.template : 'Loading...',                data () {                    return {foo: 'bar'}                },                components: {                    'my-header': headerComponent                }            })        },        created () {            axios({                url: '/remote.html',                method: 'get'            }).then(response => {                this.template = response.data            })        }    })</script></body></html>

header.html

<div>    <label>Search</label>    <input v-model="search" name=""> The search is: {{ search }}</div>

I'm not sure that this is really the best approach and if I'm really responding to the question, but it will at list give you some tips on how Vue handles rendering and components...