todolist demo

最近有空重新看了一下vuex,然后又写了一个todolist小demo,原理比较简单,主要是自己规范了一下代码的写法.
gitee地址 : https://gitee.com/darcrandex/...

效果图

图片描述

根组件

<template>
  <div class='container'>
    <h1 class='title'>todo list demo</h1>
    <type-filter
      :types='types'
      :filter='filter'
      :handleUpdateFilter='handleUpdateFilter'
    />
    <add-todo :handleAdd='handleAdd' />
    <todo-item
      v-for='(item,index) in list'
      :key='item.id'
      :index='index'
      :data='item'
      :filter='filter'
      :handleRemove='handleRemove'
      :handleToggle='handleToggle'
    />
  </div>
</template>

<script>
import { createNamespacedHelpers } from 'vuex'
import TypeFilter from './filter'
import AddTodo from './addTodo'
import TodoItem from './item'

const { mapState, mapMutations } = createNamespacedHelpers('TodoList')
export default {
  name: 'todo-list-demo',
  components: { TypeFilter, TodoItem, AddTodo },
  computed: {
    ...mapState(['list', 'types', 'filter'])
  },
  methods: {
    ...mapMutations([
      'handleAdd',
      'handleRemove',
      'handleToggle',
      'handleUpdateFilter'
    ])
  }
}
</script>

<style lang='scss' scoped>
@import './style.scss';
</style>

过滤条件组件

<template>
  <ul class='types'>
    <li
      v-for='(item,index) in types'
      :key='index + item'
      :class='filterClass(item)'
      @click='handleUpdateFilter(item)'
    >{{item}}</li>
  </ul>
</template>

<script>
export default {
  name: 'type-filter',
  props: ['types', 'filter', 'handleUpdateFilter'],
  methods: {
    filterClass(filter) {
      return { filter: true, active: filter === this.filter }
    }
  }
}
</script>

<style lang='scss' scoped>
@import './style.scss';
</style>

添加待办组件

<template>
  <input
    type='text'
    name='add-todo'
    id='add-todo-input'
    class='add-todo'
    @keyup.enter='add'
    placeholder='input then hit enter'
  />
</template>

<script>
export default {
  name: 'add-todo',
  props: ['handleAdd'],
  methods: {
    add(e) {
      const val = e.target.value.trim()
      if (val) {
        this.handleAdd({
          id: new Date().getTime(),
          message: val,
          status: false
        })
        e.target.value = ''
      }
    }
  }
}
</script>

<style lang='scss' scoped>
@import './style.scss';
</style>

单个待办事项组件

<template>
  <p v-if='show' class='todo-item'>
    <span
      :class='messageClass(data.status)'
      @click='handleToggle(data.id)'
    >{{index+1}}. {{data.message}}<i class='date'>{{dateFormat(data.id)}}</i></span>
    <span
      class='delete'
      @click='handleRemove(data.id)'
    >Delete</span>
  </p>
</template>

<script>
export default {
  name: 'todo-items',
  props: ['data', 'filter', 'index', 'handleRemove', 'handleToggle'],
  computed: {
    show() {
      return (
        this.filter === 'ALL' ||
        (this.filter === 'UNDO' && !this.data.status) ||
        (this.filter === 'DONE' && this.data.status)
      )
    }
  },
  methods: {
    dateFormat(time) {
      const date = new Date(time)
      return `(${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()})`
    },
    messageClass: status => ({ message: true, done: status })
  }
}
</script>

<style lang='scss' scoped>
@import './style.scss';
</style>

vuex部分(模块)

const state = {
  list: [],
  types: ['ALL', 'UNDO', 'DONE'],
  filter: 'ALL'
}
const mutations = {
  handleAdd(state, item) {
    state.list = [...state.list, item]
  },
  handleRemove(state, id) {
    state.list = state.list.filter(obj => obj.id !== id)
  },
  handleToggle(state, id) {
    state.list = state.list.map(
      obj => (obj.id === id ? { ...obj, status: !obj.status } : obj)
    )
  },
  handleUpdateFilter(state, filter) {
    state.filter = filter
  }
}
export default {
  namespaced: true,
  state,
  mutations
}

darcrand
637 声望20 粉丝