全局事件总线(vuex)

384 阅读2分钟

组件与数据通信

组件关系数据通信
父子关系子传父:props;父传子:$emit
非父子关系eventBus:on+on+emit
非父子关系vuex

$bus

  • 对$bus的要求: 所有的组件可以关联(就是看得见,看不见怎么关联)

要能够调用$on,$off,$emit(不能绑定关系怎么控制组件)

分析:能让所有的组件关联,必须是全局的(vm,vc,window),当然window就大材小用了,那选vm还是vc呢?

关于vc(vueComponent):

        1.App组件是本质是一个名为*vueComponent*的构造函数,且不是程序员定义的
            是*vue.extend*生成的
        2.我们只需要写<App/>,vue解析时会帮我们创建App组件的实例对象,
           即vue会帮我们执行:new VueComponent(options)
        3.特别注意:每次调用Vue.extend.*返回的都是一个全新的VueComponent*
        4.this指向:
           (1)组件配置中:
                data函数,methods中的函数,watch中的函数,computed中的函数
                它们的this均是*VueComponent实例对象*
           (2)new  vue(options)配置中:
                data函数,methods中的函数,watch中的函数,computed中的函数
                它们的this均是*Vue实例对象*
        5.一个重要的内置关系:
           vueComponent.prototype.__proto__===Vue.prototype
           即:组件实例对象可以访问vue原型上的属性,方法

标准写法

            注册:
            beforeCreate(){
              vue.prototype.$bus=this
            }
            使用:
            mounted(){
              this.$bus.$on('xxx',(data)=>{})
            }
            销毁:
            beforeDestroy(){
              this.$bus.$off('xxx')
            }

vuex

  • 定义:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式, 采用集中式存储管理应用的所有组件的状态,解决多组件数据通信。
  • 要点:
  1. vue官方搭配,专属使用 (类似于:vue-router),有专门的调试工具
  2. 集中式管理数据状态方案 (操作更简洁)data() { return { 数据, 状态 }}
  3. 数据变化是可预测的 (响应式)

属性:

state:保存公共数据

        定义:
        state(){
        return {
        数据1:值1
        }
        }

使用:this.$store.state.数据1

mutations:修改数据

        定义:
        mutation:{
        m名字(state,参数){}
        }

使用:this.$store.commit(m名字,实参)

getters:计算属性

定义:
getters:{
g名字(state){
return 计算结果
}
}

使用:this.$store.getters.g名字

actions : 异步请求

定义:
            actions:{
            a名字(context,参数){
            axios...
            context.commit('m名字')
            }
            }

使用:this.$store.dispatch('a名字',实参)

modules:拆分模块

定义:
        store
          -index.js//引入模块1.js
          -modules
             -模块1.js
        使用:
        import 模块1  from  './modules/模块1.js'
        modules:{
          模块1
        }
        模块1:
        export default{
          namespaced.true,
          state,
          mutations,
          getters,
          actions
        }
        调用:
        getters:    this.$store.getters['模块1/g名字']
        state:      this.$store.state.模块1/数据名字
        mutations:  this.$store.commit{'模块1/g名字',参数}
        actions:    this.$store.dispatch{'模块1/g名字',参数}

辅助函数(map)

        定义    import  {mapState}  from  'vuex'
        模块    computed:{...mapState('模块名',['xxx'])}
        全局    computed:{...mapState(['xxx'])}
        重命名  computed:{...mapState('新名字',['xxx'])}

路由守卫(前置)

  • 定义:路由跳转之前, 会触发一个函数(做一个拦截校验)
  • 语法:router.beforeEach((to, from, next) => {}) 代码实例
        在router/index.js 路由对象上使用固定方法beforeEach

        // 路由守卫
        // 每次页面跳转,都会执行这个回调
        router.beforeEach((to, from, next) => {
          console.log(to, from)
          // to代表要跳转到哪个路径去, to的值是个对象可以打印看到
          // from代表从哪个路径跳过去
          // next是一个函数。 
          //   next()             放行;
          //   next('路由地址')    跳到指定的位置


          // 判断,是否有权限去访问页面,如果没有权限,跳转到登录页
          const token = localStorage.getItem('token') // 假设token

          // 访问login不要token,其他都要
          if(to.path === '/login'){
            next()
          } else {
            // 不去login,就要检查一下证件
            if(token){
              next() // 有token就正常访问
            } else {
              next('/login')
            }
          }
        })

路由守卫(后置)

  • 定义:路由跳转后, 触发的函数
  • 语法:router.afterEach((to, from) => {}) 代码实例
            
            router.afterEach((to, form) => {
                console.log(to);
                console.log(form);
                console.log("路由发生了跳转");
            })

路由模式设置

  • 作用: 修改路由在地址栏的模式 代码实例
        const router = new VueRouter({
          routes,
          mode: "history" // 打包上线后需要后台支持
        })

history和hash模式对比

  1. 功能一样(跳转页面)
  2. history模式的path路径不带#号,hash有#号
  3. hash模式兼容性好 示例:
            hash路由例如:   <http://localhost:8081/#/home>
            history路由例如: <http://localhost:8081/home>