Vue组件的使用

组件使用的细节点

全局组件

Vue.component('row',{
    data: function(){
        return {
            content:'this is content'
        }
    }
    template: '<tr><td>this is a row </td></tr>'
})

<tbody>后面只能跟<tr>,所以不能直接写<row>标签,写成<tr is="row">

通过ref获取dom

通过ref来获取页面上的dom

<div ref='hello'>hello world</div>
this.$refs.hello.innerHTML //整个Vue实例里面所有的引用里面有一个叫hello的引用,获取到对应的dom节点,也就是那个<div>

若在一个组件<item>中添加上ref,那么获取到的dom就是对应的组件,也就是可以获取到组件的引用。

可以获取到组件中定义的data数据

父子组件传值

局部组件

var counter={
    template: '<div>0</div>'
}
var vm = new Vue({
    el: '#root',
    components: {
        counter: counter
    }
})

父组件传值给子组件

父组件传值给子组件通过属性来传。

  1. 在组件中定义一个属性

  2. 子组件中通过props来接收父组件传过来的值

    <div>
     <counter :count="1"></counter>
    </div>
    var counter={
     props: ['count']
        template: '<div>{{count}}</div>'
    }
    
  3. 单向数据流,子组件不能直接修改父组件的值。而是应该在自己的data上定义一个值,父组件传

过来的值赋值给定义的值,然后修改那个值

子组件向父组件传值

子组件通过事件触发来向父组件传值

//子组件
handleClick: function(){
    this.$emit('change',2) //子组件向外触发一个change事件,2是传过来的参数
}

//父组件
<counter :count="1" @change="handleInc"></counter>
父组件通过@change来接收到子组件传过来的信息
handleInc: function(step){  //step是子组件传过来的参数
    this.total = this.total+step
}

组件参数校验与非props特性

组件参数校验

定义一个全局组件

Vue.component('child',{
    template: '<div>Child</div>'
})

父组件给子组件通过属性传递一些值,而子组件做的一些约束就是组件的参数校验

<child :content ="hello"></child>

Vue.component('child',{
    props: {
        content:Number //约束content传过来的数据是数字类型
        key:[ Numver, String],
        content: {
            type: String,  //content传入的类型是字符型
            required: true,  //user必须传
            default: 'default' //给user一个默认值
            validator: function(value){  //校验传进来的内容,长度大于5
                return (value.length>5)
            }
        }
    }
    template: '<div>Child</div>'
})

非props特性

父组件要传一个名叫content的属性,而子组件刚好定义了content的prop,这个就是props特性

非props特性

  1. 父组件传,但子组件不接收
  2. 子组件不能使用父组件的值
  3. 子组件的dom标签会显示父组件的属性

给组件绑定原生事件

例如:给子组件的标签中定义一个click事件

//下面的实现是错误的
<child @click="handleClick"></child>
methods: {
    handleClick:function(){
        alert('click')
    }
}

上面的实现是错误的,原因就是在子组件中定义的@click中的click是监听的自定义事件的名称,它是接收子组件触发的事件名称,如:this.$emit('click'),@click是接收这样的事件的,并不是我们熟知的点击事件

实现上面的例子

方法一:

Vue.component('child',{
    template: '<div @click="handleChildClick">Child</div>'  
    //这里的click就是原生的点击事件
}

方法二

在click中添加.native就可标明为原生事件

<child @click.native="handleClick"></child>

非父子组件间的传值

方法一,使用Vuex

方法二,使用发布订阅模式,也称为总线机制

  1. 创建子组件child
  2. 在prototype上挂载一个bus属性,指向一个vue,以后每个vue实例上都有bus属性
Vue.prototype.bus = new Vue()
  1. 在子组件模板中定义一个点击事件
  2. 通过bus触发事件发送信息,然后同样通过bus来接收发送的信息
methods: {
    handleClick: function(){
        this.bus.$emit('change',this.content)
    }
}
mounted: function(){
    var _this = this;
    //监听change事件
    this.bus.$on('change',function(msg){
        _this.content = msg
    })
}

在Vue中使用插槽(slot)

怎么使父组件给子组件优雅的传递dom,例如父组件要给子组件传递<p>Dell</p>

按以往的方法应该是

<child content='<p>Dell</p>'></child>
//接收数据
props: ['content']
template: `<div v-html='content'></div>`  //看得出来,这样每次都会多了一个<div>标签

使用slot可以解决问题

<child>
    <p>Dell</p>
</child>

template: `<div><slot></slot></div>` //slot的内容就是子组件<child>中的dom内容

如果template中有多个<slot>,那怎么确定哪个slot要那些dom呢

可以通过名称来确定对应的dom,如

<child>
    <div class='header' slot='header'>header</div>
    <div class='footer' slot='footer'>header</div>
</child>
template: `<div><slot name='header'></slot></div>` //slot的内容就是子组件<child>中的dom内容

Vue中的作用域插槽

  1. 父组件调用子组件的时候,给子组件传递作用域插槽,作用域插槽必须是<template>标签开头和结尾
  2. 需要告诉子组件接收到的信息都放在什么地方,如:slot-scope="props" 就是接收到的信息都放在props中
  3. 需要告诉子组件需要怎样展示数据
<child>
    <template slot-scope="props">
        <h1>{{props.item}}</h1>
    </template>
</child>
template: '<div><slot v-for="item of list" :item=item></slot></div>'

动态组件与v-once指令

  1. 定义2个子组件child-one和child-two
  2. 定义一个click事件,通过点击事件循环的切换child-one和child-two 通过v-if可以实现

通过动态组件来怎么实现呢

<component :is="type"></component> 
//type的值为child-one时,这里显示child-one子组件,为child-two时显示child-two的

切换的时候,每次都是先销毁,然后再创建子组件,每次切换都销毁和创建

v-once就是为了避免这种情况的发生,使用v-once第一次展示的时候,会将组件放到内存中,第二次就不需要创建组件了,可以直接从内存中读取到

template: '<div v-once>child-one</div>'

参考
Vue.js API文档
慕课网:Vue2.5开发去哪儿网App 从零基础入门到实战项目

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

推荐阅读更多精彩内容