vue组件间通讯(传递参数)

目录

1.vue组件间的通讯

1.1 父子组件

1.2 消息总线

1.3 vuex 进行通讯

2. vuex使用

2.1 简介

2.2 安装

2.3 创建store模块

2.4 创建vuex的store实例并注册上面引入的各大模块

2.5 在main.js中导入vuex

3. 将折叠和展开效果使用vuex实现

3.1 在state.js中声明全局参数

3.2 设置全局参数

3.3 Main.vue组件

3.3.1 直接通过state获取状态值

3.3.2 getter方式获取store中的值

3.4 LeftAside.vue组件

4. 异步处理

4.1 异步修改参数

5. 异步调用后台方法

5.1 准备后台方法

5.2 配置api/actions.js

5.3 store/actions.js

5.4 Home.vue

6. Vuex的常用辅助函数

7. vuex的模块化

8. vuex状态持久化


1.vue组件间的通讯

1.1 父子组件

  • 父组件-->子组件,通过子组件的自定义属性:props

  • 子组件-->父组件,通过自定义事件:this.$emit('事件名',参数1,参数2,...);

    参考

    (2条消息) 基础语法2 - vue路由介绍_嘴强程序员的博客-CSDN博客

    vue组件间通讯(传递参数)_第1张图片

1.2 消息总线

1.我们在项目中的 mian.js 的vue上的原型对象上放入消息总线

//js中每一个对象都有一个prototype属性,js中对象的prototype
//属性的解释是:每一个构造函数都有一个属性叫原型,这个原型的作用:为特定类声明通用属性
Vue.prototype.$Bus =new Vue();

2.实例 我们将需要保存的数据绑定到总线上 定义一个触发事件

应为$Bus保存在Vue的原型prototype上 所有this只要时Vue实例我们

就能获取到$Bus对象

//获取消息总线 ,并在总线上触发事件
this.$Bus.$emit("assideStateChange",this.opened);

3.然后我们区别的组件中定义 周期函数 mounted 加载完成后定义监听函数

如果别的界面也需要此数据再定义一个监听即可

或 复制即可 只要注意监听assideStateChange名

//通过消息总线
//生命周期钩子函数
   mounted() {
   //监听函数
     this.$Bus.$on("assideStateChange", (opened) => {
       // alert(opened)
       
       //下方可以 删除
       if (opened) {
         this.asideClass = "main-aside";
      } else {
         this.asideClass = "main-aside-collapsed";
       }
       
       
       
     });
  },

1.3 vuex 进行通讯

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。可以想象为一个“前端数据库”(数据仓库), 让其在各个页面上实现数据的共享包括状态,并且可操作。

Vuex分成五个部分: 1.State:单一状态树 2.Getters:状态获取 3.Mutations:触发同步事件 4.Actions:提交mutation,可以包含异步操作 5.Module:将vuex进行分模块

2. vuex使用

2.1 简介

Vuex是专门为vue应用程序开发的状态管理模式,将组件的共享状态抽取出来,以一个全局单例模式进行管理,组件树构成一个巨大的视图,不管组件在树的何种位置,任何组件都能获取到状态和触发行为。可以将其想象为一个“前端数据库”(数据仓库),让其在各个页面上实现数据的共享包括状态,并且可操作。(核心就是 解决组件间的通讯问题)

Vuex分成五个部分: 1.State:单一状态树 2.Getters:状态获取 3.Mutations:触发同步事件 4.Actions:提交mutation,可以包含异步操作 5.Module:将vuex进行分模块

2.2 安装

进入项目目录:

npm install vuex -S

直接安装可能遇到版本冲突 可能需要自定义版本号

vue组件间通讯(传递参数)_第2张图片

npm install [email protected] -S

2.3 创建store模块

创建store目录及需要的文件:

vue组件间通讯(传递参数)_第3张图片

2.4 创建vuex的store实例并注册上面引入的各大模块

vue组件间通讯(传递参数)_第4张图片

//导入vue模块
import Vue from 'vue'
​
//导入vuex模块,如果不知道名字可在package.json中查看
import Vuex from 'vuex'
​
//在vue中作用vuex
Vue.use(Vuex)
​
//导入相关模块
import state from '@/store/state'
import actions from '@/store/actions'
import getters from '@/store/getters'
import mutations from '@/store/mutations'
​
//创建store实例,并注册模块
//注意与导入的名字相同。
const store = new Vuex.Store({
  state,
  actions,
  getters,
  mutations
})
​
//最后导出模块
export default store

勘误: new Vuex({}),修改为 new Vuex.Store({})

2.5 在main.js中导入vuex

main.js是vue应用程序的入口,在这个文件中导入vuex组件。

vue组件间通讯(传递参数)_第5张图片

通过在根实例中注册store选项,该store实例会注入到根组件下的所有子组件中,且子组件可以通过this.$store访问到。

3. 将折叠和展开效果使用vuex实现

前端代码折叠

(2条消息) mockjs模拟数据 - 首页导航-左侧菜单-绑定菜单-显示数据分页crud_嘴强程序员的博客-CSDN博客

vue组件间通讯(传递参数)_第6张图片

或者下载前端源码

文件 (lanzoul.com)

源代码 使用了 jwt令牌 在http中把 jwt过滤器注释掉即可 测试 请求 与响应

vue组件间通讯(传递参数)_第7张图片

3.1 在state.js中声明全局参数

创建的store文件架中 state.js的作用可以看作是存放全局参数的容器,组件可以通过state.js获取全局参数。

*//存放全局参数的容器,组件可以通过state.js获取全局参数*
const state = {  
LeftAsideState: 'open'
} 
export default state

3.2 设置全局参数

当在TopNav.vue中点击展开或折叠时,需要将当前的状态设置到全局参数中,以便于其他组件可以获取到状态。 mutations:相当于setter方法,处理数据的唯一途径,state的改变或赋值只能在这里。

1) mutations.js 文件 存放设置方法

//Mutation 必须是同步函数。原因:异步方法,我们不知道什么时候状态会发生改变,所以也就无法追踪了
//如果我们需要异步操作,Mutations就不能满足我们需求了,这时候我们就需要Actions了
const mutations = {
​
  //state,即state.js中定义的state,借此可以访问state中定义的全局变量
  //payload: 载荷,保存传递参数的容器
  setLeftAsideState: (state, payload) => {
    //通过载荷为全局参数赋值,相当于setter
    state.LeftAsideState = payload.LeftAsideState;
  }
​
}
​
export default mutations

2)如何调用mutations.js中定义的setLeftAsideState为全局参数赋值? 见一下示例: 当点击TopNav.vue组件中的折叠或展开按键时,需要将当前的状态设置到全局参数中,以便于其他组件可以获取到状态。 TopNav.vue

   
 //转换折叠图标的状态
      doToggle: function() {
        //如果原来为打开状态则点击后转换为折叠
        //如果原来为折叠状态则点击后转换为打开
        this.opened = !this.opened;
​
        //通过自定义事件将状态值传递个父组件,及Main.vue
        //相应的Main.vue组件中需要设置‘left-open-collapsed’
        //使用vuex方式后,将原来的实现方式注释
        //this.$emit("left-open-collapsed",this.opened);
​
        /*
         * 通过vuex进行组件间的通讯,当点击折叠或展开时设置全局参数,以便于
         * 其他组件获取状态。
         *
         *  第一种提交方式:
         * this.$store.commit(type, payload);
         * 参数type: 与mutations.js定义的方法名一致
         * 参数payload:载荷,是个json对象,其中的参数与state.js中定义的全局参数名一致
         * 该方法的作用是为全局参数LeftAsideState赋值。
         * 
         * 第二种提交方式:
         * this.$store.commit({type: 'setLeftAsideState', LeftAsideState: 'open'});
         * 即:将type参数与要设置的全局参数放在一个json对象中。
         */
        this.$store.commit("setLeftAsideState", {
          LeftAsideState : this.opened ? 'open' : 'collapsed'
        });
        
      }

3.3 Main.vue组件

Main.vue组件获取设置的全局变量(LeftAsideState)的值,并需要根据变量的值来改变自身的状态。 state中存放的状态值是响应式的,从store实例中读取状态最简单的方式是在计算属性中返回某个状态。

3.3.1 直接通过state获取状态值

Main.vue 注意使用计算属性 就不能在data中定义此属性 否则会属性已定义报错

/*
 * 通过计算属性读取store中的值,并根据获取到的值返回展开或折叠样式。
 * 定义好计算属性后,通过绑定的方式使用
 * 
 */
computed: {
  leftAsideClass: function() {
    //可以通过以下的方式进行获取,但是不推荐。
    let tmp = this.$store.state.LeftAsideState;
    return tmp == 'open' ? "main-aside" : "main-aside-collapsed";
  }
}

不推荐使用this.$store.state.LeftAsideState;获取状态值,后续使用getter方式获取。

template部分 使用计算属性设置el-aside的class属性

启动服务,查看运行效果。

vue组件间通讯(传递参数)_第8张图片

3.3.2 getter方式获取store中的值

编辑/store/getters.js 存放 get方法

//getters将state中定义的值暴露在this.$store.getters对象中
//可以通过如下代码访问:this.$store.getters.getLeftAsideState
const getters = {
​
  //参数state即为stroe中存放的state,在state.js定义
  getLeftAsideState: function(state) {
    return state.LeftAsideState;
  }
​
}
​
export default getters

将Main.vue组件中访问store中数据的方式修改为getters方式。

/*
 * 通过计算属性读取store中的值,并根据获取到的值返回展开或折叠样式。
 */
computed: {
  leftAsideClass: function() {
    //可以通过以下的方式进行获取,但是不推荐。
    //let tmp = this.$store.state.LeftAsideState;
​
    //getters方式获取状态值
    let tmp = this.$store.getters.getLeftAsideState;
    return tmp == 'open' ? "main-aside" : "main-aside-collapsed";
  }
}

3.4 LeftAside.vue组件

    computed: {
      //通过计算属性获取定义在store中的状态值,并根据状态值来设定返回值,用于标记左侧栏展开或折叠的状态
      //因为命名冲突,可将上面再data中定义的同名属性删除.
      isCollapse: function() {
        return this.$store.getters.getLeftAsideState == 'open' ? false : true;
      }
    }

至此,展开或折叠效果使用vuex方式修改完毕。运行项目查看运行效果。

4. 异步处理

同步 同步模式,即上述所说的单线程模式,一次只能执行一个任务,函数调用后需等到函数执行结束, 返回执行的结果,才能进行下一个任务。如果这个任务执行的时间较长,就会导致「线程阻塞」

var x = true; while(x); console.log("don't carry out"); //不会执行

异步 异步模式,即与同步模式相反,可以一起执行多个任务,函数调用后不会立即返回执行的结果, 如果任务A需要等待,可先执行任务B,等到任务A结果返回后再继续回调。 异步常见的使用场景是后台耗时的任务。

js中最常见的异步是定时器

setTimeout(function(){
    console.log("async task .... ");
}, 3000);

4.1 异步修改参数

现做一个异步修改参数值的简单示例:

1) 在store中声明一个参数

//存放全局参数的容器,组件可以通过state.js获取全局参数
const state = {
  LeftAsideState: 'open',
  
  //声明一个存放人员名称的参数,设置默认值,用于演示异步修改参数
  PersonName:'张飞'
}
​
export default state

2) 在mutations.js中定义修改参数的方法:

//Mutation 必须是同步函数。为什么呢?异步方法,我们不知道什么时候状态会发生改变,所以也就无法追踪了
//如果我们需要异步操作,Mutations就不能满足我们需求了,这时候我们就需要Actions了
const mutations = {
​
  //state,即state.js中定义的state,借此可以访问state中定义的全局变量
  //payload: 载荷,保存传递参数的容器
  setLeftAsideState: (state, payload) => {
    //通过载荷为全局参数赋值,相当于setter
    state.LeftAsideState = payload.LeftAsideState;
  },
​
  //设置人员名称,用于演示异步
  setPersonName: (state, payload) => {
    state.PersonName = payload.PersonName;
  }
​
}
​
export default mutations

3)在getters.js中定义获取参数的方法

//getters将state中定义的值暴露在this.$store.getters对象中
//可以通过如下代码访问:this.$store.getters.getLeftAsideState
const getters = {
​
  //参数state即为stroe中存放的state,在state.js定义
  getLeftAsideState: function(state) {
    return state.LeftAsideState;
  },
​
  //定义获取人员名称的方法
  getPersonName: function(state) {
    return state.PersonName;
  }
​
}
​
export default getters

4) 编辑actions.js添加异步设置参数功能

/*
 * Action与mutation定义语法类型,不同点:
 * 1) Action提交的是mutation,而不是直接变更状态,mutation直接变更状态
 * 2) Action可以包含任意异步操作
 * 3) Action的回调函数接收一个 context 上下文参数
 * 详见方法内的注释
 */
const actions = {
​
  /*
   * context为上下文参数,与 store 实例有着相同的方法和属性
   * context参数包含:state、rootState、getters、mutations、actions 五个属性
   * payload为负载,是一个存放需要传递的参数的容器,和mutations的含义一致
   */
  setPersonNameAsyn: function(context, payload) {
    
    //异步操作,第一个参数为一个匿名函数,第二参数为延迟的时间,单位为毫秒。
    //作用:在3秒或调用第一个参数定义的匿名函数。
    setTimeout(function() {
      
      //action提交的是mutation,而不能直接变更状态
      //第一个参数setPersonName即为mutation中定义的方法名
      //payload即为参数容器。
      //通过context的commit方法提交一个mutation,由mutation负责
      //修改参数,action负责提供异步功能,(mutation必须是同步的)
      context.commit('setPersonName', payload);
    }, 3000);
  }
​
}
​
export default actions

5) 编辑Home.vue用于演示异步设置操作

现在可以运行程序,体验异步操作。

5. 异步调用后台方法

5.1 准备后台方法

准备一个后台接口,可以让其睡眠几秒钟再返回数据,以模拟耗时的后台处理过程。

5.2 配置api/actions.js

配置api/action.js,加入准备好的后台接口。

//VUEX 异步请求后台数据
'VUE_ASYN_REQ':'/userTest',

5.3 store/actions.js

在store/actions.js中增加发送ajax请求的方法。

const actions = {
  
  ......
  
  /*
   * 在actions.js中无法直接获取vue实例的this对象,但需要该对象来获取axios
   * 对象,以便于发送ajax请求,可以通过payload参数由调用者传入vue实例的this
   * 对象。
   */
  getDataFromApiAsyn: function(context, payload) {
   //主页转过来的vue实体对象
   let _this = payload._this;
    let url = _this.axios.urls.VUE_ASYN_REQ;
​
    _this.axios.post(url, {
    //传递参数到后台
      param: payload.PersonName
    }).then(resp => {
​
      //通过resp响应对象获取返回的数据,并赋予payload
      payload.PersonName = resp.data.data;
​
      //提交一个mutation,用于设置state中的参数。
      context.commit('setPersonName', payload);
    }).catch(error => {
​
    })
  }
  
  ......
  
 }

后台获取发动参数

  @RequestMapping("userTest")
   @ResponseBody
    public String userTest(HttpServletRequest request){
        String param = request.getParameter("param");
​
        return param;
​
    }

5.4 Home.vue

在Home.vue组件中,加入异步获取后台数据的方法。

6. Vuex的常用辅助函数

mapState/mapGetters/mapMutations/mapActions

以mapGetters为例: vue组件间通讯(传递参数)_第9张图片

其他函数的使用方式

import { mapState, mapGetters, mapActions, mapMutations } from "vuex";
export default {
  computed: {
    ...mapGetters({
      "": "vuex仓库定义的方法",
    }),
    ...mapState({}),
  },
  methods: {
    ...mapMutations({}),
    ...mapActions({}),
  },
};

有两个是写computed里面------1.mapGetters 2.mapState 还有两个是写methods里面的----1.mapActions 2.mapMutations

vuex的四个辅助函数 mapState,mapActions,mapMutations,mapGetters

1.首先来说使用的步骤以mapState为例: 这步骤其实都类似 1.1要使用es6的写法按需引入import { mapState } from 'vuex'

1.2然后在computed里面写 使用展开运算符,mapState 它是一个函数 使用的方法是 1.3 ...mapState(['xxx']),-----这个xxx里面写的是你要用的数据---数组包着 1.4 ...mapState({'新名字': 'xxx'}) -----这里面的新名字是你要重新定义名字---对象包着

1.5在js里面写的话是this.xxx -----这里面的xxx也就是你拿的值 在组件里面写的话直接{{xxx}}----插值表达式一样,组件里面不加this

2.还有就是在module里面使用辅助函数如下 2.1在computed里面写 ...mapState('模块名', ['xxx']), ..mapState('模块名', {'新名字': 'xxx'})

  1. 在全局使用mapGetters computed: { ...mapGetters(['xxx']), ...mapGetters({'新名字': 'xxx'}) }

在modules中使用getters

computed: { ...mapGetters('模块名', ['xxx']), ...mapGetters('模块名',{'新名字': 'xxx'}) }

3.在全局使用mapMutations

methods: { ...mapMutations(['mutation名']), ...mapMutations({'新名字': 'mutation名'}) }

在modules中使用mapMutations methods: { ...mapMutations('模块名', ['xxx']), ...mapMutations('模块名',{'新名字': 'xxx'}) }

4.在全局使用mapActions

methods: { ...mapActions(['actions名']), ...mapActions({'新名字': 'actions名'}) }

在modules中使用mapActions

methods: { ...mapActions('模块名', ['xxx']), ...mapActions('模块名',{'新名字': 'xxx'}) }


有两个是写computed里面------1.mapGetters 2.mapState 还有两个是写methods里面的----1.mapActions 2.mapMutations,

7. vuex的模块化

vuex的模块化是为了在大型项目中,更好的管理store中的数据。在大型项目中store中的数据会非常多,直接放在store中容器引发混乱,这时候就需要模块化的管理。

示例: 在store目录中创建一个usermsg目录,在其中创建一个user-msg.js,如下图所示: vue组件间通讯(传递参数)_第10张图片

const userMsg = {
​
  state: {
    userName: '模块名称'
  },
​
  getters: {
    getUserName: function(state) {
      return state.userName
    }
  },
​
  mutations: {
    setUserName: function(state, payload) {
      state.userName = payload.userName;
    }
  }
​
}
​
export default userMsg

修改store/index.js文件: vue组件间通讯(传递参数)_第11张图片

在Home.vue组件上测试: 图一: vue组件间通讯(传递参数)_第12张图片

图二: vue组件间通讯(传递参数)_第13张图片

还可以使用如下方式获取模块中的值:this.$store.state.userMsg.userName; 但不建议使用。

8. vuex状态持久化

Vuex 解决了多视图之间的数据共享问题。但是运用过程中又带来了一个新的问题是,Vuex 的状态存储并不能持久化。也就是说当你存储在 Vuex 中的 store 里的数据,只要一刷新页面,数据就丢失了。

引入vuex-persist 插件,它就是为 Vuex 持久化存储而生的一个插件。不需要你手动存取 storage ,而是直接将状态保存至 cookie 或者 localStorage 中。

1) 安装

npm install vuex-persist -S

2)导入及配置: vue组件间通讯(传递参数)_第14张图片

可以将项目运行起来看效果

你可能感兴趣的:(javascript,开发语言,ecmascript)