Vue.js教程(十)--组件间的数据传递

1. 父子组件

 在一个组件内部定义另一个组件,称为父子组件。子组件只能在父组件中使用。
 默认情况下,子组件无法访问父组件中的数据,每个组件实例的作用域是独立的

2. 组件间数据传递(通信)

(1) 子组件访问父组件中的数据

a)在调用子组件时,绑定想要获取的父组件的数据

b)在子组件内部,使用props选项声明获取的数据,即接收来自父组件的数据。 注:组件中的数据共有三种形式,data、props、computed

示例:

<!doctype html>
<html>
 <head>
 <meta charset="utf-8">
 <title></title>
 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
 <link href="../css/mui.min.css" rel="stylesheet" />
 </head>
 <body>
 <div class="mui-content" id="content">
 <my_hello></my_hello>
 </div>
 <!-- <template>必须有且只有一个根元素 -->
 <template id="hello">
 <div>
 <h4>我是hello父组件</h4>
 <h4>访问自己的数据:{{msg}}、{{name}}、{{age}}、{{user.id}}</h4>
 
 <hr>
 <my_world :message="msg" :age="age" :user="user"></my_world>
 </div>
 </template>
 
 <template id="world">
 <div>
 <h5>我是world子组件</h5>
 <h5>访问父组件中的数据:{{message}},{{age}}、{{user.username}}</h5>
 </div>
 </template>
 <script src="../js/vue.js"></script>
 <script src="../js/mui.min.js"></script>
 <script type="text/javascript">
 mui.init()
 var vm = new Vue({ //根组件
 el: "#content",
 components: {
 'my_hello': { //父组件
 template: "#hello",
 data() {
 return {
 msg: 'hello',
 name: 'jack',
 age: 23,
 user: {
 id: 2014311951,
 username: 'yxc'
 }
 }
 },
 components: {
 'my_world': { //子组件
 template: '#world',
 props:['message','age','user']//接收父组件传过来的数据
 }
 }
 }
 }
 })
 </script>
 </body>
</html>

props props 可以是数组或对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值。

你可以基于对象的语法使用以下选项:

  • type: 可以是下列原生构造函数中的一种:String、Number、Boolean、Array、Object、Date、Function、Symbol、任何自定义构造函数、或上述内容组成的数组。会检查一个 prop 是否是给定的类型,否则抛出警告。Prop 类型的更多信息在此。
  • default: any 为该 prop 指定一个默认值。如果该 prop 没有被传入,则换做用这个值。对象或数组的默认值必须从一个工厂函数返回。
  • required: Boolean 定义该 prop 是否是必填项。在非生产环境中,如果这个值为 truthy 且该 + prop 没有被传入的,则一个控制台警告将会被抛出。
  • validator: Function 自定义验证函数会将该 prop 的值作为唯一的参数代入。在非生产环境下,如果该函数返回一个 falsy 的值 (也就是验证失败),一个控制台警告将会被抛出。你可以在这里查阅更多 prop 验证的相关信息。 示例:

// 简单语法

Vue.component('props-demo-simple', {
 props: ['size', 'myMessage']
})
// 对象语法,提供验证
Vue.component('props-demo-advanced', {
 props: {
 // 检测类型
 height: Number,
 // 检测类型 + 其他验证
 age: {
 type: Number,
 default: 0,
 required: true,
 validator: function (value) {
 return value >= 0
 }
 }
 }
})

示例:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<link href="../css/mui.min.css" rel="stylesheet" />
</head>
<body>
<div class="mui-content" id="content">
<my_hello></my_hello>
</div>
<!-- <template>必须有且只有一个根元素 -->
<template id="hello">
<div>
<h4>我是hello父组件</h4>
<h4>访问自己的数据:{{msg}}、{{name}}、{{age}}、{{user.id}}</h4>
<hr>
<my_world :message="msg" :age="age" :name="name" :user="user"></my_world>
</div>
</template>
<template id="world">
<div>
<h5>我是world子组件</h5>
<h5>访问父组件中的数据:{{message}},{{age}},{{name}},{{user.username}}</h5>
</div>
</template>
<script src="../js/vue.js"></script>
<script src="../js/mui.min.js"></script>
<script type="text/javascript">
mui.init()
var vm = new Vue({ //根组件
el: "#content",
components: {
'my_hello': { //父组件
template: "#hello",
data() {
return {
msg: 'hello',
name: 'jack',
age: 23,
user: {
id: 2014311951,
username: 'yxc'
}
}
},
components: {
'my_world': { //子组件
template: '#world',
// props:['message','age','user']//接收父组件传过来的数据
props: { //也可以是对象,允许配置高级设置,如类型判断,数据校验,设置默认值
message: String,
age: {
type: Number,
default: 18,
validator: function(value) {
return value >= 0;
}
},
name: {
type: String,
required: true,
},
user: {
type: Object,
default: function(){//对象或数组的默认值必须使用函数的属性来返回
return {id: 2014311950,username: 'jack'};
}
}
}
}
}
}
}
})
</script>
</body>
</html>

总结:父组件通过props向下传递数据给子组件

(2)父组件访问子组件中的数据

a)在子组件中使用vm.$emit(事件名,数据)出发一个自定义事件,事件名自定义

b)父组件在使用子组件的地方监听子组件触发的事件,并在父组件中定义方法,用来获取数据

示例:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<link href="../css/mui.min.css" rel="stylesheet" />
</head>
<body>
<div class="mui-content" id="content">
<my_hello></my_hello>
</div>
<!-- <template>必须有且只有一个根元素 -->
<template id="hello">
<div>
<h4>我是hello父组件</h4>
<h4>访问自己的数据:{{msg}}、{{name}}、{{age}}、{{user.id}}</h4>
<h4>访问子组件中的数据:{{h_sex}},{{h_height}}</h4>
<hr>
<my_world :message="msg" :age="age" :name="name" :user="user" @e-world="getData"></my_world>
</div>
</template>
<template id="world">
<div>
<h5>我是world子组件</h5>
<h5>访问父组件中的数据:{{message}},{{age}},{{name}},{{user.username}}</h5>
<button @click="sendData()">将子组件中的数据向上发送到父组件</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script src="../js/mui.min.js"></script>
<script type="text/javascript">
mui.init()
var vm = new Vue({ //根组件
el: "#content",
components: {
'my_hello': { //父组件
template: "#hello",
methods: {
getData(sex, height) {
console.log(sex);
console.log(height);
this.h_sex = sex;
this.h_height = height;
}
},
data() {
return {
msg: 'hello',
name: 'jack',
age: 23,
user: {
id: 2014311951,
username: 'yxc'
},
h_sex: '',
h_height: ''
}
},
components: {
'my_world': { //子组件
data() {
return {
sex: 'male',
height: 100
}
},
template: '#world',
// props:['message','age','user']//接收父组件传过来的数据
props: { //也可以是对象,允许配置高级设置,如类型判断,数据校验,设置默认值
message: String,
age: {
type: Number,
default: 18,
validator: function(value) {
return value >= 0;
}
},
name: {
type: String,
required: true,
},
user: {
type: Object,
default: function() { //对象或数组的默认值必须使用函数的属性来返回
return {
id: 2014311950,
username: 'jack'
};
}
}
},
methods: {
sendData() {
console.log(this); //这个this表示当前子组件实例
this.$emit('e-world', this.sex, this.height); //触发一个自定义事件,发送数据
}
}
}
}
}
}
})
</script>
</body>
</html>

总结:子组件通过events给父组件发送消息,实际上就是子组件把自己的数据发送到父组件。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部