VueJS简明教程(二)之组件

上一篇:VueJS简明教程(一)之基本使用方法

组件(Component)是Vue最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue的编译器为它添加特殊功能。
在有些情况下,组件也可以表现为用is特性进行了扩展的原生HTML元素。
所有的Vue组件同时也都是Vue的实例,所以可以接受相同的选项对象(除了一些根级特有的选项)并提供相同的生命周期钩子。

一 基础

以上是VUE组件的官方定义,让我说的直白一点,比如<button>Click</button>这个html的按钮就可以理解为一个组件,因为这么写就会展示出一个按钮在界面。

那么如果我写<button-demo>Click</button-demo>界面就不会有任何显示,因为浏览器不认识这个<button-demo>这个组件,html语法没有定义。

那么VUE的组件使我们有能通过现有的浏览器认可的组件自定义一个像是<button-demo>这样的组件的显示方式和内部运行逻辑。

举个栗子:

Vue.component('button-demo',{
    template:'<button>Hello here!</button>'
})

通过Vue注册一个叫做'button-demo'的组件,这个自定义组件是由<button>Hello here!</button>组成的。

可以这么理解,注册了'button-demo'以后,<button-demo></button-demo>就等价于<button>Hello here!</button>

看一下演示效果

这里需要注意下,通过Vue注册的组件只能在Vue的注册范围内用,就像演示里面一样,必须要<div id="app"></div>里面用。

二 进阶

VUE组件当然不可能就只能组合组合html标签,每一个VUE组件对相当于一个VUE实例,在组件内可以定义方法,数据,甚至可以引用其他组件

//定义button-counter组件
Vue.component('button-counter',{
    //定义数据
    data:function(){
        return {
            count: 0
        }
    },
    //定义方法
    methods:{
        clickAdd: function(){
            this.count++
        }
    },
    template:'<button @click="clickAdd">You clicked me {{count}} times</button>'

})

看一下演示效果

这里需要注意的是data并不是像这样直接提供一个对象:

data: {
    count: 0
}

取而代之的是,一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝(看不懂记住就好,以后慢慢理解):

data: function(){
    return {
        count: 0
    }
}

三 全局注册与局部注册

上面我们注册的是全局组件,也就是在整个VUE根实例中注册的,也可以理解为调用了VUE的静态方法注册的,这样注册的组件是可以在任何VUE实例中使用的。

不过这样也会带来作用域冲突的麻烦,比如我分别注册了一个前端HOME组件和一个后端ADMIN组件,又想注册两个HEAD组件分别用在HOMEADMIN组件里面,代表前台后台不同的页头,这时候如果是全局注册为了区分不同的HEAD组件,我可能就需要为他们起两个名字,分别叫HOME_HEADADMIN_HEAD

但是局部组件注册就允许用户把自定义组件的作用域限制在父级VUE实例中:

//component-a是一个全局组件
Vue.component('component-a',{
    template:'<div><p>这里是全局组件</p><component-b></component-b></div>',
    //使用components在父组件中注册局部组件
    components:{
        'component-b': {
            template:'<button>这是一个局部组件</button>'
        },
    }
})

可以看到,我们把在component-a组件里使用了关键字components注册了一个局部组件component-b并且嵌入了component-a的模板语法中。

完整代码

四 注意问题

单个根元素

注意上面局部组件的那个例子,全局组件component-a的模板字符串是被一个<div>标签完全包裹起来的,是因为VUE规定每个组件必须只有一个根元素,所以不管你的组件由多少子元素组成,最外层都只有有且只有一个元素。

合理组织代码结构

同样是局部组件的那个例子,如果向下面这样写会不会更清楚明白一些:

//定义component-b组件变量
component-b = {
    template: '<button>这是组件B</button>'
}
//定义component-a组间变量,并引用component-a变量
component-a = {
    template : '<div><p>这是组件A</p><component-b></component-b></div>'
    components: {
        'component-b':component-b
    }
}
//在Vue实例中注册component-a局部组件
//虽然component-a实在Vue实例中注册,但是如果此Vue实例
//是整个程序的跟实例,那也component-a也相当于进行了全局注册
new Vue({
     el: '#components-demo',
     components: {
         'component-b': component-a
     }
})

上面的代码将每个组件的代码赋值给了不同的变量,这样如果某个组件有变化,只用修改相应的变量,而不需要修改所有引用此变量的方法,实现了松耦合的编程思想。

特殊元素特殊对待

有些 HTML 元素,诸如 <ul><ol><table><select>,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 <li><tr><option>,只能出现在其它某些特定的元素内部。

这会导致我们使用这些有约束条件的元素时遇到一些问题。例如:

<table>
  <blog-post-row></blog-post-row>
  <!--table元素中只允许包含<th>,<tr>等元素-->
</table>

这个自定义组件 <blog-post-row> 会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的 is 特性给了我们一个变通的办法:

<table>
  <tr is="blog-post-row"></tr>
</table>

这样<blog-post-row>这个自定义组件就会正常渲染。

如果你使用单文件组件的话(就是.vue后缀的文件),这一条可以忽略

总结

作为一个轻量级的JS前端框架,

我认为这两章的内容就已经涵盖使用VUE最核心的语法和思想了。

还是那句话,学习一个框架,最有效的方法就是实践,不需要把所有文档看一个遍再去写程序,因为真正写程序的时候,你还会翻看无数遍框架文档。

直到现在,我在写VUE程序的时候,左边的屏幕是编辑器,右边的屏幕就是VUE的官方文档。

  1. 数据绑定
  2. 事件绑定
  3. 用户输入获取
  4. 组件定义和使用

上面四大知识点已经足够支撑我们写出一个差不多的VUE程序了。

后面会分别介绍一下:

  1. Node.js与NPM,现代前端开发必需品
  2. Webpack, 前端代码打包工具
  3. vue-router,单文件前端程序必需品

有了上面这几样东西的基础,就可以着手开发一个单页程序了_

如果你都看到这里了,能不能点个赞或者评价一下呢(*  ̄3)(ε ̄ *)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,585评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,283评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,760评论 0 324
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,461评论 1 266
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,280评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,268评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,656评论 3 385
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,322评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,629评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,691评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,445评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,299评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,694评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,982评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,244评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,642评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,829评论 2 335