Vue学习笔记之七组件的使用

7 组件注册

组件名

在注册一个组件的时候,我们始终需要给它一个名字。比如在全局注册的时候我们已经看到了:

Vue.component('my-component-name', { /* ... */ })

该组件名就是 Vue.component 的第一个参数

你给予组件的名字可能依赖于你打算拿它来做什么。当直接在 DOM 中使用一个组件 (而不是在字符串模板或单文件组件) 的时候,我们强烈推荐遵循 W3C 规范中的自定义组件名 (字母全小写且必须包含一个连字符)。这会帮助你避免和当前以及未来的 HTML 元素相冲突

组件名大小写

定义组件名的方式有两种:

使用 kebab-case

Vue.component('my-component-name', { /* ... */ })

当使用 kebab-case (短横线分隔命名) 定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如 <my-component-name>

使用 PascalCase

Vue.component('MyComponentName', { /* ... */ })

当使用 PascalCase (首字母大写命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说 <my-component-name><MyComponentName> 都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。

7.1 注册全局组件

到目前为止,我们只用过 Vue.component 来创建组件:

Vue.component('my-component-name', {
  // ... 选项 ...
})

这些组件是全局注册的。也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。比如:

Vue.component('component-a', { /* ... */ })
Vue.component('component-b', { /* ... */ })
Vue.component('component-c', { /* ... */ })

new Vue({ el: '#app' })

使用组件

<div id="app">
  <component-a></component-a>
  <component-b></component-b>
  <component-c></component-c>
</div>

在所有子组件中也是如此,也就是说这三个组件在各自内部也都可以相互使用。

7.2 定义和组件的三种方式

第一种方式:

//方法1:定义组件
var login = Vue.extend({
    template:'<h1>登陆页面</h1>'
})
//注册组件
Vue.component('login',login);

<div id="app">
    <login></login>
</div>

第二种方式:

//方法2:定义一个全局组件
Vue.component('register',{
    template:'<h1>注册页面</h1>'
})

使用

<div id="app">
    <register></register>
</div>

第三种方式:

//方法3:定义一个账号组件,建议使用方法三
Vue.component('account',{
    template:'#account',
    data:function(){
        //与vue对象不同的是组件中的data是一个function,
        //所以要这么写
        return {
            message:'账户组件'
        }
    },
    methods:{
        login:function(){
            alert("Hello VueJs")
        }
    }
})

模板的事件写在对应的模板中

全局组件引用了一个在html中定义的组件模板account

<!--组件模板的定义 template和script定义都可以但是建议使用template-->
<template id="account">
    <div>
        {{message}}
        <a href="#" @click.prevent="login">登陆</a> |
        <a href="#">注册</a>
    </div>
</template>

也可以使用script定义但是建议使用template标签

 <script type="x-template" id="account">
     <div>
        <a href="#">登陆</a> |
        <a href="#">注册</a>
    </div>
</script>

值得注意的是,所有子元素必须使用一个共同的根标签包围,如div

7.3 局部注册

全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。

在这些情况下,你可以通过一个普通的 JavaScript 对象来定义组件:

var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }

然后在 components 选项中定义你想要使用的组件:

new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

或者是在组件中定义子组件

//定义一个账号组件
Vue.component('account',{
    template:'<div><h1>账号组件</h1><login></login></div>',
    //在账号组件中定义一个登陆子组件
    components:{
        'login':{
            template:'<h2>登陆子组件</h2>'
        }
    }
})

在组件中定义的子组件必须在父组件中使用如上面的

<div><h1>账号组件</h1><login></login></div>

对于 components 对象中的每个属性来说,其属性名就是自定义元素的名字,其属性值就是这个组件的选项对象。

7.4 组件的动态切换

首先注册两个组件,login和regist

Vue.component('login',{
    template:'<h1>登陆页面</h1>'
})

Vue.component('regist',{
    template:'<h1>注册页面</h1>'
})      

<div id="app">
    <a href="#" @click.prevent="cname = 'login'">登陆</a> |
    <a href="#" @click.prevent="cname = 'regist'">注册</a>
    <!-- 利用component标签中的:is参数来进行组件的切换 -->
    <component :is="cname"></component>
</div>

组件的切换使用component标签的is属性

new Vue({
    el:'#app',
    data:{
        cname:'login'
    }
})

只要控制is的值即可控制组件的显示,如上通过点击事件改变cname的值来切换组件

7.5 父组件与子组件传值

父组件向子组件传值

  • 定义组件
<template id="subEle">
    <div>
        {{name}}
    </div>
</template>

new Vue({
    el:'#app',
    data:{
        name:'张三'
    },
    components:{
        'subelement':{
            template:'#subEle',
            props:['name']//负责接收父组件传入的值
        }
    }
})

在组件中有一个props属性在其中定义变量负责接收父组件传递过来的值

然后在组件模板中使用插值表达式接收{{name}}

  • 父组件如何向子组件传递值?

通过将子组件中负责接收父组件传入值得变量name绑定到组件上传入值即可

<div id="app">
    <subelement :name="name"></subelement>
</div>

子组件向父组件传值

new Vue({
    el:'#app',
    data:{
        name:'张三'
    },
    methods:{
        getdata:function(data){
            alert(data)
        }
    },
    components:{
        'subelement':{
            template:'#subEle',
            //props:['name']//负责接收父组件传入的值
            methods:{
                sendData:function(){
                    //将hello传值给父组件
                    this.$emit('send','Hello VueJs')
                }
            }
        }
    }
})

如上所示:在子组件中写一个方法sendData用于向父组件发送值,内部使用this.$emit方法向父组件发送一个事件用于传递值,key是事件名称,值就是呀发送的数据。

当点击子组件中定义的按钮时触发sendData事件向父组件传值

<template id="subEle">
    <button type="button" @click="sendData">点击传值</button>
</template>

而这个父组件我们可以将Vue对象的实例视为一个根组件,将数据传递给Vue实例。

使用组件并传递值

<div id="app">
    <subelement v-on:send="getdata"></subelement>
</div>

当点击子组件的按钮时调用子组件中定义的方法sendData触发一个方法向父组件发送一个send事件,而send事件绑定了一个getdata方法用于获取子组件传递过来的值

methods:{
        getdata:function(data){
            alert(data)
        }
    }

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

推荐阅读更多精彩内容