• vuex状态管理(二)超级详细使用教程(包含辅助函数map的使用),一看就会,一学就懂


    vuex状态管理(一)原理以及使用注意事项_无围之解的博客-CSDN博客

     

    原理上一篇文章已经写了

    1  本文默认首先项目已经安装了vuex,没有安装的参考官网安装一下

    2 先看看正常的结构

    1. import Vue from 'vue'
    2. import Vuex from 'vuex'
    3. Vue.use(Vuex)
    4. export default new Vuex.Store({
    5. //定义数据
    6. state: {
    7. },
    8. //同步操作
    9. mutations: {
    10. },
    11. //异步操作
    12. actions: {
    13. },
    14. modules: {}
    15. })

    3 这几个主要的名词解释  

    3.1 state中主要是定义公共使用的数据,对象或这单个字符串,数组等等。

    3.2 mutations 主要是数据的更改状态提交提交。只有这一种方式提交修改的数据才能追踪。

    当你修改数据时,就需要通过commit提交, mutations会记录它的修改动作,便于跟踪管理。

    3.3 actions主要时异步操作获取更改数据,但是也要最后通过dispatch就行数据提交,最终还是要通过mutations才能提交数据

    3.4 mapState, mapMutations, mapActions 这些辅助函数,写法简单,用起来方便

    3.5 页面获取数据 $store.state.obj1

    4 下面看实例

    4.1先在state中写2个数据

    1. state: {
    2. //直接使用
    3. obj1: {
    4. name: "张三儿1",
    5. id: "obj1"
    6. },
    7. //辅助函数
    8. obj2: {
    9. name: "张三儿2",
    10. id: "obj2"
    11. }
    12. },

    4.2然后mutations中写两个修改数据的方法

     state.obj1.name = name + state.obj1.name

    state.obj1.name就可以拿到state中的要操作的数据,同时可以传递一个参数name(或者多个参数)

    1. mutations: {
    2. //普通函数方法写
    3. setobjName(state, name) {
    4. state.obj1.name = name + state.obj1.name
    5. },
    6. },

    4.3 然后去页面修改 app.vue, test.vue, profile.vue页面 分别获取obj1.name,和obj2的属性id 看下图页面渲染效果

    1. <h2>
    2. <div>name:{{ $store.state.obj1.name }}</div>
    3. <div>id:{{ $store.state.obj2.id }}</div>
    4. </h2>

    我们看test.vue页面

     

    4.4此时 我们在test.vue写一个button按钮改变修改数据

    <el-button @click="changeName"><h3>改变name</h3></el-button>

    然后我们写方法调用 this.$store.commit("AAAA", BBBB);

    AAAA就是mutations中要用的方法名,BBBB是参数

     

    1. export default {
    2. data() {
    3. return {
    4. name: "new",
    5. };
    6. },
    7. methods: {
    8. changeName() {
    9. this.$store.commit("setobjName", this.name);
    10. },
    11. },
    12. };

    点击一下,看效果  会发现app.vue, test.vue, profile.vue 三个页面的都改变了,成了new张三儿1,是不是很神奇

    4.5 同样可以使用辅助函数写。我们在profile.vue页面写一个按钮

    <el-button @click="changeIdFun"><h3>改变id</h3></el-button>

    此时我们页面引入辅助函数

    import { mapState, mapMutations} from "vuex";

    然后计算属性获取

    1. computed: {
    2. ...mapState(["obj2"]),
    3. },

    我们页面获取数据可以写成这样

    1. <h2>
    2. 使用辅助函数
    3. <div>id:{{ obj2.id }}</div>
    4. </h2>
    1. <script>
    2. //辅助函数
    3. import { mapState, mapMutations} from "vuex";
    4. export default {
    5. name: "Table",
    6. computed: {
    7. ...mapState(["obj2"]),
    8. },
    9. data() {
    10. return {
    11. id: "new",
    12. };
    13. },
    14. methods: {
    15. //方法2 使用辅助函数提交 和下面注释的效果一样
    16. ...mapMutations(["setobjId"]),
    17. changeIdFun() {
    18. this.setobjId(this.id);
    19. },
    20. },
    21. };
    22. script>

    5 同样异步操作经常是调用接口获取数据需要耗时,我们需要等待,追踪状态

    方法asyncSetobjName,隔1秒再修改数据,传递参数Asyncname

    方法asyncSetobjId  隔1.2秒再修改数据,传递动态参数

    1. //异步操作
    2. actions: {
    3. asyncSetobjName(context) {
    4. setTimeout(() => {
    5. context.commit('setobjName', "Asyncname")
    6. }, 1000);
    7. },
    8. asyncSetobjId: (context, payload) => {
    9. setTimeout(() => {
    10. context.commit('setobjId', payload)
    11. }, 1200);
    12. }
    13. },

    会发现  context.commit('setobjName', "Asyncname")时候的方法还是mutations里面的同步方法!

     

    同样页面提交时候 this.$store.dispatch("XXXX");

    test.vue页面

     

    1. changeNameAsync() {
    2. this.$store.dispatch("asyncSetobjName");
    3. },

    也可以使用辅助函数操

     

    使用的详细教程文档结构

    使用的详细教程文档结构

    使用的详细教程文档结构

    1 store.js文档的结构

    1. import Vue from 'vue'
    2. import Vuex from 'vuex'
    3. Vue.use(Vuex)
    4. export default new Vuex.Store({
    5. state: {
    6. //直接使用
    7. obj1: {
    8. name: "张三儿1",
    9. id: "obj1"
    10. },
    11. //辅助函数
    12. obj2: {
    13. name: "张三儿2",
    14. id: "obj2"
    15. }
    16. },
    17. //同步操作
    18. mutations: {
    19. //普通函数方法写
    20. setobjName(state, name) {
    21. state.obj1.name = name + state.obj1.name
    22. },
    23. //箭头函数方法写
    24. setobjId: (state, id) => {
    25. state.obj2.id = id + state.obj2.id
    26. }
    27. },
    28. //异步操作
    29. actions: {
    30. asyncSetobjName(context) {
    31. setTimeout(() => {
    32. context.commit('setobjName', "Asyncname")
    33. }, 1000);
    34. },
    35. asyncSetobjId: (context, payload) => {
    36. setTimeout(() => {
    37. context.commit('setobjId', payload)
    38. }, 1200);
    39. }
    40. },
    41. modules: {}
    42. })

    2 路由里面核心代码组件 Home, Test,Profile三个组件页面(也可以不用一下代码。自己写三个路由组件)

     

    1. import Vue from 'vue'
    2. import VueRouter from 'vue-router'
    3. import Home from '../views/Home.vue'
    4. import Login from '../views/login.vue'
    5. import Footer from '../views/footer.vue'
    6. Vue.use(VueRouter)
    7. const VueRouterPush = VueRouter.prototype.push
    8. VueRouter.prototype.push = function push(to) {
    9. return VueRouterPush.call(this, to).catch(err => err)
    10. }
    11. const routes = [{
    12. path: '/',
    13. name: 'Home',
    14. components: {
    15. default: Home,
    16. footerName: Footer
    17. }
    18. },
    19. {
    20. path: '/Login',
    21. name: 'Login',
    22. components: {
    23. default: Login,
    24. }
    25. },
    26. {
    27. path: '/Test',
    28. name: 'Test',
    29. meta: {
    30. title: "是否有权限",
    31. transition: "abcd"
    32. },
    33. components: {
    34. default: () => import('../views/Test.vue'),
    35. footerName: Footer
    36. },
    37. props: {
    38. default: route => {
    39. return route.query.search
    40. },
    41. footerName: {
    42. footerdata: "正版"
    43. }
    44. },
    45. beforeEnter: (to, from, next) => {
    46. if (to.meta.title) {
    47. console.log('meta后执行', to.meta.title)
    48. }
    49. next()
    50. }
    51. }, {
    52. path: '/Profile',
    53. name: 'Profile',
    54. components: {
    55. default: () => import('../views/profile.vue'),
    56. footerName: Footer
    57. },
    58. props: {
    59. default: true,
    60. footerName: {
    61. footerdata: "正版"
    62. }
    63. }
    64. },
    65. {
    66. path: '/:all',
    67. name: 'Router404',
    68. component: () => import('../views/Router404.vue')
    69. }
    70. ]
    71. const router = new VueRouter({
    72. mode: 'history',
    73. base: process.env.BASE_URL,
    74. routes
    75. })
    76. let flag = false;
    77. let pathName = '';
    78. router.beforeEach((to, from, next) => {
    79. if (to.meta.title) {
    80. console.log('meta先执行')
    81. }
    82. flag = localStorage.getItem('userToken') ? true : false
    83. if (flag) {
    84. if (to.name === 'Login') {
    85. next('/')
    86. } else if (to.name === 'Home' && pathName) {
    87. next(pathName)
    88. } else {
    89. next()
    90. }
    91. } else {
    92. if (to.name === 'Login') {
    93. next()
    94. } else {
    95. if (to.path === '/Profile') {
    96. pathName = to.path
    97. }
    98. next('/Login')
    99. }
    100. }
    101. })
    102. export default router

     3 App.vue

    1. <template>
    2. <div id="app" style="margin: 50px; line-height: 34px; width: 800px">
    3. <h3>
    4. <div>name:{{ $store.state.obj1.name }}</div>
    5. <div>id:{{ $store.state.obj2.id }}</div>
    6. </h3>
    7. <el-button> <router-link to="/Profile">Profile</router-link></el-button>
    8. <el-button> <router-link to="/Test">Test</router-link></el-button>
    9. <router-view v-slot="{ Component }">
    10. <transition :name="route.meta.transition || 'fade'">
    11. <component :is="Component" />
    12. </transition>
    13. </router-view>
    14. <router-view name="footerName"></router-view>
    15. </div>
    16. </template>

    4 profile.vue

    1. <template>
    2. <div
    3. style="
    4. margin-top: 50px;
    5. line-height: 34px;
    6. width: 800px;
    7. border: 1px solid red;
    8. "
    9. >
    10. <h3>这是profile</h3>
    11. <h2>
    12. <div>name:{{ $store.state.obj1.name }}</div>
    13. 使用辅助函数
    14. <div>id:{{ obj2.id }}</div>
    15. </h2>
    16. <el-button @click="changeIdFun"><h3>改变id</h3></el-button>
    17. <el-button @click="changeIdFunAsync"><h3>异步改变id</h3></el-button>
    18. </div>
    19. </template>
    20. <script>
    21. //辅助函数
    22. import { mapState, mapMutations, mapActions } from "vuex";
    23. export default {
    24. name: "Table",
    25. props: ["username", "userid"],
    26. computed: {
    27. ...mapState(["obj2"]),
    28. },
    29. data() {
    30. return {
    31. id: "new",
    32. idAsync: "idAsync",
    33. };
    34. },
    35. methods: {
    36. //方法2 使用辅助函数提交 和下面注释的效果一样
    37. ...mapMutations(["setobjId"]),
    38. ...mapActions(["asyncSetobjId"]),
    39. changeIdFun() {
    40. this.setobjId(this.id);
    41. },
    42. //方法1 正常commit提交
    43. // changeId() {
    44. // this.$store.commit("setobjId", this.id);
    45. // },
    46. changeIdFunAsync() {
    47. this.asyncSetobjId(this.idAsync, this.idAsync);
    48. },
    49. },
    50. };
    51. </script>
    52. <style scoped lang="scss">
    53. h2 {
    54. color: purple;
    55. margin-bottom: 10px;
    56. }
    57. h3 {
    58. font-size: 18px;
    59. }
    60. </style>

    5 test.vue

    1. <template>
    2. <div
    3. id="app"
    4. style="
    5. margin-top: 50px;
    6. line-height: 34px;
    7. width: 800px;
    8. border: 1px solid red;
    9. "
    10. >
    11. <h3>这是test</h3>
    12. <h2>
    13. <div>name:{{ $store.state.obj1.name }}</div>
    14. <div>id:{{ $store.state.obj2.id }}</div>
    15. </h2>
    16. <el-button @click="changeName"><h3>改变name</h3></el-button>
    17. <el-button @click="changeNameAsync"><h3>异步改变name</h3></el-button>
    18. </div>
    19. </template>
    20. <script>
    21. export default {
    22. name: "test",
    23. props: ["search"],
    24. data() {
    25. return {
    26. index: 1,
    27. name: "new",
    28. };
    29. },
    30. methods: {
    31. changeName() {
    32. this.$store.commit("setobjName", this.name);
    33. },
    34. changeNameAsync() {
    35. this.$store.dispatch("asyncSetobjName");
    36. },
    37. },
    38. };
    39. </script>

    下一篇讲解模块化处理,module高级用法

     看到这里的给个赞哦 ,码字不容易,半小时多,感谢各位

  • 相关阅读:
    Mac安装Docker
    游戏测试行业还能入局吗?前线打探最新消息来了
    分布式 PostgreSQL 集群(Citus),官方快速入门教程
    unix/linux make
    PyTorch 卷积网络正则化 DropBlock
    第五章TCP/IP 网络在我们身边
    ​基于光通信的6G水下信道建模综述
    MQ常见的问题(kafka保证消息不丢失)
    Day26-龟兔赛跑案例、Callable接口、静态代理、Lambda表达式
    python爬虫——爬取豆瓣top250电影数据(适合初学者)
  • 原文地址:https://blog.csdn.net/jieweiwujie/article/details/126856548