Vue props用法详解(小结)

Vue props用法详解

组件接受的选项之一 props 是 Vue 中非常重要的一个选项。父子组件的关系可以总结为:

props down, events up

父组件通过 props 向下传递数据给子组件;子组件通过 events 给父组件发送消息。

父子级组件

比如我们需要创建两个组件 parent 和 child。需要保证每个组件可以在相对隔离的环境中书写,这样也能提高组件的可维护性。

这里我们先定义父子两个组件和一个 Vue 对象:

var childNode = {
 template: `
  <div>childNode</div>
  `
};
var parentNode = {
 template: `
  <div>
   <child></child>
   <child></child>
  </div>
  `,
 components: {
 child: childNode
 }
};
new Vue({
 el: "#example",
 components: {
 parent: parentNode
 }
});
<div id="example">
 <parent></parent>
</div>

这里的 childNode 定义的 template 是一个 div,并且内容是"childNode"字符串。

而在 parentNode 的 template 中定义了 div 的 class 名叫 parent 并且包含了两个 child 组件。

如果大家想对VUE.JS有更加深入系统的学习,可以参阅 Vue.js实战 PDF高质量扫描版 这本经典读物

静态 props

组件实例的作用域是孤立的。这意味着不能(也不应该)在子组件的模板中直接饮用父组件的数据。要让子组件使用父组件的数据,需要通过子组件的 props 选项。

父组件向子组件传递数据分为两种方式:动态和静态,这里先介绍静态方式。

子组件要显示的用 props 声明它期望获得的数据

修改上例中的代码,给 childNode 添加一个 props 选项和需要的forChildMsg数据;

然后在父组件中的占位符添加特性的方式来传递数据。

var childNode = {
 template: `
  <div>
   {{forChildMsg}}
  </div>
  `,
 props: ["for-child-msg"]
};
var parentNode = {
 template: `
  <div>
   <p>parentNode</p>
   <child for-child-msg="aaa"></child>
   <child for-child-msg="bbb"></child>
  </div>
  `,
 components: {
 child: childNode
 }
};

命名规范

对于 props 声明的属性,在父组件的 template 模板中,属性名需要使用中划线写法;

子组件 props 属性声明时,使用小驼峰或者中划线写法都可以;而子组件的模板使用从父组件传来的变量时,需要使用对应的小驼峰写法。别担心,Vue 能够正确识别出小驼峰和下划线命名法混用的变量,如这里的forChildMsgfor-child-msg是同一值。

动态 props

在模板中,要动态地绑定父组件的数据到子组件模板的 props,和绑定 Html 标签特性一样,使用v-bind绑定;

基于上述静态 props 的代码,这次只需要改动父组件:

var parentNode = {
 template: `
  <div>
   <p>parentNode</p>
   <child :for-child-msg="childMsg1"></child>
   <child :for-child-msg="childMsg2"></child>
  </div>
  `,
 components: {
 child: childNode
 },
 data: function() {
 return {
  childMsg1: "Dynamic props msg for child-1",
  childMsg2: "Dynamic props msg for child-2"
 };
 }
};

在父组件的 data 的 return 数据中的 childMsg1 和 childMsg2 会被传入子组件中,

props 验证

验证传入的 props 参数的数据规格,如果不符合数据规格,Vue 会发出警告。

能判断的所有种类(也就是 type 值)有:String, Number, Boolean, Function, Object, Array, Symbol

Vue.component("example", {
 props: {
 // 基础类型检测, null意味着任何类型都行
 propA: Number,
 // 多种类型
 propB: [String, Number],
 // 必传且是String
 propC: {
  type: String,
  required: true
 },
 // 数字有默认值
 propD: {
  type: Number,
  default: 101
 },
 // 数组、默认值是一个工厂函数返回对象
 propE: {
  type: Object,
  default: function() {
  console.log("propE default invoked.");
  return { message: "I am from propE." };
  }
 },
 // 自定义验证函数
 propF: {
  isValid: function(value) {
  return value > 100;
  }
 }
 }
});
let childNode = {
 template: "<div>{{forChildMsg}}</div>",
 props: {
 "for-child-msg": Number
 }
};
let parentNode = {
 template: `
   <div class="parent">
   <child :for-child-msg="msg"></child>
   </div>
  `,
 components: {
 child: childNode
 },
 data() {
 return {
  // 当这里是字符串 "123456"时会报错
  msg: 123456
 };
 }
};

还可以在 props 定义的数据中加入自定义验证函数,当函数返回 false 时,输出警告。

比如我们把上述例子中的 childNode 的for-child-msg修改成一个对象,并包含一个名叫validator的函数,该命名是规定叫validator的,自定义函数名不会生效。

let childNode = {
 template: "<div>{{forChildMsg}}</div>",
 props: {
 "for-child-msg": {
  validator: function(value) {
  return value > 100;
  }
 }
 }
};

在这里我们给for-child-msg变量设置了validator函数,并且要求传入的值必须大于 100,否则报出警告。

单向数据流

props 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件五一修改父组件的状态。

所以不应该在子组件中修改 props 中的值,Vue 会报出警告。

let childNode = {
 template: `
   <div class="child">
   <div>
    <span>子组件数据</span>
    <input v-model="forChildMsg"/>
   </div>
   <p>{{forChildMsg}}</p>
   </div>`,
 props: {
 "for-child-msg": String
 }
};
let parentNode = {
 template: `
   <div class="parent">
   <div>
    <span>父组件数据</span>
    <input v-model="msg"/>
   </div>
   <p>{{msg}}</p>
   <child :for-child-msg="msg"></child>
   </div>
  `,
 components: {
 child: childNode
 },
 data() {
 return {
  msg: "default string."
 };
 }
};

这里我们给父组件和子组件都有一个输入框,并且显示出父组件数据和子组件的数据。当我们在父组件的输入框输入新数据时,同步的子组件数据也被修改了;这就是 props 的向子组件传递数据。而当我们修改子组件的输入框时,浏览器的控制台则报出错误警告

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "forChildMsg"

修改 props 数据

通常有两种原因:

  1. prop 作为初始值传入后,子组件想把它当做局部数据来用
  2. prop 作为初始值传入后,由子组件处理成其他数据输出

应对办法是

定义一个局部变量,并用 prop 的值初始化它

但是由于定义的 ownChildMsg 只能接受 forChildMsg 的初始值,当父组件要传递的值变化发生时,ownChildMsg 无法收到更新。

let childNode = {
 template: `
   <div class="child">
   <div>
    <span>子组件数据</span>
    <input v-model="forChildMsg"/>
   </div>
   <p>{{forChildMsg}}</p>
   <p>ownChildMsg : {{ownChildMsg}}</p>
   </div>`,
 props: {
 "for-child-msg": String
 },
 data() {
 return { ownChildMsg: this.forChildMsg };
 }
};

这里我们加了一个<p>用于查看 ownChildMsg 数据是否变化,结果发现只有默认值传递给了 ownChildMsg,父组件改变只会变化到 forChildMsg,不会修改 ownChildMsg。

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

由于是计算属性,所以只能显示值,不能设置值。我们这里设置的是一旦从父组件修改了 forChildMsg 数据,我们就把 forChildMsg 加上一个字符串"---ownChildMsg",然后显示在屏幕上。这时是可以每当父组件修改了新数据,都会更新 ownChildMsg 数据的。

let childNode = {
 template: `
   <div class="child">
   <div>
    <span>子组件数据</span>
    <input v-model="forChildMsg"/>
   </div>
   <p>{{forChildMsg}}</p>
   <p>ownChildMsg : {{ownChildMsg}}</p>
   </div>`,
 props: {
 "for-child-msg": String
 },
 computed: {
 ownChildMsg() {
  return this.forChildMsg + "---ownChildMsg";
 }
 }
};

更加妥帖的方式是使用变量存储 prop 的初始值,并用 watch 来观察 prop 值得变化。发生变化时,更新变量的值。

let childNode = {
 template: `
   <div class="child">
   <div>
    <span>子组件数据</span>
    <input v-model="forChildMsg"/>
   </div>
   <p>{{forChildMsg}}</p>
   <p>ownChildMsg : {{ownChildMsg}}</p>
   </div>`,
 props: {
 "for-child-msg": String
 },
 data() {
 return {
  ownChildMsg: this.forChildMsg
 };
 },
 watch: {
 forChildMsg() {
  this.ownChildMsg = this.forChildMsg;
 }
 }
};

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • vue父组件通过props如何向子组件传递方法详解

    前言 本文主要给大家介绍了关于vue中父组件通过props向子组件传递方法的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: vue 组件中的 this vue 中 data/computed/methods 中 this的上下文是vue实例,需注意. 例如: 注意:不应该对 data 属性使用箭头函数 (例如data: () => { return { a: this.myProp }} ) .理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例

  • Vue中props的详解

    看一下官方文档: 组件实例的作用域是孤立的.这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据.父组件的数据需要通过 prop 才能下发到子组件中. 也就是props是子组件访问父组件数据的唯一接口. 详细一点解释就是: 一个组件可以直接在模板里面渲染data里面的数据(双大括号). 子组件不能直接在模板里面渲染父元素的数据. 如果子组件想要引用父元素的数据,那么就在prop里面声明一个变量(比如a),这个变量就可以引用父元素的数据.然后在模板里渲染这个变量(前面的a),这时候渲染

  • 详解vue2父组件传递props异步数据到子组件的问题

    测试环境:vue v2.3.3, vue v2.3.1 案例一 父组件parent.vue // asyncData为异步获取的数据,想传递给子组件使用 <template> <div> 父组件 <child :child-data="asyncData"></child> </div> </template> <script> import child from './child' export de

  • vue之父子组件间通信实例讲解(props、$ref、$emit)

    组件是 vue.js 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用.那么组件间如何通信,也就成为了vue中重点知识了.这篇文章将会通过props.$ref和 $emit 这几个知识点,来讲解如何实现父子组件间通信. 在说如何实现通信之前,我们先来建两个组件father.vue和child.vue作为示例的基础. //父组件 <template> <div> <h1>我是父组件!</h1> <child>

  • 详解vue.js之props传递参数

    本篇文章通过demo实例给大家详细分析了props传递参数的用法以及遇到问题后的解决办法,以下是全部内容. 前段时间用vue做一个后台管理系统,其中每一页都需要一个表格来展示信息.自然就想到了将表格提取出来做成公共组件,将不同页面的数据传入进行渲染,达到复用的目的. demo地址 1. 问题发现 在父组件中,需要向表格组件传递的数据有表格的内容数据tableData,表格的页面数据page. <div> <my-table :table-data="tableData"

  • 简单理解vue中Props属性

    本文实例为大家解析了vue中Props的属性,供大家参考,具体内容如下 使用 Props 传递数据 组件实例的作用域是孤立的.这意味着不能并且不应该在子组件的模板内直接引用父组件的数据.可以使用 props 把数据传给子组件. "prop" 是组件数据的一个字段,期望从父组件传下来.子组件需要显式地用 props 选项 声明 props: Vue.component('child', { // 声明 props props: ['msg'], // prop 可以用在模板内 // 可以

  • vue父组件向子组件(props)传递数据的方法

    vue页面结构 在做项目的时候常常有这样的一个情况,这个页面的数据(比如:id号)要带到另一个页面去查询某个数据的详情等,传统的作法不是在url上加参数,cookie或者是现在H5的"sessionStorage"和"localStorage"上赋值,这是页面之间传递的方法. 随着Angularjs,React,Vue的流行组件式的开发方式成为另一种不错的解决方案. 最近就有一些小伙伴问我,vue组件之间是如何传递参数的?其实vue是有三种方式可以组件之间传递数据(

  • Vuejs第九篇之组件作用域及props数据传递实例详解

    本篇资料来于官方文档: http://cn.vuejs.org/guide/components.html#Props 本教程是小编结合官方文档整理的一套更加细致,代码更多更全的教程,特别适合新手阅读. props数据传递 ①组件实例的作用域: 是孤立的,简单的来说,组件和组件之间,即使有同名属性,值也不共享. <div id="app"> <add></add> <del></del> </div> <sc

  • Vue2实现组件props双向绑定

    Vue学习笔记-3 前言 Vue 2.x相比较Vue 1.x而言,升级变化除了实现了Virtual-Dom以外,给使用者最大不适就是移除的组件的props的双向绑定功能. 以往在Vue1.x中利用props的twoWay和.sync绑定修饰符就可以实现props的双向绑定功能,但是在Vue2中彻底废弃了此功能,如果需要双向绑定需要自己来实现. Vue2的组件props通信方式 在Vue2中组件的props的数据流动改为了只能单向流动,即只能由组件外(调用组件方)通过组件的DOM属性attribu

  • vue组件中使用props传递数据的实例详解

    在 Vue 中,父子组件的关系可以总结为 props向下传递,事件向上传递.父组件通过 props 给子组件下发数据,子组件通过事件给父组件发送消息.看看它们是怎么工作的.  一.基本用法 组件不仅仅是要把模板的内容进行复用,更重要的是组件间要进行通信. 在组件中,使用选项props 来声明需要从父级接收的数据, props 的值可以是两种, 一种是字符串数组,一种是对象. 1.1 字符串数组: <div id="app4"> <my-component4 messa

随机推荐