zoukankan      html  css  js  c++  java
  • [Vuex] Use Namespaces in Vuex Stores using TypeScript

    Even by using modules, they still share the same namespace. So you couldn’t have the same mutation name in different modules. Namespaces solve that by prepending the path of the module to the StateGetterAction, and Mutation.

    This lesson shows how to use namespaces in Vuex modules with TypeScript.

    Enable namespaced to each feature store:

    import {GetterTree, MutationTree, Module} from 'vuex';
    import {TodosState, RootState} from '../types';
    import {Todo} from '../types';
    
    const state: TodosState = {
        todos: [
            {text: 'Buy milk', checked: false},
            {text: 'Learning', checked: true},
            {text: 'Algorithom', checked: false},
        ],
    };
    
    const getters: GetterTree<TodosState, RootState> = {
        todos: (state, getters, rootState) => state.todos.filter(t => !t.checked),
        dones: (state, getters, rootState) => state.todos.filter(t => t.checked)
    };
    
    const mutations: MutationTree<TodosState> = {
        addTodo(state, newTodo) {
            const copy = {
                ...newTodo
            };
            state.todos.push(copy);
        },
        toggleTodo(TodosState, todo) {
            todo.checked = !todo.checked;
        }
    };
    
    const actions: ActionTree<TodosState, RootState> = {
        addTodoAsync(context, id) {
            fetch('https://jsonplaceholder.typicode.com/posts/'+id)
                .then(data => data.json())
                .then(item => {
                    const todo: Todo = {
                        checked: false,
                        text: context.rootState.login.user + ': ' + item.title
                    }
    
                    context.commit('addTodo', todo);
                })
        }
    }
    
    export const todos: Module<TodosState, RootState> = {
        actions,
        state,
        mutations,
        getters,
        namespaced: true
    };

    Now we need to modify the component to adopt the namespace:

    <template>
    <section>
        <h4>Todos</h4>
        <ul>
          <li v-for="todo in todos">
            <input type="checkbox" :checked="todo.checked" @change="toggleTodo(todo)">
            {{ todo.text }}
          </li>
        </ul>
        <h4>Done</h4>
        <ul>
          <li v-for="todo in dones">
            <input type="checkbox" :checked="todo.checked" @change="toggleTodo(todo)">
            {{ todo.text }}
          </li>
        </ul>
        <p>
          <label for="">
            Add todo:
            <input type="text" v-model="newTodo.text" @keyup.enter="addTodo(newTodo)">
          </label>
          <label for="">
            Add todo async:
            <input type="text" v-model="id" @keyup.enter="addTodoAsync(id)">
          </label>
    
        </p>
    </section>
    </template>
    
    <script lang="ts">
    import {Component, Vue} from 'vue-property-decorator';
    import {Action, State, Getter, Mutation, namespace} from 'vuex-class';
    import {TodosState, Todo} from '../types';
    
    const TodoGetter = namespace('todos', Getter);
    const TodoAction = namespace('todos', Action);
    const TodoMutation = namespace('todos', Mutation);
    
    @Component({
    })
    export default class Todos extends Vue {
        @TodoGetter todos: TodosState;
        @TodoGetter dones: TodosState;
    
        @TodoMutation addTodo;
        @TodoMutation toggleTodo;
        @TodoAction addTodoAsync;
    
        newTodo: Todo = {
          text: '',
          checked: false
        }
    
        id: string = '1';
    }
    </script>

    If we want to trigger a different namesapce state update from Todo State, we can do it in action:

    const actions: ActionTree<TodosState, RootState> = {
        addTodoAsync(context, id) {
            fetch('https://jsonplaceholder.typicode.com/posts/'+id)
                .then(data => data.json())
                .then(item => {
                    const todo: Todo = {
                        checked: false,
                        text: context.rootState.login.user + ': ' + item.title
                    }
    
                    context.commit('addTodo', todo);
                    context.commit('login/login', null, {root: true}); // we have to say {root: true}, otherwise, it will look for the state under 'todos' namespace
                })
        }
    }

    Login mutation:

    const mutations: MutationTree<LoginState> = {
        login (state) {
            state.isLoggedIn = true;
            state.user =  'alice';
        }
    }
  • 相关阅读:
    Day 20 初识面向对象
    Day 16 常用模块
    Day 15 正则表达式 re模块
    D14 模块 导入模块 开发目录规范
    Day 13 迭代器,生成器,内置函数
    Day 12 递归,二分算法,推导式,匿名函数
    Day 11 闭包函数.装饰器
    D10 函数(二) 嵌套,命名空间作用域
    D09 函数(一) 返回值,参数
    Day 07 Day08 字符编码与文件处理
  • 原文地址:https://www.cnblogs.com/Answer1215/p/10789848.html
Copyright © 2011-2022 走看看