前面的话

组件不仅仅是要把模板的内容进行复用,更重要的是组件间要进行通信。组件接受的选项大部分与 Vue实例一样,而选项props是组件中非常重要的一个选项。在Vue中,父子组件的关系可以总结为 props down,events up。父组件通过props向下传递数据给子组件,子组件通过events给父组件发送消息。这篇文章将介绍组件使用props传递数据。

父子级组件

通常父组件的模板中包含子组件,父组件要正向地向子组件传递数据或参数,子组件接受到后根据参数的不同来渲染不同或执行操作。这个正向传递数据的过程就是通过props来实现的。

以下两种父子级组件的写法是错误的:

[第一种]

     <div id="app"><parent><child></child><child></child></parent></div>

这种写法当子组件注册到父组件时,Vue.js会编译好父组件的模板,模板的内容已经决定了父组件将要渲染的HTML代码" < div class=“parent”>我是父组件</ div>", < parent> …</ parent>运行时它的一些子标签只会被当做普通的HTMl来执行,不是标准的HTML标签,会被浏览器直接忽视掉。

[第二种]

同理:在父组件标签之外使用子组件也是错误的

  <div id="app1"><parent></parent><child></child></div>

[正确写法]

  <div id="app2"><parent></parent></div>  <script>var childNode = {template: `<div class="child">我是子组件</div>`}var parentNode = {template:`<div class="parent">我是父组件<child></child><child></child></div>`,           components: {'child': childNode}       }var app2 = new Vue({el:"#app2",components:{'parent': parentNode}})
</script>

静态props

使用props传递数据包括静态和动态两种形式,先介绍静态props 。

在组件中,使用选项props来声明需要从父级接受的数据,props的值可以是字符串数组,也可以是对象。

例如: 构造一个数组,接受一个来自父级的数据message,子组件要显式地使用props选项来声明它想获得的数据

<div id="app3"><parent-companent></parent-companent>
</div>
<script>var child = {template: "<div>{{ message}}</div>",// 显式的声明要获取的数据props: ['message']}var parent = {template:// 从父组件传递数据message给子组件`<div class="parent"><child-component message="aaa"></child-component><child-component message="bbb"></child-component></div>`,components: {'child-component': child}}var app3 = new Vue({el: "#app3",components: {'parent-companent': parent}})
</script>


[全局注册式]

<div id="app4"><my-component warning-text="提示信息"></my-component>
</div>
<script>Vue.component('my-component',{props: ['warningText'],template: '<div> {{warningText}}</div>'})var app4 = new Vue({el: '#app4',})
</script>


注意: 如果要传递多个数据,直接在props数组中添加项即可

命名规则

对于props声明的属性来说,在父级HTML模板中,属性名需要使用中划线的写法:

  var parentNode = {tempalte: `<div class="parent"><child my-message="aaa"></child><child my-message="bbb"></child></div> `,components: {'child': childNode}}

子级Props属性声明时,使用小驼峰或者中划线写法都可以;而子级HTML模板使用从父级传来的变量时,需要使用对应的小驼峰写法。

    var childNode = {// HTML模板中使用小驼峰写法template: '<div>{{myMessage}}</div>'// 声明时使用小驼峰或者中划线写法都可props: ['myMessage'] // 或者: props: ['my-message']}

动态props

有时候,传递数据并不是直接写死的,而是来自父级的动态数据,这时可以使用指令v-bind来动态绑定props 的值,当父组件的数据变化时,也会传递给子组件。

 <div id="app5"><input type="text" v-model="parentMessage"><!--动态绑定数据message  --><parent-component :message="parentMessage"></parent-component></div> <script>var app5 = new Vue({el: '#app5',data: {parentMessage: ''},components: {'parent-component': {// 从父级获取来数据messageprops: ['message'],template: `<div class="parent">{{message}}<child-component :my-message="data1"></child-component><child-component :my-message="data2"></child-component></div>`,data(){return {'data1': 'aaa','data2': 'bbb'}},// 子组件components: {'child-component': {// 从父级传递来的数据“myMessage”props: ['myMessage'],template:  `<div class="child">{{ myMessage }}</div>`}}}}})
</script>


这里用v-model绑定了父级的数据parentMessage,当通过输入框任意输入时,子组件接受props“message”也会实时响应并更新组件模板。组件child-component接受props"my-Message"(父组件parent-component返回的数据data1与data2也会实时响应。

传递类型

如果你要直接传递数字、布尔值、数组、对象,而且不使用v-bind指令,传递的仅是字符串类型。

[例如]

    <div id="app6"><parent-component></parent-component></div> <script>var childNode = {props: ["message"],template:  `<div>{{message}}的类型是{{type}}</div>`,// 监听属性返回message的数据类型computed: {type() {return typeof this.message}}}var app6 = new Vue({el: '#app6',components:{'parent-component': {template: `<div class="parent"><child-component :message="1"></child-component></div>`,components: {'child-component': childNode}}           }})
</script>

不加v-bind指令时:

加v-bind之后:

这个例子中子组件从父组件传递过来的数据messge=“1”,用计算属性监听message的类型。本来的用意是1的类型为number类型,但是这里是String类型。当加上v-bind指令时,类型就是number类型 。

单项数据流

Vue2.x与Vue1.x比较大的一个改变就是,Vue2.x通过props传递数据时单向的,也就是父组件数据变化时会传递给子组件但反过来不行。之所以这样设计,是尽可能将父子组件解耦,避免子组件无意中修改了父组件的状态。

每次父组件更新时,子组件的所有prop都会更新为最新值。这意味着不应该在子组件 内部改变prop。如果这么做了,Vue会在控制台给出警告。

[例如]

   <div id="app7"><parent-component></parent-component></div>  <script>var childNode = {props: ['childMsg'],template: `<div class="child"><span>子组件</span><input v-model="childMsg"><p>{{childMsg}}</p></div>`}var app7 = new Vue({el: "#app7",components: {'parent-component': {template: `<div class="parent"><span>父组件</span><input v-model="msg"><p>{{ msg }}</p><child :child-msg="msg"></child></div>`,components:{'child': childNode},data() {return {'msg':'match'}}           }}})
</script>


当父组件数据变化时,子组件数据会相应变化;而修改子组件数据时,父组件数据不变,并在控制台显示警告

[修改prop数据]

业务中会经常遇到两种需要改变prop数据的情况。
1:prop作为初始值传入,子组件将它作为初始值保存起来,在自己的作用域下可以随意使用和修改。
2:prop作为需要被转变的原始值传入。

注意: JS中对象与数组时引用类型,指向同一个内存空间,props选项的数据是一个对象或者数组,在子组件内部改变它会影响父组件的状态。

[第一种情况]

可以在组件data内再声明一个局部变量,引用父组件的prop. 但这种局部的变量只接受prop的初值,当父组件prop发生变化时,子组件无法随着父组件的更新而改变

<div id="app8"><parent-component></parent-component></div><script>var childNode = {props: ['childMsg'],// 使用data保存prop的初始值data() {return {newChildMsg: this.childMsg}},template:   `<div class="child"><span>子组件</span><input v-model="newChildMsg"><p>{{newChildMsg}}</p></div>`}var parentNode = {template:  `<div class="parent"><span>父组件</span><input v-model="msg"><p>{{msg}}</p><child-component :child-msg="msg"></child-component></div>`,components: {'child-component': childNode},data() {return {'msg': "match"}}}var app8 = new Vue({el: '#app8',components: {'parent-component': parentNode}})
</script>

上面的例子子组件除了渲染prop初始值以外,父组件无论怎么改变子组件都不改变;子组件变化,父组件也不改变。

[第二种情况]

可以定义一个计算属性,处理prop的值并返回。

  <div id="app9"><parent-component></parent-component></div>  <script>var childNode = {props:['childMsg'],template: `<div class="child"><span>子组件</span><input v-model="newChildMsg"><p>{{ newChildMsg}}</p>  </div>`,computed: {newChildMsg: function()  {// childMsg的值改变newChildMsg的值也会跟着改变return this.childMsg},}}var parentNode = {template:  `<div class="parent"><span>父组件</span><input v-model="msg"><p>{{msg}}</p> <child-component :child-msg="msg"></child-component>   </div>`,data(){return {'msg': "match"}},components: {'child-component': childNode}}var app9 = new Vue({el:'#app9',components: {'parent-component': parentNode}})
</script>


因为采用的是计算属性,所以子组件的数据无法手动修改.父组件的值改变后,子组件的值会随之而改变。

[watch]

最稳妥的方法是用data声明一个变量存储prop的初始值,并使用watch来观察prop的值的变化。发生变化时更新变量的值。

   <div id="app10"><parent-component></parent-component></div><script>var childNode = {props: ['childMsg'],template: `<div class="child"><span>子组件</span><input v-model="temp"><p>{{temp}}</p></div>`,data() {return {temp: this.childMsg}},watch: {// 监听数据childMsg的变化childMsg: function() {this.temp = this.childMsg;}}}var parentNode = {template: `<div class="parent"><span>父组件</span><input v-model="message"><p>{{ message }}</p><child-component :child-msg="message"></child-component></div>`,components: {'child-component': childNode},data(){return {'message': 'macth'}}}var app10 = new Vue({el: '#app10',components: {'parent-component': parentNode}})
</script>

上例中子组件的数据即可随着父组件数据的变化而变化,又可以手动改写子组件的数据,且不影响父组件的状态。

数据验证

前面介绍的props选项的值都是一个数组,一开始介绍过,除了数组外,还可以是对象,当prop需要 验证的时候,就需要对象写法

  Vue.component('my-component',{props: {// 必须是数字类型propA: Number,// 必须是字符串类型或数字类型propB: [String, Number],// 布尔值,如果没有定义,默认值就是truepropC: {type: Boolean,default: true},// 数字而且必传propD: {type: Number,required: true},// 如果是数组或对象,默认值必须是一个函数来返回propE: {type: Array,default: function() {return [];}},// 自定义一个验证函数propF: {validator: function (value) {return value > 10}}}});

一般的当你的组件需要提供给别人使用时,推荐都进行数据验证,比如某个数据必须是数字类型,如果传入 字符串,就会在控制台弹出警告。

下面的例子,如果传入子组件的message不是数字,则抛出警告 :

 <div id="app11"><parent-component></parent-component></div><script>var childNode = {props:  {'message': Number},template:  `<div>{{ message }}</div>`}var parentNode = {template: `<div class="parent"><child :message="msg"></child>    </div>`,components: {'child': childNode},data() {return{msg:  '123'}}}var app11 = new Vue({el: '#app11',components: {'parent-component':  parentNode}})
</script>

传入数字123时,则无警告提示。传入字符串’123’时,结果如下所示 :

[一个自定义验证函数]

 <div id="app12"><parent-component></parent-component></div><script>var childNode = {props:  {'message':{validator: function(value) {return value > 10}}},template:  `<div>{{ message }}</div>`}var parentNode = {template: `<div class="parent"><child :message="msg"></child>    </div>`,components: {'child': childNode},data() {return{msg:  9}}}var app12 = new Vue({el: '#app12',components: {'parent-component':  parentNode}})
</script>

当传入的数小于10,控制台弹出警告 :

参考:
《Vue.js实战》
https://www.cnblogs.com/xiaohuochai/p/7356084.html

Vue props数据传递相关推荐

  1. Vuejs——(9)组件——props数据传递

    本篇资料来于官方文档: http://cn.vuejs.org/guide/components.html#Props 本文是在官方文档的基础上,更加细致的说明,代码更多更全. 简单来说,更适合新手阅 ...

  2. uniapp 子组件 props拿不到数据_谈一谈使用 webpack 开发时,Vue 组件之间的数据传递...

    •我们在学习Vue的时候,难免会使用各个组件之间传递数据.•先来介绍一下Vue中组件传递的方式,有父组件传递给子组件数据,子组件传递给父组件数据,父组件直接获取子组件中数据,子组件直接获取父组件数据以 ...

  3. vue实现php传数据,vue+props传递数据怎样实现

    这次给大家带来vue+props传递数据怎样实现,vue+props传递数据的注意事项有哪些,下面就是实战案例,一起来看一下. 在 Vue 中,父子组件的关系可以总结为 props向下传递,事件向上传 ...

  4. VUE组件:组件的数据传递(props)

    组件的数据传递 props的作用 使用props流程 ①给组件添加props选项 ②在调用组件时传入实际参数即可 ③完整代码及效果 ④使用props传递分析 使用props传递数据时的一些细节 ①传参 ...

  5. html用vue传递数据,Vue组件及数据传递详解

    本文我们就和大家详细介绍一下Vue系列(三):组件及数据传递.路由.单文件组件.vue-cli脚手架,希望能帮助到大家. 一. 组件component 1. 什么是组件?组件(Component)是 ...

  6. 七十、Vue城市页面Ajax动态渲染和兄弟组件数据传递

    2020/10/29. 周四.今天又是奋斗的一天. @Author:Runsen 写在前面:我是「Runsen」,热爱技术.热爱开源.热爱编程.技术是开源的.知识是共享的.大四弃算法转前端,需要每天的 ...

  7. WEB前端 vue学习二 组件之间的数据传递

    Vue 的组件作用域都是孤立的,不允许在子组件的模板内直接引用父组件的数据.必须使用特定的方法才能实现组件之间的数据传递. 首先用 vue-cli 创建一个项目,其中 App.vue 是父组件,com ...

  8. Vue表单类的父子组件数据传递示例_vue.js_脚本之家

    使用Vue.js进行项目开发,那必然会使用基于组件的开发方式,这种方式的确给开发和维护带来的一定的便利性,但如果涉及到组件之间的数据与状态传递交互,就是一件麻烦事了,特别是面对有一大堆表单的页面. 在 ...

  9. vue笔记(三)生命周期、组件(嵌套)、数据传递

    生命周期文档 一.生命周期 1.参考一 2.参考二 二.自定义组件 1. 使用:<组件名></组件名> 2. 定义组件: (1)方法一:官网 let 组件变量名 = Vue.e ...

最新文章

  1. 程序员崩溃了,年终奖怎么说黄就黄
  2. xp系统本地连接服务器,本地连接,xp系统本地连接不见了怎么办
  3. java多线程(3)Thread的静态方法
  4. Android热修复升级探索——SO库修复方案 1
  5. linux环境安装LFTP_02
  6. perl调用其他的perl_如何使Perl更优雅
  7. 销售行业ERP数据统计分析都有哪些维度?
  8. python系列九:python3迭代器和生成器
  9. 项目管理相关的考试认证及证书价值介绍
  10. 微信投票作弊神器的制作代码
  11. 站在巨人的肩膀上还是站在巨人的脚底下
  12. WinEdit编辑器中中文乱码
  13. php计算第几周,php计算当前是一年或一月中第几周的函数
  14. Spring Cloud Consul 注册服务failing,但是可以访问
  15. ide之从入门到疯癫
  16. 弘辽科技:拼多多推广单元和推广计划是一样的吗?
  17. Java POI解析Word提取数据存储在Excel
  18. POST请求和PUT请求的区别
  19. 什么是NAT模式、路由模式
  20. winds添加静态路由

热门文章

  1. RPA数字化劳动力的优势与核心能力解析
  2. 【献计一刻】如何提高系统分析能力
  3. html5加js兼容性辅助,解决低版本IE关于html5新特性的兼容性问题html5shiv.js和Respond.js,以及excanvas.js解决低版本IE不支持canvas的问题...
  4. Qt QThread
  5. 利用 SSDP 协议生成 100 Gbps DDoS 流量的真相探秘
  6. Nginx+Keepalived+LVS高可用集群----相关知识回顾
  7. 维谛艾默生触摸屏维修EMU10触摸屏监控模块维修
  8. seo-视频学习-关键词布局
  9. 20几分钟完成硬件攒机高手脱变
  10. 记录一个制作图片水印的功能