• Vuex——笔试题、Vuex简介、引入方式、State、Getter、Mutation、Action、Module


    目录

     仓库vuex

    一、Vuex简介

    二、引入方式

    1.自己下载引入

    2.cli脚手架引入

    1.手动引入(方法一)

    2.引入(方法二)

    三、State

    1.创建state状态

    2.组件中访问数据

    四、Getter

    1.设计

    2.使用

    五、Mutation

    1.设计

    2.组件中使用

    2.1 第一种方式:直接触发并传值(提交载荷)

    2.2 第二种方式:可以以一个对象的形式传入

    六、 Action

    1、设计

    2、使用(两种):

    1.直接分发

    2.以对象形式分发

    七、Module

    八、笔试题


     仓库vuex

    一、Vuex简介

    1.简介

    为了方便实现组件之间的数据共享,Vuex是他们团队借鉴了redux,用来实现vue组件全局状态(数据)管理的一种机制.

    2.特点(面试)

    能够在vuex中集中管理共享的数据,易于开发和后期维护

    能够高效地实现组件之间的数据共享, 提高开发效率

    存储在 vuex中的数据都是响应式的,能够实时保持数据与页面的同步

    一般情况下,只有组件之间共享的数据,才有必要存储到vuex中;

    对于组件中的私有数据,依旧存储在组件自身的data中即可.

    3.使用场景

    如果你实在不知道开发中什么数据才应该保存到Vuex中,那你就先不用Vuex,需要的时候自然就会想到它

    Vuex的官网:

    二、引入方式

    1.自己下载引入

    2.cli脚手架引入

    1.手动引入(方法一)

    安装: 

    npm i vuex --save

    导入:

    import Vuex from "vuex"

    Vue.use(Vuex)

    创建仓库:

    const store=new Vuex.Store({

               state:{msg:"我就是所有共享的数据"}

    })

    把仓库挂载到vm对象:

    1. new Vue({
    2. render(h){return h(app)},
    3. router,
    4. store//挂载以后 所有的组件就可以直接从store中获取全局数据
    5. }).$mount( "#app")

    2.引入(方法二)

    vue create init

    选更多选项

    选择Babel、router、vuex、scss、linter

    选择2.x

    回车

    scss

    回车

    取消lint on save

    回车

    三、State

    1.创建state状态

    状态就是那个存数据的对象

    1. const store=new Vuex.store({
    2.           state:{msg:"我就是所有共享的数据"}
    3. })

    2.组件中访问数据

    this.$store.state.msg

    this.$store.state.msg =“修改”  ==>官方不建议使用此方法去修改,应该用官方提供的 mutation

    main.js

    1. import Vue from 'vue'
    2. import App from './App.vue'
    3. import router from './router'
    4. import store from './store'
    5. Vue.config.productionTip = false
    6. new Vue({
    7. router,
    8. store,//让整个vue项目仓库生效
    9. render: h => h(App)
    10. }).$mount('#app')

    router下的index.js

    1. import Vue from 'vue'
    2. import VueRouter from 'vue-router'
    3. Vue.use(VueRouter)
    4. const routes = [{
    5. path: '/',
    6. name: 'home',
    7. component: () => import("../views/home/index.vue")
    8. },
    9. {
    10. path: '/home',
    11. name: 'home2',
    12. component: () => import("../views/home/index.vue")
    13. },
    14. {
    15. path: '/login',
    16. name: 'login',
    17. component: () => import("../views/login/index.vue")
    18. },
    19. {
    20. path: '/car',
    21. name: 'car',
    22. component: () => import("../views/car/index.vue")
    23. },
    24. {
    25. path: '/news',
    26. name: 'news',
    27. component: () => import("../views/news/index.vue"),
    28. beforeEnter(to,from,next){
    29. console.log("beforeEnter",1111)
    30. next()
    31. }
    32. },
    33. {
    34. path: '/*',
    35. name: 'err',
    36. component: () => import("../views/err/index.vue")
    37. }
    38. ]
    39. const router = new VueRouter({
    40. mode: 'history',
    41. base: process.env.BASE_URL,
    42. routes
    43. })
    44. export default router

    store下的index.js

    1. import Vue from 'vue'
    2. import Vuex from 'vuex'
    3. Vue.use(Vuex)//让组件的原型链中 有仓库的工具代码
    4. export default new Vuex.Store({
    5. state: {
    6. msg:"仓库中的数据",
    7. arr:[{price:18,count:2,id:123},{price:15,count:2,id:124},{price:12,count:2,id:127}]
    8. },
    9. getters: {
    10. total(state){
    11. //笔试题: 字符串去前后空格 数组去重 求总价
    12. return state.arr.reduce(function(n1,n2){return n1+n2.price*n2.count},0)
    13. }
    14. },
    15. mutations: {
    16. change1(state,agr2){
    17. console.log(agr2,6666)
    18. state.msg=agr2.a
    19. },
    20. change3(state,arg){
    21. state.arr[0].count =arg.n
    22. // mutations中修改仓库数据 只能在同步代码中实现 不要再异步函数中实现 否则会出现不刷新页面的情况
    23. }
    24. },
    25. actions: {
    26. },
    27. modules: {
    28. }
    29. })

    home下面的components下的Box2.vue

    1. <script>
    2. export default {
    3. methods:{
    4. change1(){
    5. // this.$store.state.msg="box2修改了仓库数据"//官方说的 不要这样直接去修改数据
    6. },
    7. change2(){
    8. //提交载荷
    9. //第1种. this.$store.commit("change1","hello,box2修改了数据")
    10. //第2种. this.$store.commit("change1",{a:"hello,box2修改了数据"})
    11. //也是2种的另外一种写法,
    12. this.$store.commit({type:"change1",a:"hello,box2修改了数据"})
    13. },
    14. change3(){
    15. this.$store.commit({type:"change3",n:10})
    16. // this.$store.state.arr[0].count=200
    17. }
    18. }
    19. }
    20. script>
    21. <style>
    22. style>

    四、Getter

    getter就就像是store的计算属性,它会传入state对象供我们操作

    1.设计

    1. const store = new Vuex.Store({
    2. state: {
    3. arr: [
    4. { id: 1, text: '...', birth: "1997-02-03" },
    5. { id: 2, text: '...', birth: "2019-10-03" }
    6. ]
    7. },
    8. getters: {
    9. bigMans(state) {
    10. return state.arr.filter((man)=>{
    11. let manY=new Date(man.birth).getFullYear()
    12. let nowY=new Date().getFullYear()
    13. return (nowY-manY)>=18
    14. })
    15. }
    16. }
    17. })

    2.使用

    this.$store.getters.bigMans


     

    五、Mutation

    mutation中修改仓库数据,只能在同步代码中实现,不要在异步函数中实现,否则会出现不刷新页面的情况

    修改状态的唯一方式就是提交mutations,而且是同步的

    如果要异步的修改数据,就可以使用actions异步的提交mutations

    组件中希望更改 Vuex 的 store 中的状态(数据)的唯一方法是提交 mutation
    不要用赋值表达式直接在组件中给store设置新数据
    这样设计的原因是,只有通过mutation来更新数据,它才会去帮我们通知所有使用数据的组件更新数据 刷新UI

    1.设计

    1. const store = new Vuex.Store({
    2. state: {
    3. count: 1
    4. },
    5. mutations: {
    6. //默认传第一个参数传state
    7. increment (state,obj) {
    8. // 变更状态
    9. state.count=obj.n
    10. }
    11. }
    12. })

    2.组件中使用

    2.1 第一种方式:直接触发并传值(提交载荷)

    this.$store.commit('increment',{n:100})
    increment是触发的函数名

    2.2 第二种方式:可以以一个对象的形式传入

    传入对象时,当相于把整个对象作为了第二个参数传入mutations

    1. //第一种
    2. this.$store.commit("increment",{a:"修改"}
    3. //第二种:
    4. this.$store.commit({
    5.   type: 'increment',
    6.   n:100
    7. })

    注意:一条重要的原则就是要记住 mutation 必须是同步处理
    下面是错误的方式:

    1. mutations: {
    2. increment (state,obj) {
    3. //如果fnAsync函数是一个异步业务函数,就会导致更新失败
    4. fnAsync(() => {
    5. state.count=obj.n
    6. })
    7. }
    8. }

    六、 Action

    Action 提交的是 mutation,而不是直接变更状态。
    Action 可以包含任意异步操作。

    如果要异步的修改数据,就可以使用actions异步的提交mutations

    1、设计

    1. const store = new Vuex.Store({
    2. state: {
    3. count: 0
    4. },
    5. mutations: {
    6. increment (state,obj) {
    7. state.count=obj.n
    8. }
    9. },
    10. actions: {
    11. //默认第一个参数传一个跟store一样的对象
    12. increment (context,obj) {
    13. //假设fnAsync是一个异步业务函数
    14. fnAsync(() => {
    15. context.commit('increment',obj)
    16. })
    17. }
    18. }
    19. })

    2、使用(两种):

    1.直接分发

    this.$store.dispatch('increment',{n:100})
     

    2.以对象形式分发

    1. this.$store.dispatch({
    2.   type: 'increment',
    3.   n:100
    4. })

    七、Module

    可用于业务分块开发:
    由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
    为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter

    1. //分块设计:
    2. const moduleA = {
    3. namespaced: true,//局部命名空间(让state的中变量与其他模块中的同名变量不冲突)
    4. state: { msg:1 },
    5. mutations: { change(state,n){state.msg=n} },
    6. actions: { change(context,n){context.commit("change",n)} },
    7. getters: { x(state){return state.msg} }
    8. }
    9. const moduleB = {
    10. namespaced: true,//局部命名空间
    11. state: { msg:1 },
    12. mutations: { change(state,n){state.msg=n} },
    13. actions: { change(context,n){context.commit("change",n)} },
    14. getters: { x(state){return state.msg} }
    15. }
    16. const store = new Vuex.Store({
    17. modules: {
    18. a: moduleA,
    19. b: moduleB
    20. }
    21. })
    22. //组件中的使用:
    23. this.$store.state.a.msg // -> moduleA 的状态
    24. this.$store.state.b.msg // -> moduleB 的状态
    25. this.$store.commit("a/change",100)-> moduleA 的mutations
    26. this.$store.commit("b/change",200)-> moduleB 的mutations
    27. this.$store.getters["a/x"]-> moduleA 的getters
    28. this.$store.getters["b/x"]-> moduleB 的getters
    29. this.$store.dispatch("a/change",100)-> moduleA 的actions
    30. this.$store.dispatch("b/change",200)-> moduleB 的actions

     store下的index.js

    1. import Vue from 'vue'
    2. import Vuex from 'vuex'
    3. import Model1 from "./Model1.js"
    4. import Model2 from "./Model2.js"
    5. import Model3 from "./Model3.js"
    6. import Model4 from "./Model4.js"
    7. Vue.use(Vuex) //让组件的原型链中 有仓库的工具代码
    8. export default new Vuex.Store({
    9. state: {
    10. },
    11. getters: {
    12. },
    13. mutations: {
    14. },
    15. actions: {
    16. },
    17. modules: {
    18. Model1,
    19. Model2:Model2,
    20. Model3,
    21. Model4
    22. }
    23. })

    store下的Model1.js

    1. export default {
    2. namespaced: true,//局部命名空间(让state的中变量与其他模块中的同名变量不冲突)
    3. state: {
    4. x:"张三的公共数据"
    5. },
    6. getters: {
    7. getx(){
    8. return x+"6666"
    9. }
    10. },
    11. mutations: {
    12. setxsync(state,obj){
    13. state.x=obj.x
    14. }
    15. },
    16. actions: {
    17. setxasync(ctx,obj){
    18. setTimeout(()=>{
    19. ctx.commit("setxsync",obj)
    20. },1000)
    21. }
    22. }
    23. }

    可以拓展:

    mapState,mapGetters,mapMutation,mapAction和使用常量替代 Mutation 事件类型,

    使用常量替代 mutation 事件类型在各种 Flux 实现中是很常见的模式。

    同时把这些常量放在单独的文件中可以让你的代码合作者对整个 app 包含的 mutation 一目了然

    用不用常量取决于你——在需要多人协作的大型项目中,这会很有帮助。但如果你不喜欢,你完全可以不这样做。

    八、笔试题

    下列关于 Vuex 的描述,不正确的是哪项?
    A. Vuex 通过 Vue 实现响应式状态,因此只能用于 Vue
    B. Vuex 是一个状态管理模式
    C. Vuex 主要用于多视图间状态全局共享与管理
    D. 在 Vuex 中改变状态,可以通过 mutations 和 actions

    选C,多视图

  • 相关阅读:
    【云原生&微服务十】SpringCloud之OpenFeign实现服务间请求头数据传递(OpenFeign拦截器RequestInterceptor的使用)
    caffe-make_runtest
    到医院不给开康复证明为什么
    【五】sql 语言 -- 概览
    【Python实战】--输出与输出(updating)
    Python简直是万能的,这5大主要用途你一定要知道!
    开源的容器运行时项目 Podman
    跳跃游戏(动态规划)
    2022-05-05 mybatis-plus 批量插入修改操作
    An Empirical Study of GPT-3 for Few-Shot Knowledge-Based VQA
  • 原文地址:https://blog.csdn.net/qq_52301431/article/details/126832511