其他分享
首页 > 其他分享> > Web前端之vuex基础

Web前端之vuex基础

作者:互联网

什么是Vuex

Vuex是一个专门为Vue.js应用程序开发的一个状态管理模式,它采用了集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化

什么是状态管理模式

new Vue({
  // state
  data () {
    return {
      count: 0
    }
  },
  // view
  template: `
    <div>{{ count }}</div>
  `,
  // actions
  methods: {
    increment () {
      this.count++
    }
  }
})

状态自管理应用包含以下几个部分:

单向数据流:

在这里插入图片描述

当遇到多个组件共享时,单向数据流的简洁性很容易被破坏

在这里插入图片描述

使用Vuex管理数据的好处:

Vuex使用

安装或引入

可以通过CDN节点引入(不推荐)

<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js"></script>

也可以使用npm命令进行安装(推荐)

npm install vuex -S

当然,如果在用Vue CLI 脚手架进行创建项目时,如果引用了Vuex咋不在需要上面的操作了

使用

使用时需要在新建js文件中引用,当然我们还需要在main.js中引入使用

当我们使用Vue CLI 脚手架创建项目后

我们在src目录下的views下面新建文件夹Store

在这里插入图片描述

在此文件夹内创建index.js文件
在这里插入图片描述

在index中编写如下编码

在这里插入图片描述

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
const store = new Vuex.Store({
  state: {

  },
  mutations: {

  }
})
export default store

然后在main.js中引入调用并且创建实例
在这里插入图片描述

父传子

Add.vue

<template>
  <div id="app">
     <my-add :count="count" @handle-add="add"></my-add>  <my-sub
      :count="count"
      @handle-sub="del"
    ></my-sub>
  </div>
</template>
<script>
import c1 from './views/children'
import c2 from './views/children1'
export default {
  data() {
    return {
      count: 0
    }
  },
  components: {
    'my-add': c1,
    'my-sub': c2
  },
  methods: {
    add() {
      this.count++
    },
    del() {
      this.count--
    }
  }
}
</script>

children.vue

<template>
  <div class="main">
     
    <h3>变量 count 的值为:{{ count }}</h3>
     <button @click="add">+1</button>
  </div>
</template>
<script>
export default {
  props: ['count'],
  methods: {
    add() {
      this.$emit('add')
    }
  }
}
</script>

children1.vue

<template>
  <div class="main">
    <h3>变量 count 的值为:{{ count }}</h3>
    <button @click="sub">-1</button>
  </div>
</template>
<script>
export default {
  props: ['count'],
  methods: {
    sub() {
      this.$emit('del')
    }
  }
}
</script>

加加减减的写法

index.js文件

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    add(state) {
      state.count++
    },
    del(state) {
      state.count--
    }
  }
})
export default store

修改组件

<template>
  <div class="main">
    <h3>变量 count 的值为:{{ $store.state.count }}</h3>
    <button @click="add">+1</button>
    <button @click="del">-1</button>
  </div>
</template>
<script>
export default {
  methods: {
    add() {
      this.$store.commit('add')
    },
    del() {
      this.$store.commit('del')
    }
  }
}
</script>

效果:

在这里插入图片描述

核心

states

单一状态树

State提供唯一的公共数据源,所有共享的数据都要统一放到Store中的State中存储
vuex 中的 state 相当于组件中的 data
State中的数据与组件 data 中的数据一样,也是响应式的

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    name: '张三',
    age: 20,
    sex: '男'
  }
})
export default store

组件使用state中的值

<template>
  <div class="home">{{ $store.state }}</div>
</template>
<script>
export default {

}
</script>

计算属性

上面原样使用不方便使用所以使用计算属性来便于使用

<template>
  <div class="home">
    <p>{{ name }}</p>
    <p>{{ age }}</p>
    <p>{{ sex }}</p>
  </div>
</template>
<script>
export default {
  computed: {
    name() {
      return this.$store.state.name
    },
    age() {
      return this.$store.state.age
    },
    sex() {
      return this.$store.state.sex
    }
  }
}
</script>

在这里插入图片描述

但上面那样使用代码量太多

我们可以使用辅助函数:mapState

<template>
  <div class="home">
    <p>{{ name }}</p>
    <p>{{ age }}</p>
    <p>{{ sex }}</p>
  </div>
</template>
<script>
// 在vuex中引出mapState辅助函数
import { mapState } from 'vuex'
export default {
  computed: mapState({
    name: state => state.name,
    age: state => state.age,
    sex: state => state.sex
  })
}
</script>

再次简洁一步

<template>
  <div class="home">
    <p>{{ name }}</p>
    <p>{{ age }}</p>
    <p>{{ sex }}</p>
  </div>
</template>
<script>
// 在vuex中引出mapState辅助函数
import { mapState } from 'vuex'
export default {
  computed: mapState({
    name: 'name',
    age: 'age',
    sex: 'sex'
  })
}
</script>

最简洁方法:

映射的计算属性的名称与 state 的子节点名称相同时,我们可以给 mapState 传一个字符串数组

<template>
  <div class="home">
    <p>{{ name }}</p>
    <p>{{ age }}</p>
    <p>{{ sex }}</p>
  </div>
</template>
<script>
// 在vuex中引出mapState辅助函数
import { mapState } from 'vuex'
export default {
  computed: mapState(['name', 'age', 'sex'])
}
</script>

展开运算符

使用辅助函数后,mapState 函数的返回值是一个对象

<template>
  <div class="home">
    <p>{{ name }}</p>
    <p>{{ age }}</p>
    <p>{{ sex }}</p>
  </div>
</template>
<script>
// 在vuex中引出mapState辅助函数
import { mapState } from 'vuex'
export default {
  computed: mapState(['name', 'age', 'sex']),
  created() {
    const res = mapState(['name', 'age', 'sex'])
    console.log(res)
  }
}
</script>

输出结果

在这里插入图片描述

所以利用展开运算符可以更改上面的编码

<template>
  <div class="home">
    <p>{{ name }}</p>
    <p>{{ age }}</p>
    <p>{{ sex }}</p>
  </div>
</template>
<script>
// 在vuex中引出mapState辅助函数
import { mapState } from 'vuex'
export default {
  computed: { ...mapState(['name', 'age', 'sex']) }
}
</script>

但是我感觉用在这里,那简直的画蛇添足、多此一举

不过展开运算符用在其他地方还是很有必要的

Getter数据获取器

在Store文件夹下index.js添加

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    teacher: [
      {
        name: '张三',
        age: 20,
        sex: '男'
      },
      {
        name: '李四',
        age: 25,
        sex: '女'
      }
    ]
  },
  getters: {
    // 定义gettter,统计所有完成的事项
    doneTodos: state => {
      return state.teacher.filter(t => t.sex)
    }
  }
})
export default store

组件中

<template>
  <div class="home">
    {{ $store.getters.doneTodos }}
  </div>
</template>
<script>

export default {

}
</script>

也可使用 mapGetters 和 mapState 辅助函数

<template>
  <div class="home">
    <p>{{ doneTodos }}</p>
    <p>{{ teacher }}</p>
  </div>
</template>
<script>
// 在vuex中引出mapState辅助函数
import { mapState, mapGetters } from 'vuex'
export default {
  computed: {
    ...mapState(['teacher']),
    ...mapGetters(['doneTodos'])
  }
}
</script>

Mutation

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)

这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

任何时候想添加新值,且不能直接添加,只有通过mutation才可

Store 下的 index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    teacher: [
      {
        name: '张三',
        age: 20,
        sex: '男'
      },
      {
        name: '李四',
        age: 25,
        sex: '女'
      }
    ]
  },
  getters: {
    // 定义gettter,统计所有完成的事项
    doneTodos: state => {
      return state.teacher.filter(t => t.sex)
    }
  },
  mutations: {
    add(state) {
      state.teacher.push({
        name: '王五',
        age: 19,
        sex: '女'
      })
    }
  }
})
export default store

组件

<template>
  <div class="home">
    <p>{{ doneTodos }}</p>
    <p>{{ teacher }}</p>
    <button @click="add">添加</button>
  </div>
</template>
<script>
// 在vuex中引出mapState辅助函数
import { mapState, mapGetters } from 'vuex'
export default {
  computed: {
    ...mapState(['teacher']),
    ...mapGetters(['doneTodos'])
  },
  methods: {
    add() {
      this.$store.commit('add')
    }
  }
}
</script>

提交载荷

传入额外的参数,即 mutation 的 载荷(payload)

index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    teacher: [
      {
        name: '张三',
        age: 20,
        sex: '男'
      },
      {
        name: '李四',
        age: 25,
        sex: '女'
      }
    ]
  },
  getters: {
    // 定义gettter,统计所有完成的事项
    doneTodos: state => {
      return state.teacher.filter(t => t.sex)
    }
  },
  mutations: {
    add(state, teacher) {
      state.teacher.push(teacher)
    }
  }
})
export default store

组件中使用

<template>
  <div class="home">
    <p>{{ doneTodos }}</p>
    <p>{{ teacher }}</p>
    <button @click="add">添加</button>
  </div>
</template>
<script>
// 在vuex中引出mapState辅助函数
import { mapState, mapGetters } from 'vuex'
export default {
  computed: {
    ...mapState(['teacher']),
    ...mapGetters(['doneTodos'])
  },
  methods: {
    add() {
      this.$store.commit('add', {
        name: '王五',
        age: 19,
        sex: '女'
      })
    }
  }
}
</script>

大多数情况下,载荷应该是一个对象,可以包含多个字段并且记录的 mutation 会更易读Mutation 必须是同步函数:不要在其中执行ajax 等异步操作

mapMutations辅助函数减少代码

组件中作如下修改

<template>
  <div class="home">
    <p>{{ doneTodos }}</p>
    <p>{{ teacher }}</p>
    <button @click="addI">添加</button>
  </div>
</template>
<script>
// 在vuex中引出辅助函数
import { mapState, mapGetters, mapMutations } from 'vuex'
export default {
  computed: {
    ...mapState(['teacher']),
    ...mapGetters(['doneTodos'])
  },
  methods: {
    ...mapMutations(['add']),
    addI() {
      this.add({ name: '王五', age: 19, sex: '女' })
    }
  }
}
</script>

Action

Action 类似于 mutation,不同在于:

js文件中

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    teacher: [
      {
        name: '张三',
        age: 20,
        sex: '男'
      },
      {
        name: '李四',
        age: 25,
        sex: '女'
      }
    ]
  },
  getters: {
    // 定义gettter,统计所有完成的事项
    doneTodos: state => {
      return state.teacher.filter(t => t.sex)
    }
  },
  mutations: {
    add(state, teacher) {
      state.teacher.push(teacher)
    }
  },
  actions: {
    addS(state, teacher) {
      setTimeout(() => {
        state.commit('add', teacher)
      }, 2000)
    }
  }
})
export default store

组件中

<template>
  <div class="home">
    <p>{{ doneTodos }}</p>
    <p>{{ teacher }}</p>
    <button @click="addI">添加</button>
  </div>
</template>
<script>
// 在vuex中引出辅助函数
import { mapState, mapGetters, mapMutations } from 'vuex'
export default {
  computed: {
    ...mapState(['teacher']),
    ...mapGetters(['doneTodos'])
  },
  methods: {
    ...mapMutations(['add']),
    addI() {
      // this.add({ name: '王五', age: 19, sex: '女' })
      this.$store.dispatch('addS', { name: '王五', age: 19, sex: '女' })
    }
  }
}
</script>

mapActions 辅助函数映射使用

组件中

<template>
  <div class="home">
    <p>{{ doneTodos }}</p>
    <p>{{ teacher }}</p>
    <button @click="addI">添加</button>
  </div>
</template>
<script>
// 在vuex中引出辅助函数
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
  computed: {
    ...mapState(['teacher']),
    ...mapGetters(['doneTodos'])
  },
  methods: {
    ...mapMutations(['add']),
    ...mapActions(['addS']),
    addI() {
      // this.add({ name: '王五', age: 19, sex: '女' })
      this.addS({ name: '王五', age: 19, sex: '女' })
    }
  }
}
</script>

  methods: {
    ...mapMutations(['add']),
    addI() {
      // this.add({ name: '王五', age: 19, sex: '女' })
      this.$store.dispatch('addS', { name: '王五', age: 19, sex: '女' })
    }
  }
}
</script>

mapActions 辅助函数映射使用

组件中

<template>
  <div class="home">
    <p>{{ doneTodos }}</p>
    <p>{{ teacher }}</p>
    <button @click="addI">添加</button>
  </div>
</template>
<script>
// 在vuex中引出辅助函数
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
  computed: {
    ...mapState(['teacher']),
    ...mapGetters(['doneTodos'])
  },
  methods: {
    ...mapMutations(['add']),
    ...mapActions(['addS']),
    addI() {
      // this.add({ name: '王五', age: 19, sex: '女' })
      this.addS({ name: '王五', age: 19, sex: '女' })
    }
  }
}
</script>

标签:Web,name,前端,sex,mapState,state,vuex,age
来源: https://blog.csdn.net/blue_698/article/details/115310175