Prop

Prop

使用Prop传递数据

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

子组件要显式地用 props 选项声明它期待获得的数据:

Vue.component("child", {
  // 声明 props
  props: ["message"],
  // 就像 data 一样,prop 可以用在模板内
  // 同样也可以在 vm 实例中像 “this.message” 这样使用
  template: "<span>{{ message }}</span>"
})

然后我们可以这样向它传入一个普通字符串:

<child message="hello!"></child>

完整代码示例:

		<div id="app">
			<child message="hello!"></child>
		</div>
		<script type="text/javascript">
			Vue.component("child", {
			  // 声明 props
			  props: ["message"],
			  // 就像 data 一样,prop 可以用在模板内
			  // 同样也可以在 vm 实例中像 “this.message” 这样使用
			  template: "<span>{{ message }}</span>"
			})
		new Vue({
			el:"#app"
		});
	</script>
页面显示效果为:hello

### camelCase vs.kebab-case
HTML 特性是不区分大小写的。所以,当使用的不是字符串模版,camelCased (驼峰式) 命名的 prop 需要转换为相对应的 kebab-case (短横线隔开式) 命名:

Vue.component("child", {
// camelCase in JavaScript
props: ["myMessage"],
template: "{{ myMessage }}"
})


如果你使用字符串模版,则没有这些限制。
>[info]完整代码示例:
	<div id="app">
		<child my-message="hello!"></child>
	</div>

	<script type="text/javascript">
		Vue.component("child", {
		  // camelCase in JavaScript
		  props: ["myMessage"],
		  template: "<span>{{ myMessage }}</span>"
		})
		new Vue({
			el:"#app"
		});
	</script>

### 动态Prop
在模板中,要动态地绑定父组件的数据到子模板的props,与绑定到任何普通的HTML特性相类似,就是用 v-bind。每当父组件的数据变化时,该变化也会传导给子组件:

使用 v-bind 的缩写语法通常更简单:
>[info]完整代码示例:
	<div id="app">
		<input v-model="parentMsg">
	    <br>
	    <child v-bind:my-message="parentMsg"></child>
	</div>

	<script type="text/javascript">
		new Vue({
			el:"#app",
			data: {
			    parentMsg: "Message from parent"
			},
			components: {
			    child: {
			      props: ["myMessage"],
			      template: "<span>{{myMessage}}</span>"
			    }
			}
		});
	</script>
### 字面量语法 VS 动态语法
初学者常犯的一个错误是使用字面量语法传递数值:
因为它是一个字面 prop ,它的值是字符串 "1" 而不是number。如果想传递一个实际的number,需要使用 v-bind ,从而让它的值被当作 JavaScript 表达式计算:
### 单向数据流
prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。
另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop 。如果你这么做了,Vue 会在控制台给出警告。

为什么我们会有修改prop中数据的冲动呢?通常是这两种原因:
- prop 作为初始值传入后,子组件想把它当作局部数据来用;
- prop 作为初始值传入,由子组件处理成其它数据输出。

对这两种原因,正确的应对方式是:
- 1.定义一个局部变量,并用 prop 的值初始化它:

props: ["initialCounter"],
data: function () {
return { counter: this.initialCounter }
}

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

props: ["size"],
computed: {
normalizedSize: function () {

return this.size.trim().toLowerCase()

}
}

>[danger]注意在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。

### Prop验证
我们可以为组件的 props 指定验证规格。如果传入的数据不符合规格,Vue 会发出警告。当组件给其他人使用时,这很有用。
要指定验证规格,需要用对象的形式,而不能用字符串数组:

Vue.component("example", {
props: {

// 基础类型检测 (`null` 意思是任何类型都可以)
propA: Number,
// 多种类型
propB: [String, Number],
// 必传且是字符串
propC: {
  type: String,
  required: true
},
// 数字,有默认值
propD: {
  type: Number,
  default: 100
},
// 数组/对象的默认值应当由一个工厂函数返回
propE: {
  type: Object,
  default: function () {
    return { message: "hello" }
  }
},
// 自定义验证函数
propF: {
  validator: function (value) {
    return value > 10
  }
}

}
})

type 可以是下面原生构造器:
- String
- Number
- Boolean
- Function
- Object
- Array
type 也可以是一个自定义构造器函数,使用 instanceof 检测。
当 prop 验证失败,Vue会在抛出警告 (如果使用的是开发版本)。
文章导航