为了账号安全,请及时绑定邮箱和手机立即绑定

浅谈Vue模板的那些事儿

图片描述
接触过vue的童鞋都知道,组件的模板一般都是在template选项内定义的,如:

1 Vue.component('child-component', {
2 
3     template:  '<h3>我是闰土大叔</h3>'
4 
5 })

这个用法都是老生常谈了,今天来聊聊Vue的内联模板。看过vue文档的同学都知道,Vue提供了一个内联模板的功能,在使用组件时,给组件标签使用inline-template特性,组件就会把它的内容当做模板,而不是把它当成内容分发,这样做的好处是,让模板更灵活。

介绍完内联模板的概念后,接下来我要分享一个我在工作中碰到的bug,关于内联模板,以及我debug的过程。

先来贴出案发现场的代码片段:

 <div id="app">
    <child-component inline-template>
        <div>
            <h2>在父组件中定义子组件的模板</h2>
            <p>{{message}}</p>
            <p>{{msg}}</p>
        </div>
    </child-component>
</div>
<script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="js/vue.js"></script>
<script>
    Vue.component('child-component',{
        data:function(){
            return {
                msg: '在子组件声明的数据'
            }
        }
    });

    var app = new Vue({
        el:'#app',
        data:{
            message: '在父组件声明的数据'
        }
    })
</script>

渲染后的理想结果本应该是:

 1 <div id="app">
 2 
 3     <div>
 4 
 5         <h2>在父组件中定义子组件的模板</h2>
 6 
 7         <p>在父组件声明的数据</p>
 8 
 9         <p>在子组件声明的数据</p>
10 
11     </div>
12 
13 </div>      

可在Chrome里显示的DOM节点却是这样的:
图片描述

不仅第一个P标签内的插值没有渲染出来,而且在控制台里还报了一个错误:

图片描述

说什么Property or method "message" is not defined on the instance but referenced during render.(属性或方法“message”不是在实例上定义的,而是在呈现过程中引用的。)

这个报错让我一脸懵逼,我可是照着书上的代码敲的,来来回回看了N遍,一模一样啊。而且书内提及 “ 在父组件中声明的数据message和子组件中声明的数据msg,两个都可以渲染。”

相信很多刚接触vue的新人童鞋都有这种体会,照着书上的代码敲了一遍,结果运行出错,与书上说的结果不一致。当你仔仔细细地检查了半天还是没发现哪错了的时候,你会不会内心抓狂到怀疑人生?

别急,这个时候你一定要有自己的判断,尽信书则不如无书。这句话出自于孟子,释义是读书时应该加以分析,不能盲目的去相信书中所言,一定要辩证的看待问题。万一这本书在排版的时候小编大意写错了呢?也有可能吧。我们对所谓的技术书籍,在尊敬作者的前提下,也要有批判精神。

其实,console控制台里的错误提示信息,就给你指明了debug的方向。通读一遍代码,我们可以分析一下,属性message是定义在父组件中的data选项内的,而调用的时候是在子组件里面调用,首先在没有任何干涉的情况下,父子组件是没有互通有无的功能的。所以,这时候你应该会想到,父子组件间传递数据用props啊!有了思路后,那就赶紧把代码敲起来吧:
图片描述

运行一遍后,果然如你所愿,第一个P标签里的插值顺利地渲染出来了。

除了内联模板,Vue还提供了另一种效率比较高的定义模板的方式,就是x-template。如果你之前没有使用过webpack、gulp等构件工具,试想下你的组件template的内容很冗长很复杂,如果都在javascript里拼接字符串,效率是很低的,因为不能像写html那么舒服(除非你用ES6里面的模板字符串)。

Vue提供了另一种定义模板的方式,在<script>标签里使用text/template类型,并且指定一个id,将这个id赋给template,举个栗子:

<div id="app">
    <my-component></my-component>
    <script type="text/x-template" id="my-component">
        <div>这是组件的内容</div>
    </script>
</div>
<script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="js/vue.js"></script>
<script>
    Vue.component('my-component',{
        template:'#my-component'
    });

    var app = new Vue({
        el:'#app'
    })
</script>

这样,在<script>标签里,你可以愉快地写html代码了,不用考虑换行等问题。

很多刚接触Vue开发的新手会非常喜欢这个功能,因为用它,再加上组件知识,就可以很轻松地完成交互相对复杂的页面和应用了。如果再配合一些构件工具(gulp)组织好代码结构,开发一些中小型产品是没有问题的。

不过Vue的初衷并不是滥用它,因为它将模板和组件的其他定义隔离了。在之后的文章里,我会介绍如何使用webpack来编译.vue的文件,从而优雅地解决html书写的问题。

今天的文章就分享到这里。

点击查看更多内容
8人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
1.1万
获赞与收藏
2282

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消