vue-cli中vueX的安装与使用

vue-cli 3.x脚手架配置并使用vux vue-cli更新到3.x,改动很大,做前端的朋友推荐我将vux项目转到vue-cli3上,通过看文档和查资料,花了几个小时,终于完成,特此记录。 一、安装vue-cli 3 首先官方文档:https://cli.vuejs.org/ 官方文档包含了很多的内容,很靠谱,比较全面,第一步当然是把官方文档看一遍。 安装 Node 版本要求 Vue CLI 需要 Node.js 8.9 或更... 阅读详情

前言:

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,但并不意味着你需要将所有的状态放入 Vuex。虽然将所有的状态放到 Vuex 会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态。你应该根据你的应用开发实际需要进行权衡和确定。

运用vueX的场景:

多个视图依赖于同一状态,此时传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。

来自不同视图的行为需要变更同一状态。此时采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝,通常会导致无法维护的代码

兼容:

Vuex 依赖 Promise。如果你支持的浏览器并没有实现 Promise (如 IE),那么你可以使用一个 polyfill 的库(如  es6-promis)

1.你可以通过 CDN 将其引入,window.Promise 会自动可用:

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

2.包管理器安装:

npm install es6-promise --save //yarn add es6-promise 

然后,将下列代码添加到你使用 Vuex 之前的一个地方:

import 'es6-promise/auto'

一、安装

npm install vuex --save

二、新建仓库

在src目录下新建一个名为store的文件夹,然后在该文件夹下面创建一个store.js文件

三、在main.js中引入

import store from  './store/store'
//每当 store.state.count 变化的时候, 都会重新求取计算属性,并且触
//发更新相关联的 DOM。然而,这种模式会导致组件依赖全局状态单例。所以
//Vuex 通过 store 选项,提供了一种机制将状态从根组件“注入”到每一个
//子组件中(需调用 Vue.use(Vuex)):
Vue.use(Vuex)

...........

new Vue({
  el: '#app',
  router,
  store,//记得需要挂载才可以用,把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的        
  子组件,且子组件能通过 this.$store
  components: { App },
  template: '<App/>'
})

四、使用

vuex中有默认的五个核心概念:

1、state:存储状态(变量),vuex中的数据源,我们需要保存的数据就保存在这里,可以在页面通过 this.$store.state来获取我们定义的数据,要记得将每个状态进行初始化。

2、getters:对数据获取之前的再次编译,可以理解为state的计算属性。在组件中通过 this.$sotre.getters.xxx使用,Getter相当于vue中的computed计算属性, getter 的返回值会根据它的依赖被缓存起来, 且只有当它的依赖值发生了改变才会被重新计算,getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果,通过属性访问Getter 会暴露为 store.getters 对象,很容易地在任何组件中使用它 你可以以属性的形式访问这些值:this.$store.getters.xxx;Getters 可以用于监听、 state中的值的变化,返回计算后的结果,即getters中“+”的操作在进入时即会执行。

3、mutations:,在组件中通过this.$store.commit(‘xxx’,params)使用,它是更改 Vuex 的 store 中的状态的唯一方法,会执行状态的同步更新,且一旦状态发生改变监视状态的 Vue 组件也会自动更新,所以我们需要给每个状态进行初始化。方法中第一个参数默认为state,接下来的为自定义参数(即官方文档中说的载荷(payload),多数情况下,载荷应该是一个对象,这样可以包含多个字段并且记录的 mutation 会更易读)。

4、actions:Action 可以包含任意异步操作,但它提交的是 mutation,而且是异步提交,在组件中通过this.$store.dispath(‘xxx’)触发,不能直接变更数据,Action 函数接收一个与 store 实例具有相同方法和属性的 context 对象,所以我们可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。但是context 对象并不是 store 实例本身(这个和Modules相关 )。

5、modules:store的子模块,为了开发大型项目,方便状态管理而使用的,即将store分割为模块,使store对象不会太臃肿。

store.js

import Vue from 'vue'
import Vuex from 'vuex'
import {
  log
} from 'util';
Vue.use(Vuex)
export default new Vuex.Store({
  state: {
    count: 0,
    age: 0
  },
  getters: {
    getterAge(state) {
      console.log(state);
      return state.age;
    }
  },
  mutations: {
    addCount(state, obj) {
      return state.count += obj.num;
    },
    subCount(state, obj) {
      return state.count -= obj.num;
    }
  },
  actions: {
    addCountAsy(context) {
      setTimeout(() => {
        context.commit('addCount', {
          num: 2
        })
      }, 1000)
    },
    subCountAsy(context) {
      setTimeout(() => {
        context.commit('subCount', {
          num: 2
        })
      }, 1000)
    }
  }
})

index.vue

<template>
  <div>
    <h1></h1>
    <div class="addBtn" @click="handleAdd()">count++</div>
    <div class="addBtn" @click="handleSub()">count--</div>
    <div class="addBtn" @click="handleAddAsy()">异步count++(1S后执行)</div>
    <div class="addBtn" @click="handleSubAsy()">异步count--(1S后执行)</div>
    <h2>computed中通过state获取到的count:{{count}}</h2>
    <h2>computed中通过getters获取到计算后的count:{{getCount}}</h2>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  computed: {
    count() {
      return this.$store.state.count;
    },
    // 辅助函数mapState的用法,可以使我们更加方便的运用vuex,效果都是相同的
    /* 等价于:
    ...mapState([
      'count'
    ]), */
    getCount() {
      return this.$store.getters.getterCount;
    }
    /*  等价于:
    ...mapGetters([
      'getterCount'
    ]) */
  },
//监听count的变化
  watch: {
    count: { 
        function(val, oldVal) {console.log(val,oldVal)},
        deep: true
    }
  },
  data() {
    return {
      // msg: "Welcome to Your Vue.js App"
    };
  },
  methods: {
    // 可以通过点击事件进行同步的增加或减少count的值,且每次加减的值为传入载荷(可以为参数及对象)num的值2,载荷应该是一个对象,这样可以包含多个字段并且记录的 mutation 会更易读
    handleAdd() {
      this.$store.commit("addCount", {
        num: 2
      });
      console.log(
        "state中的count为:" + this.$store.state.count,
        "getters中的count为:" + this.$store.getters.getterCount
      );
    },
    handleSub() {
      this.$store.commit("subCount", {
        num: 2
      });
      console.log(
        "state中的count为:" + this.$store.state.count,
        "getters中的count为:" + this.$store.getters.getterCount
      );
    },
    // …mapMutations函数
    // 这里这样写并用大括号是为了将函数重新命名,即重新命名addCount和subCount',
    // 关于使用辅助函数后载荷的传参,直接在调用的地方进行传参便可
    // <div class="addBtn" @click="handleAdd({num:2})">count++</div>
    // <div class="addBtn" @click="handleSub({num:2})">count--</div>
    /* 等价于:
    ...mapMutations({
      handlerAdd: 'addCount',
      handlerSub: 'subCount'
    }), */

    //分发action,这里看起来好像比直接提交mutation麻烦,但是它却解决了异步的操作问题
    // …mapActions函数 ,和…mapMutations用法相似。
    /* 等价于
    ...mapActions({
          handlerAddasy: 'addCountasy',
          handlerSubasy: 'subCountasy'
    }) */
    handleAddAsy() {
      this.$store.dispatch("addCountAsy");
    },
    handleSubAsy() {
      this.$store.dispatch("subCountAsy");
    }
  },
  mounted() {
    console.log(this.$qs);
    console.log(this.$axios);
    console.log(this);
  }
};
</script>
<style>
.addBtn {
  width: 200px;
  height: 50px;
  line-height: 50px;
  text-align: center;
  font-size: 16px;
  background-color: skyblue;
  margin: 50px auto;
  cursor: pointer;
}
</style>

actions  getters  mutations也可以分别放在单独的文件夹下面进行定义,然后在store.js引入即可,main.js中的引入和上面的是一样的。

项目结构

store.js

import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'
import * as mutations from './mutations'
Vue.use(Vuex)
export const store = new Vuex.Store({
  state:{
    count: 0,
    age: 0
  },
  getters,
  mutations,
  actions
})

 

 

拓展:

对象展开运算符

let a = [1,2,3];

let b = [0, ...a, 4]; // [0,1,2,3,4] 

let obj = { a: 1, b: 2 }; 

let obj2 = { ...obj, c: 3 }; // { a:1, b:2, c:3 }

let a = [1,2,3]; 

let [b, ...c] = a; b;  // 1 c;     // [2,3]

let object = { a: '01', b: '02' }; 

let newObject = { c: '03', ...object }; 

console.log(newObject);      //{c: "03", a: "01", b: "02"}

 

Module(允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。)

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

#模块的局部状态

对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象。

const moduleA = {
  state: { count: 0 },
  mutations: {
    increment (state) {
      // 这里的 `state` 对象是模块的局部状态
      state.count++
    }
  },

  getters: {
    doubleCount (state) {
      return state.count * 2
    }
  }
}

同样,对于模块内部的 action,局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState:

const moduleA = {
  // ...
  actions: {
    incrementIfOddOnRootSum ({ state, commit, rootState }) {
      if ((state.count + rootState.count) % 2 === 1) {
        commit('increment')
      }
    }
  }
}

对于模块内部的 getter,根节点状态会作为第三个参数暴露出来:

const moduleA = {
  // ...
  getters: {
    sumWithRootCount (state, getters, rootState) {
      return state.count + rootState.count
    }
  }
}

#命名空间

默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。

如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。例如:

const store = new Vuex.Store({
  modules: {
    account: {
      namespaced: true,

      // 模块内容(module assets)
      state: { ... }, // 模块内的状态已经是嵌套的了,使用 `namespaced` 属性不会对其产生影响
      getters: {
        isAdmin () { ... } // -> getters['account/isAdmin']
      },
      actions: {
        login () { ... } // -> dispatch('account/login')
      },
      mutations: {
        login () { ... } // -> commit('account/login')
      },

      // 嵌套模块
      modules: {
        // 继承父模块的命名空间
        myPage: {
          state: { ... },
          getters: {
            profile () { ... } // -> getters['account/profile']
          }
        },

        // 进一步嵌套命名空间
        posts: {
          namespaced: true,

          state: { ... },
          getters: {
            popular () { ... } // -> getters['account/posts/popular']
          }
        }
      }
    }
  }
})

启用了命名空间的 getter 和 action 会收到局部化的 getter,dispatch 和 commit。换言之,你在使用模块内容(module assets)时不需要在同一模块内额外添加空间名前缀。更改 namespaced 属性后不需要修改模块内的代码。

#在带命名空间的模块内访问全局内容(Global Assets)

如果你希望使用全局 state 和 getter,rootState 和 rootGetters 会作为第三和第四参数传入 getter,也会通过 context 对象的属性传入 action。

若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。

modules: {
  foo: {
    namespaced: true,

    getters: {
      // 在这个模块的 getter 中,`getters` 被局部化了
      // 你可以使用 getter 的第四个参数来调用 `rootGetters`
      someGetter (state, getters, rootState, rootGetters) {
        getters.someOtherGetter // -> 'foo/someOtherGetter'
        rootGetters.someOtherGetter // -> 'someOtherGetter'
      },
      someOtherGetter: state => { ... }
    },

    actions: {
      // 在这个模块中, dispatch 和 commit 也被局部化了
      // 他们可以接受 `root` 属性以访问根 dispatch 或 commit
      someAction ({ dispatch, commit, getters, rootGetters }) {
        getters.someGetter // -> 'foo/someGetter'
        rootGetters.someGetter // -> 'someGetter'

        dispatch('someOtherAction') // -> 'foo/someOtherAction'
        dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'

        commit('someMutation') // -> 'foo/someMutation'
        commit('someMutation', null, { root: true }) // -> 'someMutation'
      },
      someOtherAction (ctx, payload) { ... }
    }
  }
}

#在带命名空间的模块注册全局 action

若需要在带命名空间的模块注册全局 action,你可添加 root: true,并将这个 action 的定义放在函数 handler 中。例如:

{
  actions: {
    someOtherAction ({dispatch}) {
      dispatch('someAction')
    }
  },
  modules: {
    foo: {
      namespaced: true,

      actions: {
        someAction: {
          root: true,
          handler (namespacedContext, payload) { ... } // -> 'someAction'
        }
      }
    }
  }
}

#带命名空间的绑定函数

当使用 mapState, mapGetters, mapActions 和 mapMutations 这些函数来绑定带命名空间的模块时,写起来可能比较繁琐:

computed: {
  ...mapState({
    a: state => state.some.nested.module.a,
    b: state => state.some.nested.module.b
  })
},
methods: {
  ...mapActions([
    'some/nested/module/foo', // -> this['some/nested/module/foo']()
    'some/nested/module/bar' // -> this['some/nested/module/bar']()
  ])
}

对于这种情况,你可以将模块的空间名称字符串作为第一个参数传递给上述函数,这样所有绑定都会自动将该模块作为上下文。于是上面的例子可以简化为:

computed: {
  ...mapState('some/nested/module', {
    a: state => state.a,
    b: state => state.b
  })
},
methods: {
  ...mapActions('some/nested/module', [
    'foo', // -> this.foo()
    'bar' // -> this.bar()
  ])
}

而且,你可以通过使用 createNamespacedHelpers 创建基于某个命名空间辅助函数。它返回一个对象,对象里有新的绑定在给定命名空间值上的组件绑定辅助函数:

import { createNamespacedHelpers } from 'vuex'

const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')

export default {
  computed: {
    // 在 `some/nested/module` 中查找
    ...mapState({
      a: state => state.a,
      b: state => state.b
    })
  },
  methods: {
    // 在 `some/nested/module` 中查找
    ...mapActions([
      'foo',
      'bar'
    ])
  }
}

#给插件开发者的注意事项

如果你开发的插件(Plugin)提供了模块并允许用户将其添加到 Vuex store,可能需要考虑模块的空间名称问题。对于这种情况,你可以通过插件的参数对象来允许用户指定空间名称:

// 通过插件的参数对象得到空间名称
// 然后返回 Vuex 插件函数
export function createPlugin (options = {}) {
  return function (store) {
    // 把空间名字添加到插件模块的类型(type)中去
    const namespace = options.namespace || ''
    store.dispatch(namespace + 'pluginAction')
  }
}

#模块动态注册

在 store 创建之后,你可以使用 store.registerModule 方法注册模块:

// 注册模块 `myModule`
store.registerModule('myModule', {
  // ...
})
// 注册嵌套模块 `nested/myModule`
store.registerModule(['nested', 'myModule'], {
  // ...
})

之后就可以通过 store.state.myModule 和 store.state.nested.myModule 访问模块的状态。

模块动态注册功能使得其他 Vue 插件可以通过在 store 中附加新模块的方式来使用 Vuex 管理状态。例如,vuex-router-sync 插件就是通过动态注册模块将 vue-router 和 vuex 结合在一起,实现应用的路由状态管理。

你也可以使用 store.unregisterModule(moduleName) 来动态卸载模块。注意,你不能使用此方法卸载静态模块(即创建 store 时声明的模块)。

#保留 state

在注册一个新 module 时,你很有可能想保留过去的 state,例如从一个服务端渲染的应用保留 state。你可以通过 preserveState 选项将其归档:store.registerModule('a', module, { preserveState: true })。

当你设置 preserveState: true 时,该模块会被注册,action、mutation 和 getter 会被添加到 store 中,但是 state 不会。这里假设 store 的 state 已经包含了这个 module 的 state 并且你不希望将其覆写。

#模块重用

有时我们可能需要创建一个模块的多个实例,例如:

如果我们使用一个纯对象来声明模块的状态,那么这个状态对象会通过引用被共享,导致状态对象被修改时 store 或模块间数据互相污染的问题。

实际上这和 Vue 组件内的 data 是同样的问题。因此解决办法也是相同的——使用一个函数来声明模块状态(仅 2.3.0+ 支持):

const MyReusableModule = {
  state () {
    return {
      foo: 'bar'
    }
  },
  // mutation, action 和 getter 等等...
}

 

项目结构

Vuex 并不限制你的代码结构。但是,它规定了一些需要遵守的规则:

  1. 应用层级的状态应该集中到单个 store 对象中。

  2. 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。

  3. 异步逻辑都应该封装到 action 里面。

只要你遵守以上规则,如何组织代码随你便。如果你的 store 文件太大,只需将 action、mutation 和 getter 分割到单独的文件。

对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。下面是项目结构示例:

├── index.html
├── main.js
├── api
│   └── ... # 抽取出API请求
├── components
│   ├── App.vue
│   └── ...
└── store
    ├── index.js          # 我们组装模块并导出 store 的地方
    ├── actions.js        # 根级别的 action
    ├── mutations.js      # 根级别的 mutation
    └── modules
        ├── cart.js       # 购物车模块
        └── products.js   # 产品模块

 

插件

在 Scrimba 上尝试这节课

Vuex 的 store 接受 plugins 选项,这个选项暴露出每次 mutation 的钩子。Vuex 插件就是一个函数,它接收 store 作为唯一参数:

const myPlugin = store => {
  // 当 store 初始化后调用
  store.subscribe((mutation, state) => {
    // 每次 mutation 之后调用
    // mutation 的格式为 { type, payload }
  })
}

然后像这样使用:

const store = new Vuex.Store({
  // ...
  plugins: [myPlugin]
})

#在插件内提交 Mutation

在插件中不允许直接修改状态——类似于组件,只能通过提交 mutation 来触发变化。

通过提交 mutation,插件可以用来同步数据源到 store。例如,同步 websocket 数据源到 store(下面是个大概例子,实际上 createPlugin 方法可以有更多选项来完成复杂任务):

export default function createWebSocketPlugin (socket) {
  return store => {
    socket.on('data', data => {
      store.commit('receiveData', data)
    })
    store.subscribe(mutation => {
      if (mutation.type === 'UPDATE_DATA') {
        socket.emit('update', mutation.payload)
      }
    })
  }
}
const plugin = createWebSocketPlugin(socket)

const store = new Vuex.Store({
  state,
  mutations,
  plugins: [plugin]
})

#生成 State 快照

有时候插件需要获得状态的“快照”,比较改变的前后状态。想要实现这项功能,你需要对状态对象进行深拷贝:

const myPluginWithSnapshot = store => {
  let prevState = _.cloneDeep(store.state)
  store.subscribe((mutation, state) => {
    let nextState = _.cloneDeep(state)

    // 比较 prevState 和 nextState...

    // 保存状态,用于下一次 mutation
    prevState = nextState
  })
}

生成状态快照的插件应该只在开发阶段使用,使用 webpack 或 Browserify,让构建工具帮我们处理:

const store = new Vuex.Store({
  // ...
  plugins: process.env.NODE_ENV !== 'production'
    ? [myPluginWithSnapshot]
    : []
})

上面插件会默认启用。在发布阶段,你需要使用 webpack 的 DefinePlugin 或者是 Browserify 的 envify 使 process.env.NODE_ENV !== 'production' 为 false。

#内置 Logger 插件

如果正在使用 vue-devtools,你可能不需要此插件。

Vuex 自带一个日志插件用于一般的调试:

import createLogger from 'vuex/dist/logger'

const store = new Vuex.Store({
  plugins: [createLogger()]
})

createLogger 函数有几个配置项:

const logger = createLogger({
  collapsed: false, // 自动展开记录的 mutation
  filter (mutation, stateBefore, stateAfter) {
    // 若 mutation 需要被记录,就让它返回 true 即可
    // 顺便,`mutation` 是个 { type, payload } 对象
    return mutation.type !== "aBlacklistedMutation"
  },
  transformer (state) {
    // 在开始记录之前转换状态
    // 例如,只返回指定的子树
    return state.subTree
  },
  mutationTransformer (mutation) {
    // mutation 按照 { type, payload } 格式记录
    // 我们可以按任意方式格式化
    return mutation.type
  },
  logger: console, // 自定义 console 实现,默认为 `console`
})

日志插件还可以直接通过 <script> 标签引入,它会提供全局方法 createVuexLogger。

要注意,logger 插件会生成状态快照,所以仅在开发环境使用。

严格模式

开启严格模式,仅需在创建 store 的时候传入 strict: true:

const store = new Vuex.Store({
  // ...
  strict: true
})

在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。

#开发环境与发布环境

不要在发布环境下启用严格模式!严格模式会深度监测状态树来检测不合规的状态变更——请确保在发布环境下关闭严格模式,以避免性能损失。

类似于插件,我们可以让构建工具来处理这种情况:

const store = new Vuex.Store({
  // ...
  strict: process.env.NODE_ENV !== 'production'
})

 

表单处理

在 scrimba 上尝试这节课

当在严格模式中使用 Vuex 时,在属于 Vuex 的 state 上使用 v-model 会比较棘手:

<input v-model="obj.message">

假设这里的 obj 是在计算属性中返回的一个属于 Vuex store 的对象,在用户输入时,v-model 会试图直接修改 obj.message。在严格模式中,由于这个修改不是在 mutation 函数中执行的, 这里会抛出一个错误。

用“Vuex 的思维”去解决这个问题的方法是:给 <input> 中绑定 value,然后侦听 input 或者 change 事件,在事件回调中调用 action:

<input :value="message" @input="updateMessage">
// ...
computed: {
  ...mapState({
    message: state => state.obj.message
  })
},
methods: {
  updateMessage (e) {
    this.$store.commit('updateMessage', e.target.value)
  }
}

下面是 mutation 函数:

// ...
mutations: {
  updateMessage (state, message) {
    state.obj.message = message
  }
}

#双向绑定的计算属性

必须承认,这样做比简单地使用“v-model + 局部状态”要啰嗦得多,并且也损失了一些 v-model 中很有用的特性。另一个方法是使用带有 setter 的双向绑定计算属性:

<input v-model="message">
// ...
computed: {
  message: {
    get () {
      return this.$store.state.obj.message
    },
    set (value) {
      this.$store.commit('updateMessage', value)
    }
  }
}

 

vue3知识点7 vue3.0+cli4.5 vuex vuex安装配置 state mutations actions modules命名空间 getters 本文详解了vue3.0+vue-cli4.5的vuex中各种属性的用法。state mulations actions modules getters等。 阅读详情

相关推荐

vue-cli-plugin-modular-vuex:为Vue CLI 3插件创建模块化Vuex存储

vue-cli-plugin-模块化vuex 为创建模块化Vuex存储 安装 如果尚未安装vue-cli 3,请先按照此处的安装说明进行操作: : 提示:如果由于仍然需要vue init而不想覆盖当前的vue-cli,请。 使用vue-cli 3.0生成项目 vue create my-app 在安装模块化vuex插件之前,请确保提交或存储所做的更改,以防您需要还原 要安装模块化vuex插件... cd my-app vue add vuex // if you haven't selected to add vuex during the vue create stage vue add modular-vuex 用法 调用以生成新的商店模块 vue invoke modular-vuex 与其他插件一起使用 电子-Vuetify 只需添加和 vue add vu

vuex的用法(含vue-cli的安装与使用)

1.什么是vuex? vuex是使用vue中必不可少的一部分,基于父子、兄弟组件,我们传值可能会很方便,但是如果是没有关联的组件之间要使用同一组数据,就显得很无能为力,那么vuex就很好的解决了我们这种问题,它相当于一个公共仓库,保存着所有组件都能共用的数据。 2.什么是vue-cli? 脚手架: vue-cli :vue脚手架 帮你提供好基本项目结构 本身集成很多项目模板: simple 基本没用 webpack 可以使用(大型项目) Eslint 检查代码规范, 单元测试 webpack-simp

wangming2531的博客 479

Jenkins+docker 微服务实现自动化部署安装和部署过程

本文详细介绍了如何使用Docker部署Jenkins自动化服务器。主要内容包括:1)拉取Jenkins官方或BlueOcean镜像;2)创建容器并配置端口映射、数据卷挂载;3)设置防火墙规则;4)配置清华大学镜像加速;5)安装必要插件;6)SSH密钥配置;7)构建触发器设置;8)编写自动化构建脚本。通过Docker部署Jenkins可以简化安装流程,确保环境一致性,并利用容器特性实现快速启动和管理。文章提供了完整的配置步骤和注意事项,帮助用户快速搭建CI/CD环境。

qq_33665793的博客 1687

Vue:vuex

1、vue插件vuex 是实现数据集中式状态管理的插件。数据由 vuex 统一管理。其它组件都去使用 vuex 中的数据。只要有其中一个组件去修改了这个共享的数据,其它组件会同步更新。

islunatic的博客 2929

告别理论劝退:用动画和Tanner图轻松理解QC-LDPC的译码原理(BP算法详解)

本文通过动画和Tanner图直观解析QC-LDPC码的BP译码原理,帮助读者轻松理解802.11ac协议中的编译码过程。文章详细展示了QC-LDPC的结构之美、BP算法的动态信息流动以及LLR的视觉化解读,并对比了硬判决算法的性能差异,为开发者和研究者提供了实用的可视化工具开发建议。

weixin_30411239的博客 492

企业网络架构设计:从内网到外网的无缝通信方案

本文详细解析了企业网络架构设计中的关键技术与实践方案,重点介绍了VLAN划分、OSPF路由优化、安全策略及无线网络集成等核心内容。通过OSPF多区域部署和链路聚合技术,实现内网到外网的无缝通信,提升企业网络性能与安全性。文章还提供了具体的配置示例和最佳实践,助力企业构建高效可靠的网络架构。

weixin_28331555的博客 623

引入Vuex的步骤

引入Vuex的步骤

weixin_55761900的博客 458

告别环境配置噩梦:用Docker Desktop + WSL2在Windows上5分钟搞定vLLM运行环境

本文详细介绍了如何在Windows系统上使用Docker Desktop和WSL2快速搭建vLLM开发环境,5分钟内完成配置。通过容器化技术解决传统环境配置中的依赖冲突、环境污染等问题,提供一键复用的高效方案,特别适合AI开发者快速部署和测试vLLM框架。

weixin_28728495的博客 502

vue-cli安装与使用和vuex使用

VUE-cli 安装与使用 安装步骤: 安装nodejs环境:地址:https://nodejs.org 一般情况选择第一个稳定版本下载使用即可 安装vue-cli的dos命令: 第一步:npm install -g vue-cli–&gt;装上vue脚手架 第二步:创建并使用脚手架:vue init webpack my-project-----&gt;ynnn 第三步...

knowledge_bird的博客 1867

2.ROS实用工具:坐标变换

本文围绕ROS坐标变换展开,介绍其在机器人系统中的关键作用,即统一不同传感器和执行器坐标系,服务数据融合等操作。基于ROS的tf库,从广播和监听TF变换两方面阐述实现过程,涵盖新建工作包、编写广播和监听代码、配置构建文件及编译等步骤。此外,介绍启动节点管理器后运行广播和监听节点的方法,并通过rqt_graph、rqt_tf_tree、tf_echo等工具可视化和获取坐标系变换信息。借助这些内容,读者不仅能掌握ROS坐标变换的实现,还能对机器人坐标变换系统的调试和理解有更深入认识 。

qq_74168740的博客 1173

YOLOv11 改进 - 特征融合 | 替换 C3k2 涨点:GELAN 融合 CSP+ELAN 提精度

本文介绍了可编程梯度信息(PGI)和广义高效层聚合网络(GELAN)与 YOLOv11 的结合,以解决深度网络数据传输时的信息丢失问题。PGI 能为目标任务提供完整输入信息,计算目标函数以更新网络权重。GELAN 作为轻量级网络架构,由 SPPELAN、ELAN1、RepNCSPELAN4 等模块组成。我们将 GELAN 代码集成进 YOLOv11, 实验脚本显示,结合 GELAN 的 YOLOv11 在 MS COCO 数据集目标检测任务中或有良好表现。

魔改工程师的博客 1242

vue-router、vue-cli、vuex在cmd下快速安装使用

vue-router、vue-cli、vuex在cmd下快速安装使用vue-router安装配置及使用路由vue-cli安装配置vuex安装使用对State、Getter、Mutation、Action、Module的理解使用辅助函数...mapGetters和...mapActions vue-router 安装 a. cmd切换盘符到当前项目的文件夹下 b. 安装路由模块 npm inst...

Duktig的博客 1366

机器人常用坐标系详解:原理、获取方法及实战实例

本文系统阐述了机器人四大核心坐标系(世界、基、工具、工件)的原理与标定方法。世界坐标系提供全局参考基准,基坐标系绑定机器人本体,工具坐标系定义末端执行器位置,工件坐标系则锁定作业对象位置。通过齐次变换矩阵实现各坐标系间的关联转换。重点介绍了三类标定技术:手动设定法(世界坐标系)、三点/六点法(工具TCP标定)和视觉识别法(工件标定),并以工业机械臂上下料为例演示了完整应用流程。随着技术发展,自动化标定、动态坐标系等新趋势将进一步提升机器人作业精度与效率。

start_up_go的博客 513

安装vue-cli、vuex

npm/cnpm install vue-cli -g npm/cnpm uninstall vue-cli -g 不要用分号,不然会报错 卸载命令 vue -V 如果已经安装,不需要执行上面的命令,可以通过这句话来查看vue版本 vue init webpack my-project如果原本安装的vue-cli出现问题,可以卸载后再重装。npm install vuex -S这里需要注意的...

spfLinux的博客 618

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

vue-cli安装scss,element-ui,md5,vuex

vue-cli安装scss,element-ui,md5,vuex scss: cnpm install node-sass -D npm install sass-loader -D vue.config.js加上: pluginOptions: { 'style-resources-loader': { preProcessor: 'sass', patterns: [ path.resolve(__dirname, './src/styles/common.scss') //

Nancy617的博客 407

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

vue3.0cli+安装使用vuex

安装vuex 项目目录下打开命令行工具输入如下命令安装vuex npm install vuex --save 使用vuex 在开发目录(src目录)中新建一个名为store的文件夹 store下新建index.js进行配置vuex模块 store下新建vuex模块 userinfo.js是我们配置的vuex模块 index.js import Vue from 'vue' //引用vue i...

meis27461的博客 1376

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Vue-CLI入门(webpack入门、安装配置Vue-CLI(命令、手动、自动版本)、使用Vue-CLI创建组件和Vuex和Vue-router、配置跨域请求数据以及配置webpack添加插件等)

目录 webpack入门链接 Vue-CLI介绍 安装配置Vue-CLI 全局安装命令 自动版本 手动版本 运行和打包项目 使用Vue-CLI 创建子组件 使用Vuex 使用Vue-router 修改webpack配置 Vue-CLI封装的webpack配置属性链接 配置反向代理(跨域请求数据) 添加webpack中插件 webpack插件链接 封装自定义插件 保存自动格式化代码配置 webpack入门链接 webpack使用入门(配置loader:style、css

AIWWY的博客 1835

Vuex的安装与文件基础格式(vue-cli2)

这里对应的脚手架版本是(vue-cli2) 安装:npm install --save vuex@3 删除:npm uninstall vue-route store文件夹里的index.js(基本格式) import Vue from 'vue'; import Vuex from 'vuex' Vue.use(Vuex); const store = new Vuex.Store({ state: { }, mutations: { }, actions: {

dumpling_wrapper的博客 227

coderwhy-vue学习

(新)2019Vue、Vuejs最详细教程-入门到项目实战 一、邂逅Vuejs 1、认识Vuejs 1.1 简单认识一下Vuejs Vue (读音 /vjuː/,类似于 view),不要读错。 Vue是一个渐进式的框架,什么是渐进式的呢? 渐进式意味着你可以将Vue作为你应用的一部分嵌入其中,带来更丰富的交互体验。 或者如果你希望将更多的业务逻辑使用Vue实现,那么Vue的核心库以及其生态系统...

xieanna123的博客 8485

JSDoc-VueJS 开源项目教程

JSDoc-VueJS 开源项目教程 项目介绍 JSDoc-VueJS 是一个开源项目,旨在为 Vue.js 组件生成文档。通过结合 JSDoc 和 Vue.js,开发者可以为他们的 Vue 组件编写详细的文档,从而提高代码的可维护性和可读性。该项目支持 Vue 2 和 Vue 3,并且易于集成到现有的 Vue 项目中。 项目快速启动 安装 首先,你需要在你的项目中安装 JSDoc 和 JSDoc...

gitblog_00689的博客 486

【前端28_Vue-Cli 脚手架】萌新指南、安装脚手架、创建项目、项目目录介绍、路由重定向、路由守卫、Vuex、代码规范ESlint、常用组件:Element、Vue-Axios

Vue-cli 脚手架 介绍 Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统。 就是说我们在开发的时候,前期需要配置很多东西(网络组件,路由组件,打包组件等等),有了Vue-cli脚手架,他会帮我们集成这些功能 安装 可以通过以下命令,在命令行里敲 npm install -g @vue/cli # OR yarn global add @vue/cli 创建一个项目 创建项目有两种方法1. 代码2. 图形界面GUI 代码创建 找到想要创建项目的文件夹,在此文件夹下打开cmd,(按住s

Lovely Ruby 的手账 636

vue vuex 挂载_vuex 笔记—vue-cli和router使用vuex

vuex 笔记—vue-cli和router使用vuexVuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。安装vuex#以下三个方...

weixin_28756005的博客 227

Vue CLI、Vue Router、Vuex的使用

Vue CLI、Vue Router、Vuex的使用 1. vue-cli(vue脚手架)创建项目 1.1 关于旧版本 Vue CLI 的包名称由 vue-cli 改成了 @vue/cli。 如果你已经全局安装了旧版本的 vue-cli (1.x 或 2.x),你需要先通过 npm uninstall vue-cli -g 或 yarn global remove vue-cli 卸载它。 1.2 Node 版本要求 Vue CLI 4.x 需要 Node.js v8.9 或更高版本 (推荐 v10

qq_46178261的博客 758

vue-cli2安装vuex出现版本适配问题,降vuex版本。已解决

vuex是官方提供的一个插件,状态管理库,集中式管理项目中组件公用的数据。使用于大项目、组件和模块过多的时候来管理数据。安装时可能会出现的问题:系统报错 此处安装环境为vue2出现了版本问题 这边修改安装3版本即可。//我们在store中index.js文件中配置相应处理。ommit} actions可以处理异步。vue2 安装vuex@3.6.2 解决此问题。//此处不能直接修改mapstate。

qq_51283497的博客 548

一文包你明白!Vue CLI 3搭建vue+vuex 最全分析

个人博客导航页(点击右侧链接即可打开个人博客):大牛带你入门技术栈 一、介绍 Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统。有三个组件: CLI:@vue/cli全局安装的 npm 包,提供了终端里的vue命令(如:vue create 、vue serve 、vue ui 等命令) CLI 服务:@vue/cli-service是一个开发环境依赖。构建于we...

weixin_41663412的博客 575
上一篇: 怎么解决跨域
下一篇: 高斯模糊背景图
春风欲雨
博客等级 码龄7年 68粉丝 106原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值