diff --git a/src/programming/java/框架/测试.md b/src/programming/java/框架/测试.md new file mode 100644 index 0000000..380a38c --- /dev/null +++ b/src/programming/java/框架/测试.md @@ -0,0 +1,296 @@ + + + +# Vuex + +## 1. 安装 + +```bash +npm install vuex --save +``` + +## 2. 开始 + +1. Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器 + 1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新 + 2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地**提交mutation** + +## 3. state + +### 1. 单一状态树 + +1. Vuex使用**单一状态树**—一个对象就包含了全部的应用层级状态(意味着每个应用将仅仅包含一个 store 实例) + +### 2. 在 Vue 组件中获得 Vuex 状态 + +>Vuex 通过 `store` 选项,提供了一种机制将状态从根组件“注入”到每一个子组件中(需调用 `Vue.use(Vuex)`): + +```vue +const app = new Vue({ + el: '#app', + // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件 + store, + components: { Counter }, + template: ` +
+ +
+ ` +}) +``` + +>this.$store可以访问 store 实例 + +```vue +const Counter = { + template: `
{{ count }}
`, + computed: { + count () { + return this.$store.state.count + } + } +} +``` + +### 3. `mapState` 辅助函数 + +>当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 `mapState` 辅助函数帮助我们生成计算属性,让你少按几次键: + +```vue +// 在单独构建的版本中辅助函数为 Vuex.mapState +import { mapState } from 'vuex' + +export default { + // ... + computed: mapState({ + // 箭头函数可使代码更简练 + count: state => state.count, + + // 传字符串参数 'count' 等同于 `state => state.count` + countAlias: 'count', + + // 为了能够使用 `this` 获取局部状态,必须使用常规函数 + countPlusLocalState (state) { + return state.count + this.localCount + } + }) +} +``` + +>当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 `mapState` 传一个字符串数组 + +```vue +computed: mapState([ + // 映射 this.count 为 store.state.count + 'count' +]) +``` + +### 4. 对象展开运算符 + +>使用对象展开运算符与局部计算属性混合使用,因为mapState返回的是一个对象,所以吧mapState和computed合并即可 + +```tex +computed: { + localComputed () { /* ... */ }, + // 使用对象展开运算符将此对象混入到外部对象中 + ...mapState({ + // ... + }) +} +``` + +### 5. 组件仍然保有局部状态 + +>使用 Vuex 并不意味着你需要将**所有的**状态放入 Vuex。虽然将所有的状态放到 Vuex 会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态。你应该根据你的应用开发需要进行权衡和确定。 + +## 4. Getter + +>有时候我们需要使用state计算一些值,而且需要在其它组件使用,要么复制这个函数,或者抽取到一个共享函数然后在多处导入它 +> +>例如对列表进行过滤并计数: + +```vue +computed: { + doneTodosCount () { + return this.$store.state.todos.filter(todo => todo.done).length + } +} +``` + +>解决方案 +> +>Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。 +> +>Getter 接受 state 作为其第一个参数: + +```vue +const store = new Vuex.Store({ + state: { + todos: [ + { id: 1, text: '...', done: true }, + { id: 2, text: '...', done: false } + ] + }, + getters: { + doneTodos: state => { + return state.todos.filter(todo => todo.done) + } + } +}) +``` + +### 1. 通过属性访问 + +```tex +1. 声明 +const store = new Vuex.Store({ + state: { + todos: [ + { id: 1, text: '...', done: true }, + { id: 2, text: '...', done: false } + ] + }, + //相当于计算属性只是对于state的计算 + getters: { + doneTodos: state => { + return state.todos.filter(todo => todo.done); + }, + doneTodosCount: (state, getters) => { + return getters.doneTodos.length + }, + getTodoById: (state) => (id) => { + return state.todos.find(todo => todo.id === id) + } + } +}) + +2. 调用 +store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }] +store.getters.doneTodosCount // -> 1 +组件中 +this.$store.getters.doneTodosCount +``` + +### 2. 通过方法访问 + +```tex +1.声明一个方法 +getters: { + // ... + getTodoById: (state) => (id) => { + return state.todos.find(todo => todo.id === id) + } +} + +2. 使用该方法 +store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false } +``` + +### 3. `mapGetters` 辅助函数 + +```vue +import { mapGetters } from 'vuex' + +export default { + // ... + computed: { + // 使用对象展开运算符将 getter 混入 computed 对象中 + ...mapGetters([ + 'doneTodosCount', + 'anotherGetter', + // ... + ]) + } +} + +...mapGetters({ + // 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount` + doneCount: 'doneTodosCount' +}) +``` + +## 5. Mutation + +>更改 Vuex 的 store 中的状态的唯一方法是提交 mutation +> +>Mutation 必须是同步函数 + +```vue +const store = new Vuex.Store({ + state: { + count: 1 + }, + mutations: { + increment (state) { + // 变更状态 + state.count++ + } + } +}) + +store.commit('increment') +``` + +### 1. 传入参数方式1 + +>你可以向 `store.commit` 传入额外的参数,即 mutation 的 **载荷(payload)**: +> +>在大多数情况下,载荷应该是一个对象,这样可以包含多个字段并且记录的 mutation 会更易读: + +```vue +// ... +mutations: { + increment (state, payload) { + state.count += payload.amount + } +} + +store.commit('increment', { + amount: 10 +}) +``` + +### 2. 对象风格的提交方式 + +>当使用对象风格的提交方式,整个对象都作为载荷传给 mutation 函数,因此 handler 保持不变: + +```tex +1. 函数不变 +mutations: { + increment (state, payload) { + state.count += payload.amount + } +} + +2. 对象提交方式 +store.commit({ + type: 'increment', + amount: 10 +}) +``` + +### 3. `mapMutations` 辅助函数 + +```tex +import { mapMutations } from 'vuex' + +export default { + // ... + methods: { + ...mapMutations([ + 'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')` + + // `mapMutations` 也支持载荷: + 'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)` + ]), + ...mapMutations({ + add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')` + }) + } +``` + + + +## 6.Action +