Vue组件一-父组件传值给子组件

Vue组件一-父组件传值给子组件

开始

Vue组件是学习Vue框架最比较难的部分,而这部分难点我认为可以分为三个部分学习,即

  1. 组件的传值 - 父组件向子组件中传值
  2. 事件回馈 - 子组件向父组件发送消息,父组件监听消息
  3. 分发内容

整个博客使用的源代码-请点击

所以将用三篇博客分别进行介绍以上三种情况和使用

Vue的设计者对组件的理解

Vue的设计者,对组件和父组件之间的关系流上做了阐述,即单向数据流图:父组件向子组件传递数据,子组件回馈事件

组件意味着协同工作,通常父子组件会是这样的关系:组件 A 在它的模板中使用了组件 B。它们之间必然需要相互通信:父组件要给子组件传递数据,子组件需要将它内部发生的事情告知给父组件。然而,在一个良好定义的接口中尽可能将父子组件解耦是很重要的。这保证了每个组件可以在相对隔离的环境中书写和理解,也大幅提高了组件的可维护性和可重用性。

在 Vue 中,父子组件的关系可以总结为 props down, events up。父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。看看它们是怎么工作的。

属性下传,事件上传

父组件挂载的实例

上文提到的三篇文章,都使用一个父组件挂载对象,内容比较长(可以选择不看,直接看props的使用),感兴趣可以到git上去看源代码

模版:

<body>
    <div id="el-component-id"></div>
<body

Vue实例:

var vm = new Vue({
    el: "#el-component-id",
    data: {
        welcome: "welcome to Vue",
        parentMessage: "this is parent message",
        iMessage: "",
        person: {
            name: "小明",
            from: "江苏",
            to: "江西",
            purpose: "喝一杯牛奶"
        },
        persons: 10,
        sumOfTotal: 0,
        nativeSumOfTotal: 0,
        food: "牛肉",
        languages: ["英语", "中文", "希腊语", "法语", "俄罗斯语"],
        dynamicComponent: "AppHeader"
    },
    methods: {
        incrementWithTotal: function() {
            this.sumOfTotal = this.sumOfTotal + 1;
        },
        nativeDoThing: function() {
            this.nativeSumOfTotal += 1;
        },
        changeCurrentComponent: function() {
            let components = ["AppHeader", "AppFooter", "AppMain"];
            let idx = components.indexOf(this.dynamicComponent);
            if (idx == 2 || idx == -1) {
                idx = 0;
            } else {
                ++idx;
            }
            this.dynamicComponent = components[idx];
        }
    },
    components: {
        AppHeader: {
            props: ["initialText"],
            template: "<div><strong>{{title}}</strong></div>",
            data: function() {
                return {
                    title: this.initialText
                }
            }
        },
        AppFooter: {
            props: ["initialText"],
            template: "<div><sub>{{footerTitle}}</sub></div>",
            data: function() {
                return {
                    footerTitle: this.initialText
                }
            }
        },
        AppMain: {
            props: ["initialText"],
            template: "<div style='color:blue;'>{{mainContent}}</div>",
            data: function() {
                return {
                    mainContent: this.initialText
                }
            }
        }
    }
});

1. props传递单个参数

组件定义:

// 使用props数组的形式进行传递参数
Vue.component("component-span-child-1", {
    props: ["message"],
    template: "<span>{{message}}</span>"
})

模版中进行传值:

<div>
    <h4>组件一-props传递单个参数</h4>
    // 字面量传值
    <component-span-child-1 message="component-style-one"></component-span-child-1>
    <br />
    // 绑定父组件对象实例属性 v-bind:someProperty简写为:someProperty
    <component-span-child-1 :message="parentMessage"></component-span-child-1>
    <br />
    <component-span-child-1 v-bind:message="parentMessage"></component-span-child-1>
    <br />
    <input v-model="iMessage" placeholder="请输入值"/>
    <component-span-child-1 :message="iMessage"></component-span-child-1>
</div>

2. props传递多个参数

组件定义:

Vue.component("component-span-child-2", {
    props: ["name", "from", "to", "purpose"],
    template: "<div><span>{{name}}从{{from}}到{{to}},{{purpose}}</span></div>"
})

模版中传值:

<div>
    <h4>组件二-props传递多个参数</h4>
    // 字面量传值
    <component-span-child-2 name="小李" from="南京" to="北京" purpose="去买个书包"></component-span-child-2>
    // 父组件实例对象属性传值
    <component-span-child-2 :name="person.name" :from="person.from" :to="person.to" :purpose="person.purpose"></component-span-child-2>
</div>

3. 使用props对象高级传参,并对参数进行校验

组件定义:

可以校验传递进来的属性,例如:1. 校验类型 2. 是否必须传递 3. 提供默认值 4. 通过函数校验,如校验Number类型是否大于某个值

Vue.component("component-span-child-3", {
    props: {
        name: {
            type: String,
            require: true
        },
        persons: {
            type: Number,
            default: 1,
            validator: function(value) {
                return value > 0;
            }
        },
        location: {
            type: String,
            default: "上海"
        },
        action: {
            type: String,
            default: "拉粑粑"
        }
    },
    template: "<div><span>{{name}}和{{persons}}个人,去{{location}}里面{{action}}</span></div>"
})

模版中使用:

<div>
    <h4>组件三-使用props对象传递参数,和校验</h4>
    <component-span-child-3 name="小狗" :persons="persons" location="讲述郾城" action="去淘金啊"></component-span-child-3>
</div>

总结

父组件向子组件主要是通过props关键字,主要使用情况可以分为上面描述的三种。props的封装可以是一个数组,也可以是对象。

  1. 当使用数组封装props的时候,只是简单将父组件的参数传递给子组件使用,此处的参数可以是对象,字符串,number类型的数据
  2. 当使用对象封装props的时候,可以更加高级的校验参数,比如参数类型,默认值,参数大小等一系列校验。当不符合时候,可以看到Vue再控制台给出错误警告

熟练掌握父组件向子组件传递参数的方法,可以对Vue的关键部分更快的理解。

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

推荐阅读更多精彩内容

  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 5,040评论 0 29
  • vue概述 在官方文档中,有一句话对Vue的定位说的很明确:Vue.js 的核心是一个允许采用简洁的模板语法来声明...
    li4065阅读 7,176评论 0 25
  • 此文基于官方文档,里面部分例子有改动,加上了一些自己的理解 什么是组件? 组件(Component)是 Vue.j...
    陆志均阅读 3,794评论 5 14
  • iOS响应链 前言 当我们的手指点击屏幕的时候我们的app是怎么响应的呢,当我们点击一个不规则的view的时候怎么...
    一叶__知秋阅读 2,411评论 1 60
  • 夜深人静,我又开始写着我的小心情。开头依然习惯用许久……写好的两个字猛然间意识到错误迅速擦掉换成了夜深人静。此刻也...
    凹凸鱼阅读 200评论 0 0