prop 传递数据
组件实例的作用域是孤立的,父组件不能直接使用子组件的数据,子组件也不能直接使用父组件的数据
父组件在模板中使用子组件的时候可以给子组件传递数据
<div id="app">
<p>{{msg}}</p>
<father></father>
</div>
<template id="father">
<div class="father">
这是father! {{fatherMsg}}
<button @click='fatherMsg=123'>button</button>
<son :parent-msg="fatherMsg"></son>
</div>
</template>
子组件需要通过props属性来接收后才能使用
如果父组件传递属性给子组件的时候键名有’-’,子组件接收的时候写成小驼峰的模式
//Vue.extend() //组件的类 Vue子类 所以组件可以拥有vue实例的绝大多数配置
// 父组件给子组件传递数据的时候,
//子组件需要利用props的属性来确定自己的预期数据
//中间有- 需要写出驼峰的形式来接收
//如果儿子没有通过props属性接受传递过来的数据,则数据会以自定义属性的方式
//放在儿子最外层的根元素上面
//组件之间的数据都是相互独立的。 数据只能在其自己管辖的范围内去使用。
var json = {
fatherMsg:"fatherMsg!!!!!!"
}
Vue.component("father",{
template:"#father",
components:{
son:{
props:["parentMsg"],//声明props来接受父组件传递来的属性
template:"<div>我是son! {{parentMsg}}</div>"
}
},
data(){ //组件内部数据必须写成一个函数,并且内部返回对象形式。
return { //目的就是让每一个实例维护一份被返回对象的独立的拷贝。
fatherMsg:"fatherMsg!!!!!!"
}
}
})
let vm = new Vue({
el: '#app',
data:{
msg:"我是msg!"
}
})
我们可以用 v-bind 来动态地将 prop 绑定到父组件的数据。每当父组件的数据变化时,该变化也会传导给子组件
单向数据流
Prop 是单向绑定的:当父组件的属性变化时,将传递给子组件,但是反过来不会。这是为了防止子组件无意间修改了父组件的状态,来避免应用的数据流变得难以理解。
另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop。如果你这么做了,Vue 会在控制台给出警告。
注意在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。 message:{val:""}
<div id="app">
<father></father>
</div>
<template id="father">
<div>
<input type="text" v-model="message.value">
<son :message="message"></son>
</div>
</template>
<template id="son">
<div>
<input type="text" v-model="message.value">
</div>
</template>
.box{
width: 100px;height: 100px;
}
//Vue/React单向数据流的体现:数据只能从父级组件流向子级组件
//实现父子间的数据共享,依靠的就是应用类型的地址传递
Vue.component("father",{
template:"#father",
data(){
return {
message:{
value:"hello!"
}
}
}
})
Vue.component("son", {
template: "#son",
props:["message"]
})
new Vue({
el:"#app"
})
prop验证
我们可以为组件的 prop 指定验证规则。如果传入的数据不符合要求,Vue 会发出警告。这对于开发给他人使用的组件非常有用
验证主要分为:类型验证、必传验证、默认值设置、自定义验证
props:{
//类型验证:
str:String,
strs:[String,Number],
//必传验证
num:{
type:Number,
required:true
},
//默认数据
bool:{
type:Boolean,
// default:true,
default:function(){
return true
}
},
//自定义验证函数
//props:["nums"]
props:{
nums:{
type:Number, //[Number,String,Boolean,Array]
validator: function (value) {
return value %2 == 0
}
}
}
}
当父组件传递数据给子组件的时候,子组件不接收,这个数据就会挂载在子组件的模板的根节点上
slot
vue里提供了一种将父组件的内容和子组件的模板整合的方法:内容分发,通过slot插槽来实现
- 匿名插槽
<abc>123</abc>
Vue.component("abc",{
template:<div>我是div元素 <slot></slot></div>
})
在父组件中使用子组件的时候,在子组件标签内部写的内容,在子组件的模板中可以通过来使用
- 具名插槽
父组件在子组件标签内写的多个内容我们可以给其设置slot属性来命名,在子组件的模板通过通过使用带有name属性的slot标签来放置对应的slot,当slot不存在的时候,slot标签内写的内容就出现
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<aaa>
<p slot="top">111111</p>
<p slot="bottom">222222</p>
</aaa>
<hr>
<aaa></aaa>
<hr>
<aaa>
<div class="top" slot="top">toptoptoptpt</div>
</aaa>
</div>
<template id="aaa">
<div>
<p>我是aaa组件!</p>
<slot name="top"></slot>
<slot name="bottom"></slot>
</div>
</template>
</body>
<script src="./base/vue.js"></script>
<script>
//在组件标签内部写入的内容默认的会被替换掉,
//如果想要在组件的模板里使用这些内容,
//就在对应的位置写上slot标签,这个slot标签就代表着这些内容
//slot 插槽 匿名 具名槽口
//具名槽口
//slot上面通过name属性指定槽口名称
//然后使用的时候通过slot="槽口名称"
Vue.component("aaa",{
template:"#aaa"
})
new Vue({
el:"#app",
data: {
num:1
}
})
</script>
</html>