Vue 组件的信息传递
最近看了一下vue框架,把里面组件的信息传递总结了一下:哪里写的不对地方,希望大家可以提出宝贵意见!
单向数据流
在vue中,当父组件通过方法改变自己的数据时,如果子组件也用到了这个数据,那么子组件也会跟着更新发生改变;父组件的数据流动到了子组件,子组件更新,这就是vue数据的单向数据流
父子组件的信息交互
父传子:可通过属性传递,子组件先在行内用动态属性接收,然后在组件中用props注册之后才可以使用
```
<html>
<body>
<div id="app">
<my-child :mydata="name"></my-child>
</div>
<template id="myChild">
<p class="bg">{{mydata}}</p>
</template>
</body>
<script>
let my-child={
template:'#myChild',
//简写:props:['mydata'],
props:{ //子组件需要props 接收一下才能用
mydata:{
type:[Number,String], //数据类型检测
default:'大妖', //默认值
required:true, //是否为必传
validator(val){ //自定义规则使用的属性;不管成功与否都会继续渲染页面
//val值为传进来的mydata
return val.length>2
}
}
}
}
let vm=new Vue({
el:'#app',
data:{
name:'小妖',
},
components:{ //[kəmˈpəʊnənts]组件,子组件需要在父组件components注册才能使用
//全写:my-child:my-child,
my-child
}
})
</script>
</html>
```
新增父传后代
把要传递的属性也要先在子组件的行内属性接收一下,子组件通过\$attrs 获取传递的属性值,通过\$listeners 获取传递的方法
孙子组件则需要在行内通过v-bind 接收属性,v-on 接收方法
```
<html>
<body>
<div id="app">
<child :val="a" user='大妖' age="18" @hhh='fn'></child>
</div>
</body>
<script>
let grandson={
template:"<div>{{$attrs.val}}{{$attrs.user}}<button @click='$listeners.f'>改一改</button></div>"
}
let child ={
data(){
return {}
},
components:{
grandson
},
// props:["val"],
// 可以通过v-bind将child的行间的属性以对象的形式传递给grandson组件
// v-bind :属性 v-on : 事件方法
template:"<div><grandson v-bind='$attrs' v-on='$listeners'></grandson></div>"
}
let vm = new Vue({
el:"#app",
data:{
a:"小妖"
},
components:{
child
},
methods:{
fn(){
this.a="小妖现世"
}
}
})
</script>
</html>
```
子传父
+ 通过自定义事件发布订阅,子组件通过this.$emit("方法名") 通知父组件方法执行;简写用.sync修饰符::x.sync="xx" ;在子件中修改用,写在方法中 this.$emit("update:x", mm);mm为要修改的值
```
<html>
<body>
<div id="app">
<!-- 自定义事件:自己起的名字 -->
{{money}}
<!-- 订阅 -->
<son :m="money" @changemoney="fn"></son>
//sync修饰符
<!--<son v-bind:m="money" @update:m="money=$event"></son>-->
<son :m.sync="money"></son>
</div>
</body>
<script>
let son = {
data(){
return {}
},
methods:{
add(){
// 发布订阅==>自定义事件
// 子组件订阅了父组件的方法;在子组件中,触发了父组件的方法,让父组件改变自己的数据;
// 发布让订阅的方法执行
// $emit: 是vue实例的一个方法;发布自定义事件的方法
this.$emit("changemoney");
//update:m 自定义事件的名字
//888是最新值,传给了$event,触发事件必须是update:m
this.$emit("update:m",888);
}
},
props:["m"],
template:"<div>{{m}}<button @click='add'>多要点</button></div>"
}
let vm = new Vue({
el:"#app",
data:{
money:666
},
methods:{
fn(){
this.money=888;
}
},
components:{
son
}
});
</script>
</html>
```
兄弟组件之间的交互
```
<body>
<div id="app">
<bro1></bro1>
<bro2></bro2>
</div>
<body>
<script>
let eventBus = new Vue;// 这个就是个容器,能够把两个兄弟进行关联
let bro1 = {
data(){
return {
color:"红色"
}
},
methods:{
changeBro2(){
// 让eventBus中的订阅的changeRed执行
eventBus.$emit("changeRed");
}
},
template:"<div>{{color}}<button @click='changeBro2'>变红色</button></div>"
};
let bro2= {
data(){
return {
color:"绿色"
}
},
created(){
// created能获取到methods方法
// $on : 订阅;把bro2的事件放到了eventBus这个实例的事件池中
eventBus.$on("changeRed",this.changeRed)
},
methods:{
changeRed(){
this.color="红色";
}
},
template:"<div>{{color}}<button>变绿色</button></div>"
}
new Vue({
el:"#app",
data:{},
methods:{},
components:{
bro1,
bro2
},
})
</script>
```
Vuex:专门解决vue项目的公共数据管理的库
store 是一个实例,state:公共数据
创建Vuex的实例,并注入vue实例中,可以在子组件的钩子函数中使用
在vuex中规定,要改state的数据,必须通过commit来提交一个mutation
```
let store=new Vuex.Store({
state:{
count:100
},
getters:{
//相当于computed ,根据数据依赖技术,有缓存机制
str(state){
//str 执行时,默认会传递进来一个state,第一个参数都是当前store的state
return state.count%2===0?"偶":"奇"
}
},
mutations:{
//mutations 是同步事物
add(state,payload){
//第一项state 默认是store 中的state
//payload :调用函数传递的参数
//vue中唯一改变state的数据方法就是提交mutations
state.count+=payload;
}
},
actions:{
//action提交的是mutation, 不直接更改状态
//action可以异步操作,函数接受一个与 store 实例具有相同方法和属性的 context 对象
increase(context,option){
//context === store的实例,当然也可以把{commit}结构出来
setTimeout(()=>{
context.commit("add",option);
},200)
}
}
})
let child={
data(){
return{}
},
computed:{
//vuex.mapState 返回值是一个对象
//组件的计算属性依赖store中的数据变化
...Vuex.mapState(["count"]),
...Vuex.mapGetters(["str"])
},
methods:{
// mutations中的方法是commit提交
// addCount(val){
// this.$store.commit("add",val);
// }
// actions中的方法是dispatch派发
// addCount(val){
//通知vuex中add 方法执行
// this.$store.dispatch("increase");
// }
...Vuex.mapMutations(["add"])
/*将store中的add方法映射到自己的methods,
并且methods这个方法名字叫aaa*/
// ...Vuex.mapMutations({aaa:"add"})
...Vuex.mapActions(["increase"])
},
template:"<div>{{count}}<p @click='addCount(2)'>累加</p><div>"
}
// 每个模块独立的state;但是getters mutations actions 会注册到全局上;
// 每一个module都可以有自己独立的state getters mutations actions
// 如果私有模块和公有模块存在同样的方法,会把两个方法整合到一起;
let vm=new Vue({
el:"#app",
data:{},
created(){
//可以在生命周期的任何一个钩子函数中使用vuex
console.log(this.$store.state.count)
},
store //把store注入vm实例中
})
```
- 点赞
- 收藏
- 关注作者
评论(0)