父传子
父传子:主要通过props来实现的
具体实现:父组件通过import引入子组件,并注册,在子组件标签上添加要传递的属性,子组件通过props接收,
接收有两种形式一是通过数组形式[‘要接收的属性’ ],二是通过对象形式{ }来接收,对象形式可以设置要传递
的数据类型和默认值,而数组只是简单的接收
//父组件页面
<div id="app">
<child :data="data" />
</div>
//父组件引入:
import child from '@/views/child.vue'
//组件注册:
components:{
child
}
//子组件接收数据
//子组件被动接收父组件数据,这种方式不能直接修改父组件数据
props:{
data:{
type:String|Number,
default:''
}
}
//子组件主动获取父组件数据,这种方式可以直接修改父组件数据
this.$parent.data/$parent.data;
子传父
子传父:主要通过$emit来实现
具体实现:子组件通过通过绑定事件触发函数,在其中设置this.$emit(‘自定义事件名称’,要传递的值)
,$emit中有两个参数一是要派发的自定义事件,第二个参数是要传递的值
然后父组件中,在这个子组件身上@派发的自定义事件,绑定事件触发的methods中的方法接受的默认值,就是传递
过来的参数
//父组件
<div>
<child ref="myChild" @change="changeParent" />
</div>
//子组件给父组件传值
this.$emit('change','来自子组件的数据')
export:{
methods:{
changeParent(val){
//val的值师"来自子组件的数据"
}
}
}
//父组件主动获取子组件数据,父组件只有一个子组件时,下标取0
this.$children[0].data;
this.$refs.myChild.data;
兄弟之间
兄弟之间传值有两种方法:
方法一:通过event bus.js实现
具体实现:创建一个空的vue并暴露出去,这个作为公共的bus,即当作两个组件的桥梁,在两个兄弟组件中分别
引入刚才创建的bus,在组件A中通过bus.$emit(’自定义事件名’,要发送的值)发送数据,在组件B中
通过bus.$on(‘自定义事件名‘,function(v) { //v即为要接收的值 })接收数据
bus.js文件内容
import Vue from 'vue'
export default new Vue();
//a组件自定义事件
bus.$emit('change','来自兄弟的数据');
//b组件接收
bug.$on('change',function(val){
//val的值为"来自兄弟的数据"
})
方法二:通过vuex实现
具体实现:vuex是一个状态管理工具,主要解决大中型复杂项目的数据共享问题,主要包括state,actions,
mutations,getters和modules 5个要素,主要流程:组件通过dispatch到 actions,actions是异步
操作,再actions中通过commit到mutations,mutations再通过逻辑操作改变state,从而同步到组件,
更新其数据状态
使用vuex时,新建index.js文件
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//modules模块化使用
import user from './modules/user.js'
export default new Vuex.Store({
state:{
//全局共享属性,可以在任何组件中使用
flag:'123',
number:1
},
getters:{
//计算属性,针对state值进行二次计算
changeFlag( state ){
return state.flag + 'x'
}
},
mutations:{
//存放同步方法的
add( state ){
state.number += 2;
}
},
actions:{
//存放异步方法,并且可以提交mutations
addNumber({commit,state}){
state.number += 4;
}
},
modules:{
//把vuex再次进行模块之间的划分
user
},
})
//父组件
<div>
<chidl />
//父组件使用全局共享属性flag
{{this.$store.state.flag}}
</div>
//子组件
<div>
子组件
//子组件使用全局共享属性flag
</div>
//vuex使用state值有两种形式
//区别:使用this.$store.state可以直接修改全局属性值,辅助函数无法修改
1、this.$store.state.flag;
2、使用辅助函数
第一:在组件中引入
import { mapState } from 'vuex'
第二:注册函数
export default{
computed:{
...mapState(['flag'])
}
}
第三:页面直接使用
{{flag}}
//vuex使用getters值有两种形式
***注意:getters师不可以修改的
1、this.$store.getters.changeFlag
2、使用辅助函数
第一:在组件中引入
import { mapGetters } from 'vuex'
第二:注册函数
export default{
computed:{
...mapGetters (['changeFlag'])
}
}
第三:页面直接使用
{{changeFlag}}
//vuex使用modules两种形式
1、$store.state.user.token
2、使用辅助函数
import { mapState } from 'vuex'
export default{
computed(){
...mapState({
token : state => state.user.token
})
}
}
页面使用{{token}}
vuex的modules模块化应用示例
第一:新建user.js文件,内容如下
export default{
state:{
token:'sdfoisjdflskdflsdfskdf'
}
}
第二:在index.js中引入user.js文件,并且在modules中挂载user
第三:页面中直接使用 {{this.$store.state.user.token}}
//vuex使用mutations
******注意mutations没有返回值
第一:在mutations中定义方法
第二:在使用的页面引入辅助函数
import { mapMutations } from 'vuex'
export default{
computed(){
...mapMutations(['add'])
}
}
//调用add方法
<button @click="add">调用add方法</button>
//页面展示 {{$store.state.number}}
//vuex中actions使用
******注意actions没有返回值
第一:在actions中定义addNumber方法
第二:页面引入辅助函数
import { mapActions } from 'vuex'
export default{
computed(){
...mapActions (['addNumber'])
}
}
//调用addNumber方法
<button @click="addNumber">调用addNumber方法</button>
//页面展示 {{$store.state.number}}
//vuex的区别
相同点
1、mutations和actions都是存放全局方法的,方法return的值拿不到
异同点
1、mutations是同步的,actions是异步的操作
2、mutations是来修改state的值得,actions是来提交mutations的
孙子辈
爷爷辈传递参数给孙子辈,两种方式:一级一级传递或者依赖注入provide/inject
//一级一级传递
...参考父传子形式
//依赖注入provide/inject
//缺点:是孙子辈无法确定页面的值来自那个父组件
//优点:不用一级一级去传递
export:{
provid(){//与生命周期函数同级
return{
val : '爷爷辈数据'
}
}
}
//孙子辈注入,页面可直接使用{{val}}
export:{
inject:['val']
}
//孙子辈使用爷爷辈数据
this.$parent.$parent.data;