父子组件传参

父传子(props、插槽、ref)

一、props

1.代码实现:

父组件

<template>
  <!-- 通过:addTodo=""给子组件传值 -->
  <div class="todo-wrap"><MyHeader :addTodo="addTodo"/>父组件</div>
</template>
<script>
export default {
  data() {};
  components:{MyHeader},
    methods: {
         addTodo(todoObj){
          this.todos.unshift(todoObj)
            },;//给子组件传的值
  }
</script>
子组件

<template>
  <!-- 通过props接受值后可直接使用 -->
  <div>子组件{{addTodo}}</div>
</template>
<script>
export default {
  name:'MyHeader',
    //通过props接收父组件传来的值
  props: {
    addTodo: {
        // 定义接收的类型[String, Undefined, Number]
        type: String,
        // 定义是否必须传
        required: true,
        // 定义默认值
        default: ''
    },
  },
  data() {},
};
</script>

props三种写法:

1.(只接收)props:['name(父组件传的值)']
2.(限制类型)props:{name(父组件传的值):String( 定义接收的类型)}
3.(限制类型、限制必要性、指定默认值)
props: {
    name(父组件传的值)父组件传的值: {
        // 定义接收的类型[String, Undefined, Number]
        type: String,
        // 定义是否必须传
        required: true,
        // 定义默认值
        default: ''

注意:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。

二、插槽

定义:所谓的插槽就是⼀个占位符,将⾃定义组件的内容展示出来

  1. 作用:让父组件可以向子组件指定位置插入html结构。
  2. 分类:默认插槽、具名插槽、作用域插槽
  3. 默认插槽
    使用场景:使用者没有填充内容,插槽指定默认数据。
    代码实现:
父组件中:
<Category>
  <div>html结构1</div>
</Category>

子组件中:
<template>
  <div>
    <!-- 定义插槽 -->
    <slot>插槽默认内容...</slot>
  </div>
</template>

4.具名插槽
使用场景:给特定的slot添加内容。
代码实现:

 父组件中:
<Category>
    <template slot="center">
    <div>html结构1</div>
    </template>

    <template v-slot:footer>
    <div>html结构2</div>
    </template>
</Category>

子组件中:
<template>
    <div>
        <!-- 定义插槽 -->
        <slot name="center">插槽默认内容...</slot>
        <slot name="footer">插槽默认内容...</slot>
    </div>
</template>

5.作用域插槽
使用场景:子组件提供数据,父组件决定如何渲染。
定义:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。
代码实现:

父组件中:
            <Category>
              <template scope="scopeData">
                <!-- 生成的是ul列表 -->
                <ul>
                <li v-for="g in scopeData.games" :key="g">{{g}}</li>
                </ul>
                </template>
            </Category>
         
            <Category>
              <template slot-scope="scopeData">
                <!-- 生成的是h4标题 -->
            <h4 v-for="g in scopeData.games" :key="g">{{g}}</h4>
                  </template>
            </Category>

子组件中:
                 <template>
                     <div>
                <!--通过v-bind来暴露数据 :数据名=“要暴露的数据”-->
                         <slot :games="games"></slot>
                     </div>
                 </template>
                
                 <script>
                     export default {
                         name:'Category',
                         props:['title'],
                         //数据在子组件自身
                         data() {
                             return {
                                 games:['红色警戒','穿越火线','劲舞团','超级玛丽']
                             }
                         },
                     }
                 </script>

三、ref

  1. 被用来给元素或子组件注册引用信息(id的替代者)
  2. 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)。
  3. 使用方式:
父组件
<template>
 <!--1. 打标识-->
   <h1 ref="xxx">.....</h1>或`<School ref="xxx"></School>
</template>
<script>
//引入子组件
    import School from './components/School'
// 获取:
      export default {
        name:'',
        components:{School},
        data() {
            return {}},
      methods: {
        showDOM(){
                console.log(this.$refs.title) //真实DOM元素
                                          }
    ```this.$refs.xxx```
</script>

适用于,后面动态给子组件传值,这样会比较快速,但是操作的时候记得备注,方便后续追踪及维护。

子传父(组件的自定义事件)

原理:通过父组件给子组件绑定一个自定义事件实现:子给父传递数据。

  1. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件。
  2. 作用:在封装组件时,为了让组件的使用者可以监听到组件内状态的变化。
  3. 写法:
    父组件:
    第一种写法,使用@或v-on
<template>
  <Student ref="student" @click.native="show"/>
</template>

第二种写法,使用ref:

<template>
        <Demo ref="demo"/>
</template>
        ......
  <script>
      import Student from './components/Student'
        mounted(){
           this.$refs.student .$on('atguigu',this.test)
        }
</script>
  1. 若想让自定义事件只能触发一次(父组件),可以使用once修饰符,或$once方法。

  2. 触发自定义事件(子组件):this.$emit('自定义事件名',数据)

  3. 解绑自定义事件(子组件)this.$off('自定义事件名')
    this.$off() //解绑所有的自定义事件

  4. 销毁了当前t组件的实例(子组件)this.$destroy()

  5. 组件上也可以绑定原生DOM事件(父组件),需要使用native修饰符。

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

推荐阅读更多精彩内容