组件传递对象参数
基于组件基础的学习,我们可以看到vue不允许在子组件中修改props(父组件传入的参数)的值,但是有些时候,我们需要在父组件传入一些参数让子组件修改,然后再将修改后的值返回,这时我们使用自定义事件的方式,基本步骤是
子组件声明props参数
子组件data中将props参数复制(避免直接修改参数,而是将props的参数作为初始值,后续修改复制的值),注意如果参数是对象,应该使用深拷贝
子组件中的控件绑定拷贝的值
子组件watch拷贝的值(注意如果是对象,应该使用deep watch)
在watch中,使用this.$emit()引发一个自定义事件,第一个参数是事件的名字,第二个参数是向监听器发送的参数,监听器可以通过$event获取这个参数
在父组件声明数据
父组件引用子组件,绑定传入参数,并监听第5步的自定义事件,把$event赋值给父组件的数据
这样就完成了父组件向子组件传递一个数据,子组件中进行修改,当子组件修改了数据,父组件中的值也能跟着修改
传递基本类型的值可以参考昨天的笔记,下面是传递对象类型数据的例子
子组件
<template>
<div>
<input type="radio" value="0" v-model.number="idInfoCopy.country"/>中国
<input type="radio" value="1" v-model.number="idInfoCopy.country"/>其他<br/>
<input type="text" v-model="idInfoCopy.value" v-if="idInfoCopy.country === 0" placeholder="请输入身份证"/>
<input type="text" v-model="idInfoCopy.value" v-else placeholder="请输入护照"/>
</div>
</template>
<script>
export default {
name: "IdInfoInputComponent",
props: ['idInfo'], // 这个idInfo是个对象,结构: {country: 0, value: ''}
data: function () {
return {
// idInfoCopy: this.idInfo 对象副本不能这么拷贝,因为是引用
idInfoCopy: JSON.parse(JSON.stringify(this.idInfo)), // 使用深拷贝拷贝对象
}
},
watch: {
// 观察idInfoCopy的变化,页面一输入,就会变化
idInfoCopy: {
handler: function(val){
// 当idInfoCopy发生了变化,通过Vue的$emit对象,引发一个自定义的事件,叫做 infoChange,
// 事件参数是:val,这样监听infoChange事件的地方通过$event就能获取val的值
this.$emit('infoChange', val);
},
deep: true
}
}
}
</script>
<style scoped>
</style>
父组件
<template>
<div class="about">
<!-- <h1>This is an about page</h1>-->
<table align="center">
<tr>
<td>用户名</td>
<td><input type="text" :value="user.username"></td>
</tr>
<tr>
<td>密码</td>
<td><password-safe-component :default-pass="user.password" @passChange="user.password = $event"></password-safe-component></td>
</tr>
<input type="button" @click="doLogin" value="登陆"/>
</table>
<!-- 组件的复用 -->
<!-- <password-safe-component></password-safe-component>-->
<!-- <password-safe-component></password-safe-component>-->
<!-- <password-safe-component></password-safe-component>-->
<!-- <password-safe-component></password-safe-component>-->
<!-- <password-safe-component></password-safe-component>-->
<id-info-input-component :id-info="idInfo" @infoChange="idInfo = $event"></id-info-input-component>
<button @click="commit">提交</button>
</div>
</template>
<script>
import PasswordSafeComponent from "@/components/PasswordSafeComponent";
import IdInfoInputComponent from "@/components/IdInfoInputComponent";
export default {
name: 'About',
components: {IdInfoInputComponent, PasswordSafeComponent},
comments: {
PasswordSafeComponent
},
data: function(){
return {
user: {
username: 'admin',
password: '123456'
},
idInfo: {
country: 1,
value: 'A11544'
}
}
},
methods: {
doLogin(){
console.log(this.user);
},
commit(){
console.log(this.idInfo.country, this.idInfo.value);
}
}
}
</script>