VUE进阶篇Part11(vue-route和vuex前端状态管理)---下

此章节涉及到的内容:

1、vuex的store用法
2、vuex的相关操作和核心用法

什么是 vuex?

vuex 是一个状态管理模式,可以用来共享数据。

以淘宝为例,如果在首页登录了自己的账户,当点击首页的链接跳转到其他页面时,仍然会是登录状态。

这就是vuex,而实现这些的是因为用到了vuex中的store(仓库),这个 store 会让各个组件获取到你当前的状态,根据状态去判断渲染出什么。

store 基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。

什么情况下要用 vuex?

判断方式很简单,当你不需要用到 vuex 就把项目的所有功能全部都实现了的时候,就不需要用了。

反之就需要用 vuex !

先回顾一下之前父子组件之间的数据传递

直接看例子,都是在src/components文件夹下

parent.vue 父组件
<template>
  <div>
    <span>这里都是父组件</span><br><br>
    {{fromSon}}
    <hr>
    <!-- 自定义一个handle事件来接受子组件的数据 -->
    <son v-bind:msg="toSonMsg" v-on:handle="getMsgFromSon"></son>
  </div>
</template>

<script>
//父组件传递数据到子组件,需要先引入子组件
import son from "./son";

export default {
  name: "parent",
  data: function() {
    return {
      toSonMsg: "我是父组件传递过来的内容",
      fromSon: ""
    };
  },
  components: {
    son
  },
  methods: {
    getMsgFromSon: function(value) {
      this.fromSon = value;
    }
  }
};
</script>
son.vue 子组件
<template>
  <div>
    <span>这里都是子组件</span><br><br>
    {{msg}}
    <button v-on:click="toFaMsg">向父组件传递数据</button>
  </div>
</template>

<script>
export default {
  name: "son",
  data:function(){
      return {
          sonMsg:'我是子组件传递过来的内容'
      }
  },
  //子组件接收数据
  props: {
    msg: {
      type: String,
      default: ""
    }
  },
  //子组件向父组件传递数据
  methods:{
      toFaMsg:function(){
          //使用this,$emit()传递数据,第一个写事件名,第二个写要传递的参数
          this.$emit('handle',this.sonMsg)
      }
  }
};
</script>
HelloWorld.vue 显示页面内容的组件
<template>
  <div class="hello">
    <parent/>
  </div>
</template>

<script>
//将父组件引入就可以看到子组件
import parent from "./parent";

export default {
  name: "HelloWorld",
  data() {
    return {
      msg: "Welcome to Your Vue.js App"
    };
  },
  //记得在这里也要注入进去
  components: {
    parent
  }
};
</script>

使用npm run dev进入项目,地址栏输入localhost:8080,并且点击按钮可以看到显示的内容,就表示传递成功
在这里插入图片描述

1、vuex的基本用法

需求:outter.vue | parent.vue | son.vue 三个组件之间共享数据
1、安装vuex,进入到项目目录下

npm install vuex

2、引入vuex,在src下的main.js中引入,并且创建状态仓库

import Vue from 'vue'
import App from './App'
import router from './router'
//引入vuex
import Vuex from 'vuex'

Vue.config.productionTip = false

//并且调用它
Vue.use(Vuex)

//创建一个状态仓库 store,后面的 Vuex.Store 首字母一定要大写
var store = new Vuex.Store({
  //用state来记录状态,这个state不要乱改
  state:{
    num:88
  }
})

//创建好了store仓库之后,记得在这里引入一下
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

3、通过this.$sore.state.XXX直接拿到需要的数据

parent.vue中
<template>
  <div>
    <span>这里都是父组件</span><br><br>
    {{fromSon}}<br><br>
    这里是父组件通过store获取的数据num:{{getNum}}
    <hr>
    <!-- 自定义一个handle事件来接受子组件的数据 -->
    <son v-bind:msg="toSonMsg" v-on:handle="getMsgFromSon"></son>
  </div>
</template>

<script>
//父组件传递数据到子组件,需要先引入子组件
import son from "./son";

export default {
  name: "parent",
  data: function() {
    return {
      toSonMsg: "我是父组件传递过来的内容",
      fromSon: ""
    };
  },
  components: {
    son
  },
  methods: {
    getMsgFromSon: function(value) {
      this.fromSon = value;
    }
  },
//父组件中是用计算属性去拿到 store 仓库的数据
computed:{
    getNum:function(){
        return this.$store.state.num
    }
}
};
</script>
son.vue中
<template>
  <div>
    <span>这里都是子组件</span><br><br>
    {{msg}} <br><br>
    这里是子组件通过
    store获取的数据num:{{getNum}} <br><br>
    <button v-on:click="toFaMsg">向父组件传递数据</button>
  </div>
</template>

<script>
export default {
  name: "son",
  data:function(){
      return {
          sonMsg:'我是子组件传递过来的内容'
      }
  },
  //子组件接收数据
  props: {
    msg: {
      type: String,
      default: ""
    }
  },
  //子组件向父组件传递数据
  methods:{
      toFaMsg:function(){
          //使用this,$emit()传递数据,第一个写事件名,第二个写要传递的参数
          this.$emit('handle',this.sonMsg)
      }
  },
  //子组件中是用计算属性去拿到 store 仓库的数据
  computed:{
      getNum:function(){
          return this.$store.state.num
      }
  }
};
</script>
outter.vue中
<template>
  <div>
      <hr>
      这里是outter组件通过store获取的数据num:{{getNum}}
  </div>
</template>

<script>

export default {
  name: "parent",
  data: function() {
    return {
    };
  },
  //outter组件中是用计算属性去拿到 store 仓库的数据
  computed:{
      getNum:function(){
          return this.$store.state.num
      }
  }
};
</script>
HelloWorld.vue 中显示出来
<template>
  <div class="hello">
    <parent/>
    <outter/>
  </div>
</template>

<script>
//将父组件引入就可以看到字组件
import parent from "./parent";
import outter from "./outter"

export default {
  name: "HelloWorld",
  data() {
    return {
      msg: "Welcome to Your Vue.js App"
    };
  },
  //记得在这里也要注入进去
  components: {
    parent,
    outter
  }
};
</script>
结果,全部能够拿到store里面的num的数据:

在这里插入图片描述

2、vuex的相关操作和核心用法

在实际过程中不仅是需要获取,同时经常需要改变它的状态,比如淘宝购物车,把这个网页的宝贝添加进购物车,在那个网页的宝贝也添加进购物车,这是需要状态的改变的。

那么改变的时候实际上进行了那些操作呢?看下面

vuex状态的管理流程:

view → actions → mutations → state → view

除了能够获取状态如何改变状态呢?

需求:让parent组件,son组件,outter组件点击后分别可以改变state仓库的状态

第一种方法具体实现过程:

(下面的代码就是基于上面的整体代码实现的)

1、现在main.js中定义mutations事件,来改变store仓库的状态
//创建一个状态仓库 store,后面的 Vuex.Store 首字母一定要大写
var store = new Vuex.Store({
  //用state来记录状态,这个state不要乱改
  state:{
    num:88
  },
  //定义mutations事件,来改变state仓库的状态
  mutations:{
    //定义一个increase方法,点击按钮,每次让num + 1,传统写法
    increase:function(state){
      state.num++ 
    },
    //定义一个decrease方法,点击按钮,每次让num - 1,es6写法,":function"这个可以省略
    decrease(state){
      state.num--
    }
    //获取方法: this.$store.commit(xxx),这个xxx是mutations中定义的方法
  }
})
2、在parent | son | outter 组件中引入

parent.vue

<button v-on:click="pAdd">父组件---改变状态按钮</button>

<script>
methods:{
	//添加改变组件状态的方法,记住传递的一定是字符串,加''
    pAdd: function() {
      this.$store.commit('increase');
    }
}
</script>

son.vue

<button v-on:click="sAdd">子组件---改变状态按钮</button>

<script>
methods:{
	//添加改变组件状态的方法,记住传递的一定是字符串,加''
    sAdd: function() {
      this.$store.commit('increase');
    }
}
</script>

outter.vue

<button v-on:click="oAdd">outter组件---改变状态按钮</button>

<script>
methods:{
	//添加改变组件状态的方法,记住传递的一定是字符串,加''
    oAdd: function() {
      this.$store.commit('increase');
    }
}
</script>
3、结果:

只要点击这三个按钮,先出出来的数值就会加1,就代表改变状态成功了。
在这里插入图片描述

第二种方法具体实现过程
还有一种方法可以修改状态,使用 actions

注意:actions 提交的是 mutations ,而不是直接改变状态。

同时 actions 可以包含异步操作(setTimeout等),但是 mutations 只能包含同步操作。

1、main.js中加入actions

需要先定义好 mutations ,再去定义actions

//定义mutations事件,来改变state仓库的状态
mutations:{
  //定义一个increase方法,点击按钮,每次让num + 1,传统写法
  increase:function(state){
    state.num++ 
  },
  //定义一个decrease方法,点击按钮,每次让num - 1,es6写法,":function"这个可以省略
  decrease(state){
    state.num--
  }
  //获取方法: this.$store.commit(xxx),这个xxx是mutations中定义的方法
},


//定义actions来改变state仓库的状态,但是这里需要传一个参数 context(上下文对象)
actions:{
  //并且actions只能对mutations进行操作,不能直接操作state
  decreaseAction:function(context){
    //这里传入的必须是在上面mutations写好了的方法
    context.commit('decrease')
  }
  //获取方法:this.$store.dispatch(xxx),这个xxx是actions中定义的
}
2、在parent | son | outter 组件中引入

parent.vue

<button v-on:click="pReduce">父组件---改变状态按钮(actions)</button>

<script>
  methods: {
    //使用mutations改变组件状态的方法,记住传递的一定是字符串,加''
    pAdd: function() {
      this.$store.commit('increase');
    },
    //使用actions改变组件状态
    pReduce:function(){
      this.$store.dispatch('decreaseAction')
    }
  },
</script>

son.vue

<button v-on:click="sReduce">子组件---改变状态按钮(actions)</button>

<script>
  methods: {
    //使用mutations改变状态方法
    sAdd: function() {
      this.$store.commit('increase');
    },
    //使用actions改变组件状态
    sReduce:function(){
      this.$store.dispatch('decreaseAction')
    }
  },
</script>

outter.vue

<button v-on:click="oReduce">outter组件---改变状态按钮(actions)</button>

<script>
  methods: {
    //使用mutations改变状态方法
    oAdd:function(){
      this.$store.commit('increase')
    },
    //使用actions改变组件状态
    oReduce:function(){
      this.$store.dispatch('decreaseAction')
    }
</script>
3、结果

只要点击这个actions按钮,上面的数字就会减1,就代表使用actions修改成功了。
在这里插入图片描述

4、最后还有一个 getters

getters 可以对拿到的状态进行处理,比如去银行取钱,不会取到负数,最多取到余额0,这个余额0就需要在 getters 里面先处理好

与mutations,actions是同一级的

4.1 main.js中
//定义getters,这个getters可以对状态做处理,做限制
getters: {
  //这里传的参数也是 state ,并且在实际业务中是通过在getters里面定义的方法来拿到state的状态的
  getNum: function (state) {
    return state.num >= 0 ? state.num : 0
  }
  //获取方法:this.$store.getters.xxx ,这个xxx是在getters里面定义的方法
}
4.2 在parent | son | outter 组件中引入

因为这里用到getters的地方就是computed计算属性内

parent.vue

//父组件中是用计算属性去拿到 store 仓库的数据
computed: {
  getNum: function() {
    // return this.$store.state.num;

    //这里通过getters里面定义的拿
    return this.$store.getters.getNum
  }
}

son.vue

//子组件中是用计算属性去拿到 store 仓库的数据
computed: {
  getNum: function() {
    // return this.$store.state.num;

    //这里通过getters里面定义的拿
    return this.$store.getters.getNum
  }
}

outter.vue

//outter组件中是用计算属性去拿到 store 仓库的数据
computed: {
  getNum: function() {
    // return this.$store.state.num;

    //这里通过getters里面定义的拿
    return this.$store.getters.getNum
  }
},
4.3 结果

这里一直减的话,会减到0就减不下去了,这就代表 getters 设置状态成功!
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值