首页 文章

可以在渲染的html中使用带有模板的VueJS SFC组件吗?

提问于
浏览
3

我有单页应用程序和多页面应用程序(经典网站)的经验 . 在过去,我在每个页面上都使用过AngularJS 1.x,它非常有用,因为所有组件都可以存在于单独的文件中,并在每个页面上显示时执行 .

我现在正在寻找VueJS来取代AngularJS,但是没有发现如何构建我的多页应用程序很容易理解 .

正如所料,我想在所有页面上使用一些组件,有些只在几页上使用 .

例:

components

我使用的ES2015看起来很有前途,但我的后端是Java,它从JSP输出我的html . 似乎.vue文件是由webpack预编译的,但是如果我的模板只在呈现页面时才准备好,那么它会不会出现?

如何构建解决方案以使每个组件都是模块化的,但在html中使用 x-template 并以某种方式将其附加到.vue SFC,或者是否有其他方法可以将组件放在可以使用ES2015导入的单独文件中?

我希望这是有道理的,似乎无法弄明白 .

2 回答

  • 1

    一种可能的方法是为内联的Vue组件设置模板 . 所以这就是拥有一个组件文件

    Home.vue:

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

    将其作为Vue的全局组件导入(使用require,import等)

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

    并且在您的服务器生成的HTML中,您必须使用内联模板,该模板具有普通模板的所有灵活性

    针对home.jsp:

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

    Update

    我在GitHub上添加了一个例子here

  • 3

    如果我理解您的问题,您需要使用HTML制作单个文件组件 .

    如果是这种情况,您应该使用render()函数和常规组件 .

    render函数决定使用什么作为组件的模板:

    <!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>
    

    Hello World 渲染到屏幕上 .

    现在,让我们看看这个函数是如何被动的:

    <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>
    

    这里,在2秒后, <div>Hello World ' + this.count + '</div> 中的计数器将从0增加到1 .

    现在,如果我们想将模板与数据分开怎么办?

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

    此代码将显示 Hello World bar .

    现在,让's see what happen if we try to load our template over http. We' ll使用 axios 库来执行此操作 . 让我们创建一个 remote.html 文件来包含我们的HTML代码:

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

    现在,让我们尝试通过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>
    

    一旦从浏览器加载 remote.html ,此代码将显示 I'm a remote component {{ foo }} .

    请注意,传递给createElement函数的对象实际上是一个组件结构 . 您可以使用相同的方法:

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

    将在浏览器上触发 alert .

    无论如何,这是一个嵌套组件的完整示例:

    的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>
    

    我不确定这是否真的是最好的方法,如果我真的回答了这个问题,但它会在列表中给出一些关于Vue如何处理渲染和组件的提示......

相关问题