vue中的父组件传递数据给子组件、子组件传递数据给父组件
1、父组件传递数据给子组件
中心思想:父组件向子组件传值,需要通过props
1.1 父传子数组
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="../helloVue/js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 父组件向子组件传值,需要通过props -->
<cpn :cmessage="message" :cmovies="movies"></cpn>
</div>
<template id="cpn">
<div>
<h1>{{cmessage}}</h1>
<ul>
<li v-for="movie in cmovies">{{movie}}</li>
</ul>
</div>
</template>
<script>
const cpn = {
// 子组件
template: '#cpn',
data() {
return {
title: 'VUE'
}
},
props:['cmessage','cmovies']
}
var app = new Vue({
el: '#app',
data: {
message:'语文',
movies:['姜子牙','西游记','大话西游']
},
methods: {
},
components: {
cpn
}
})
</script>
</body>
</html>
1.2 父传子对象
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="../helloVue/js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 父组件向子组件传值,需要通过props -->
<cpn :cmessage="message" :cmovies="movies"></cpn>
</div>
<template id="cpn">
<div>
<h1>{{cmessage}}</h1>
<ul>
<li v-for="movie in cmovies">{{movie}}</li>
</ul>
</div>
</template>
<script>
const cpn = {
// 子组件
template: '#cpn',
data() {
return {}
},
props: {
// 不能使用驼峰命名法
cmessage: {
type:String,
default:'111',
required:true
},
cmovies:{
type:Array,
default:[]
}
}
}
var app = new Vue({
el: '#app',
data: {
message:'语文',
movies:['姜子牙','西游记','大话西游']
},
methods: {
},
components: {
cpn
}
})
</script>
</body>
</html>
2、子组件传递数据给父组件
当子组件需要向父组件传递数据的时候,就需要用到自定义事件来完成,v-on不仅可以用来监听dom事件,也可以用来监听组件间的自定义事件
流程:
在子组件中,用$emit()来触发事件
在父组件中,通过v-on来监听子组件事件
步骤:
1.$emit()通过自定义事件,并发射数据
2.在所挂载的组件中使用所发射的自定义事件
3.在父级方法中使用自定义事件中所触发的方法获取数据
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="../helloVue/js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 2、在所挂载的组件中使用所发射的自定义事件 -->
<cpn @item-click="cpnClick"></cpn>
</div>
<template id="cpn">
<div>
<button v-for="item in goods" @click = "btnClick(item)">{{item.name}}</button>
</div>
</template>
<script>
const cpn = {
// 子组件
template: '#cpn',
data() {
return {
goods:[
{ id: 1, name: '牛奶' },
{ id: 2, name: '零食' },
{ id: 3, name: '大米' },
{ id: 4, name: '水果' },
]
}
},
methods: {
// 1.$emit()通过自定义事件item-click名称,发射数据item
btnClick(item){
this.$emit('item-click',item)
}
}
}
var app = new Vue({
el: '#app',
data: {
message: '好困困困困困'
},
methods: {
// 3.在父级方法中使用自定义事件中所触发的方法获取数据
cpnClick(item){
console.log(item)
}
},
components: {
cpn
}
})
</script>
</body>
</html>
父传子、子传父案例
需求:
将父组件的数组传递给子组件,再在子组件中修改数据后再传递给父组件
思路
1.通过在子组件中使用props将父组件的数据传递过来
2.在子组件中修改传递过来的数据,但不能利用绑定来直接修改props中的数据
解决办法:通过在子组件的data中声明一个中间者,修改中间者
3.将子组件所修改的中间者通过$emit()发送数据给父组件
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="../helloVue/js/vue.js"></script>
</head>
<body>
<div id="app">
<h2>父组件num1: {{num1}}</h2>
<h2>父组件num2: {{num2}}</h2>
<cpn :number1="num1" :number2="num2" @num1change=number1change @num2change=number2change></cpn>
</div>
<template id="cpn">
<div>
<p>{{number1}}</p>
<input type="text" @input=num1Change :value="number1">
<p>{{number2}}</p>
<input type="text" @input=num2Change :value="number2">
</div>
</template>
<script>
var cpn = {
template: '#cpn',
data() {
return {
cnum1:this.number1,
cnum2:this.number2
}
},
props: {
number1:{
type:Number
},
number2: {
type: Number
}
},
methods: {
num1Change(event) {
this.cnum1 = event.target.value*1
this.$emit('num1change', this.cnum1)
},
num2Change(event) {
this.cnum1 = event.target.value * 1
this.$emit('num2change', this.cnum2)
}
}
}
var app = new Vue({
el: '#app',
data: {
num1:1,
num2:2
},
methods: {
number1change(value){
this.num1 = value
},
number2change(value) {
this.num2 = value
}
},
components: {
cpn
}
})
/*
* 父级里面有数据,子级里面没有数据
* 父级的data数据传入props,props传入子级data
* 子级data驱动input和p里的内容
* 子级input输入时,修改了子级的data,并且发射给父级,父级修改自身的data
* 父级data再次流入props
* */
</script>
</body>
</html>
通过watch的父子访问案例
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="../helloVue/js/vue.js"></script>
</head>
<body>
<div id="app">
<h2>父组件num1: {{num1}}</h2>
<cpn :number1="num1" :number2="num2" @num1change=number1change @num2change=number2change></cpn>
</div>
<template id="cpn">
<div>
<p>{{number1}}</p>
<input type="text" v-model="cnum1">
<p>{{number2}}</p>
<input type="text" v-model="cnum2">
</div>
</template>
<script>
var cpn = {
template: '#cpn',
data() {
return {
cnum1: this.number1,
cnum2: this.number2
}
},
props: {
number1: {
type: Number
},
number2: {
type: Number
}
},
watch: {
cnum1(newValue,oldValue) {
this.$emit('num1change', this.cnum1*1)
},
cnum2(newValue) {
this.$emit('num2change', this.cnum2*1)
}
}
}
var app = new Vue({
el: '#app',
data: {
num1: 1,
num2: 2
},
methods: {
number1change(value) {
this.num1 = value
},
number2change(value) {
this.num2 = value
}
},
components: {
cpn
}
})
</script>
</body>
</html>