• vue中组件间的通信


    方式一:
    props:父组件可以通过该方式将数据传递给子组件
    示例:
    1. //父组件
    2. <BlogPost :title="post.title" />
    3. //子组件
    4. export default
    5.     ...
    6.     props: { 
    7.        title: String,
    8.        defalut: ''
    9.     }
    10.     ... 
    11. }
    12. //子组件使用
    13. {{ title }}

    方式二:
    父组件首先给子组件传递一个函数类型的props,然后子组件调用该函数给父组件传值。 方式只适用于父子组件中
    父组件中:
    1. <School :getSchoolName="getSchoolName"/>
    2. methods: {
    3.     getSchoolName(name){
    4.         console.log('App收到了学校名:',name)
    5.     }
    6. }
    子组件中:
    1. props:['getSchoolName'],
    2. data() {
    3.     return {
    4.         name:'学校名称'
    5.     }
    6. },
    7. methods: {
    8.     sendSchoolName(){
    9. //通过props中的函数将学校名传给App父组件。
    10. //这得需要父组件先给子组件一个函数类型的props,子组件调用这个函数,将数据传递出去
    11.         this.getSchoolName(this.name)
    12.     }
    13. }
    方式三:
    通过自定义事件实现组件间通信, 该方式适用于父子组件间
    父子组件之间的访问方式:
    1、父组件访问子组件:$refs:开发中常用
    ref:用来给元素或者子组件注册引用信息
    2、子组件访问父组件:$parent ,在开发中尽量少用,组件复用性很高!从这个父组件中拿到的属性,在其他父组件中可能没有这个属性
    3、子组件访问根组件:$root
    父组件中:
    写法1:
    1. <Student @getStudentName="getStudentName"/>
    2. methods: {
    3.     getStudentName(name, ...params){
    4.         console.log('App收到了学生名:',name,params)
    5.     }
    6. }
    写法2:
    1. <Student ref="student" />
    2. methods: {
    3.     getStudentName(name,...params){
    4.         console.log('App收到了学生名:',name,params)
    5.     }
    6. },
    7. mounted() {
    8.     this.$refs.student.$on('getStudentName',this.getStudentName) //绑定自定义事件
    9. }
    子组件中:
    1. data() {
    2.     return {
    3.         name:'张三'
    4.     }
    5. },
    6. methods: {
    7.     sendStudentName(){
    8.         //触发Student组件实例身上的getStudentName事件
    9.         this.$emit('getStudentName',this.name,666,888,900)
    10.     }
    11. }
    方式四:
    通过全局事件总线实现组件间通信, 该方式适用于任何组件间
    main.js中安装全局事件总线:
    1. //引入Vue
    2. import Vue from 'vue'
    3. //引入App
    4. import App from './App.vue'
    5. //创建vm
    6. new Vue({
    7.     el:'#app',
    8.     render: h => h(App),
    9.     beforeCreate() {
    10.         Vue.prototype.$bus = this //安装全局事件总线
    11.     },
    12. })
    消息接收者:
    1. mounted() {
    2.     this.$bus.$on('hello',(data)=>{
    3.         console.log('我是School组件,收到了数据',data)
    4.     })
    5. },
    6. beforeDestroy() {
    7.     this.$bus.$off('hello')
    8. }
    消息发送者:
    1. data() {
    2.     return {
    3.         name:'张三'
    4.     }
    5. },
    6. methods: {
    7.     sendStudentName(){
    8.         this.$bus.$emit('hello',this.name)
    9.     }
    10. }
    方式五:
    消息的发布于订阅, 该方式适用于任何组件间。这里使用pubsub实现消息的订阅与发布
    先安装pubsub-js:npm i pubsub-js
    消息订阅者school.vue:
    消息发布者student.vue:
    1. <script>
    2.     import pubsub from 'pubsub-js'
    3.     export default {
    4.         name:'Student',
    5.         data() {
    6.             return {
    7.                 name:'张三',
    8.                 sex:'男',
    9.             }
    10.         },
    11.         methods: {
    12.             sendStudentName(){//发布消息
    13.                 pubsub.publish('hello',666)
    14.             }
    15.         },
    16.     }
    17. script>
    方式六
    通过Vuex实现组件间的通信, 该方式适用于任何组件间
    安装Vuex:
    1. npm install vuex --save             //默认安装Vuex4
    2. //npm install vuex@3 --save           //安装Vuex3
    3. //tips:默认安装的时Vuex4,但是Vue2只能使用Vuex3;Vue3使用Vuex4
    使用:
    main.js:
    1. //引入Vue
    2. import Vue from 'vue'
    3. //引入App
    4. import App from './App.vue'
    5. //引入store
    6. import store from './store'
    7. //关闭Vue的生产提示
    8. Vue.config.productionTip = false
    9. //创建vm
    10. new Vue({
    11.     el:'#app',
    12.     render: h => h(App),
    13.     store
    14. })
    src/store/count.js:
    1. //求和相关的配置
    2. export default {
    3.     namespaced:true,
    4.     actions:{
    5.         jiaOdd(context,value){
    6.             console.log('actions中的jiaOdd被调用了')
    7.             if(context.state.sum % 2){
    8.                 context.commit('JIA',value)
    9.             }
    10.         },
    11.         jiaWait(context,value){
    12.             console.log('actions中的jiaWait被调用了')
    13.             setTimeout(()=>{
    14.                 context.commit('JIA',value)
    15.             },500)
    16.         }
    17.     },
    18.     mutations:{
    19.         JIA(state,value){
    20.             console.log('mutations中的JIA被调用了')
    21.             state.sum += value
    22.         },
    23.         JIAN(state,value){
    24.             console.log('mutations中的JIAN被调用了')
    25.             state.sum -= value
    26.         },
    27.     },
    28.     state:{
    29.         sum:0, //当前的和
    30.         school:'学校',
    31.         subject:'学科',
    32.     },
    33.     getters:{
    34.         bigSum(state){
    35.             return state.sum*10
    36.         }
    37.     },
    38. }
    src/store/person.js:
    1. //人员管理相关的配置
    2. import axios from 'axios'
    3. import { nanoid } from 'nanoid'
    4. export default {
    5.     namespaced:true,
    6.     actions:{
    7.         addPersonWang(context,value){
    8.             if(value.name.indexOf('王') === 0){
    9.                 context.commit('ADD_PERSON',value)
    10.             }else{
    11.                 alert('添加的人必须姓王!')
    12.             }
    13.         },
    14.         addPersonServer(context){
    15.             axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(
    16.                 response => {
    17.                     context.commit('ADD_PERSON',{id:nanoid(),name:response.data})
    18.                 },
    19.                 error => {
    20.                     alert(error.message)
    21.                 }
    22.             )
    23.         }
    24.     },
    25.     mutations:{
    26.         ADD_PERSON(state,value){
    27.             console.log('mutations中的ADD_PERSON被调用了')
    28.             state.personList.unshift(value)
    29.         }
    30.     },
    31.     state:{
    32.         personList:[
    33.             {id:'001',name:'张三'}
    34.         ]
    35.     },
    36.     getters:{
    37.         firstPersonName(state){
    38.             return state.personList[0].name
    39.         }
    40.     },
    41. }

    src/store/index.js:
    1. //该文件用于创建Vuex中最为核心的store
    2. import Vue from 'vue'
    3. //引入Vuex
    4. import Vuex from 'vuex'
    5. import countOptions from './count'
    6. import personOptions from './person'
    7. //应用Vuex插件
    8. Vue.use(Vuex)
    9. //创建并暴露store
    10. export default new Vuex.Store({
    11.     modules:{
    12.         countAbout:countOptions,
    13.         personAbout:personOptions
    14.     }
    15. })
    count.vue: 
    模块化+命名空间-->借助四个map辅助函数
    1. <script>
    2.     import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
    3.     export default {
    4.         name:'Count',
    5.         data() {
    6.             return {
    7.                 n:1, //用户选择的数字
    8.             }
    9.         },
    10.         computed:{
    11.             //借助mapState生成计算属性,从state中读取数据。(数组写法)
    12.             ...mapState('countAbout',['sum','school','subject']),
    13.             ...mapState('personAbout',['personList']),
    14.             //借助mapGetters生成计算属性,从getters中读取数据。(数组写法)
    15.             ...mapGetters('countAbout',['bigSum'])
    16.         },
    17.         methods: {
    18.             //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
    19.             ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
    20.             //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
    21.             ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    22.         },
    23.         mounted() {
    24.             console.log(this.$store)
    25.         },
    26.     }
    27. script>
    28. <style lang="css">
    29.     button{
    30.         margin-left: 5px;
    31.     }
    32. style>
    person.vue: 
    模块化+命名空间-->原生写法