熟悉vue各类关系的组件之间传值方法会令开发更加得心应手,下面将对父子、兄弟、页级组件之间的传值作浅谈。
一、父子关系组件
- 父向子组件传值
父组件向子组件传值通常是利用props
属性。首先,在子组件里定义一个props值用来接收父组件数据;然后调用子组件并v-bind绑定这个props值 = 父组件的data值。
父组件代码:
<template>
<div class="home">
<HelloWorld :newMsg="msg" />
//绑定子组件newMsg(props值) = 父组件msg(data值)
</div>
</template>
<script>
import HelloWorld from "@/components/HelloWorld.vue";
export default {
name: "Home",
data(){
return{msg:'Welcome to Vue.js'} //父组件数据msg
},
components: {HelloWorld}
};
</script>
子组件代码:
<template>
<div>
<h1>{{ newMsg }}</h1> //直接调用newMsg,显示“Welcome to Vue.js”
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {newMsg: String} //为子组件定义newMsg(props值)接收父组件msg
//或者props:['newMsg']
};
</script>
- 子向父组件传值
子组件向父组件传值有两种方式:
1. 利用$emit()方法。 首先在子组件中用$emit()
向上传递一个自定义事件并附带想要传递的数据;然后在父组件v-on监听这个自定义事件并自动接收到数据;最后在响应该事件的方法中进行数据操作。
子组件代码:
<script>
export default {
name: "HelloWorld",
data() {
return {msg:"Welcome to Vue"} //data值,即将向上传递的值
},
created(){
this.$emit('change',this.msg) //向上传递自定义事件change和data值。这里我调用created生命周期函数触发$emit()
}
};
</script>
父组件代码:
<template>
<div class="home">
<HelloWorld @change="handle" /> //监听到子组件传递来的事件并响应handle方法
<span>{{newMsg}}</span> //直接调用newMsg,显示“Welcome to Vue”
</div>
</template>
<script>
import HelloWorld from "@/components/HelloWorld.vue";
export default {
name: "Home",
data() {
return {newMsg:""}
},
methods:{
handle(msg){ //定义handle方法,将自动接收到的msg值给了自己的newMsg
this.newMsg = msg
}
},
components: {HelloWorld}
};
</script>
2.利用ref属性。 ref是vue提供的内部属性,它其实相当于类似"id""class"的标识。首先在子组件上定义ref值(例:ref="son"
);然后在父组件中用this.\$refs.son
即可获取到son这个ref的组件,进行操作。
子组件代码:
<script>
export default {
name: "HelloWorld",
data() {
return {msg:"Welcome to Vue"} //即将向父传递的data值
}
};
</script>
父组件代码:
<template>
<div class="home">
<HelloWorld ref="son" /> //在子组件上定义一个ref 名为"son"
</div>
</template>
<script>
import HelloWorld from "@/components/HelloWorld.vue";
export default {
name: "Home",
mounted(){
console.log(this.$refs.son.msg) //获取到ref名为"son"的子组件内msg数据,在控制台显示“Welcome to Vue”
},
components:{HelloWorld}
};
</script>
二、兄弟关系组件
兄弟组件间的传值方式我称为 “总线转送” 。原理很简单,利用父组件作为总线去转送数据。首先,用上述讲到的ref
属性或$emit()
将组件A的数据向上传递给父组件;再由父组件通过props
属性向下传值到组件B。
组件A代码:
<template>
<div>click me</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {helloMsg:"Welcome to Vue"} //即将传送的数据helloMsg
}
};
</script>
组件B代码:
<template>
<div>
{{hiMsg}} //直接调用hiMsg,显示“Welcome to Vue”
</div>
</template>
<script>
export default {
name: "Hi",
props:{hiMsg:String} //用来接收父组件传值的props属性hiMsg
};
</script>
父组件代码:
<template>
<div class="home">
<HelloWorld ref="son" @click.native="change"></HelloWorld> //定义ref属性接收组件A传来的数据;点击组件A触发change()
<Hi :hiMsg="msg"></Hi> //绑定组件B的hiMsg=msg,将数据转发给组件B
</div>
</template>
<script>
import HelloWorld from "@/components/HelloWorld.vue";
import Hi from "@/components/Hi.vue";
export default {
name: "Home",
data(){
return{ msg: "" }
},
methods:{
change(){
return this.msg = this.$refs.son.helloMsg //将组件A传来的helloMsg赋予this.msg
}
},
components:{HelloWorld, Hi}
};
</script>
三、页级关系组件
在vuecli3.0以后,项目结构对组件级别作了明确的区别:入口组件(App) - 页级组件(View) - 零件组件(Component)。一般在开发中我们也会尽量按照这种结构去划分模块,但页级组件没有父组件,如果说页级组件之间需要传值,那就不能用“总线转送”的方法了。
vuex: 这是官方提供的一个插件,可称为“状态管理仓库”,用来管理项目中需要跨页共享反复调用的状态(状态你可以理解成就是数据、变量、方法)。
vuex的存放仓库为Store,内部结构可分五大块:
state: 状态库,寄放基础状态。
mutations: 同步方法,可理解成相当于组件内的computed属性,接收state进行改装。
actions: 异步方法,只针对mutations,接收并改装。
getters: 过滤器,对state调用前进行改装、派生并返回数据。
modules: 模块,在复杂项目中用modules处理Store,使分工更清晰。
vuex令开发中数据共享操作更得心应手,还需要大家到官方文档认真学习,后续也可能将会对vuex相关知识作分享。