效果
实现
- 通过vue.cli脚手架创建项目
- 引入bulma库创建样式
- 引入vuex进行状态管理,最主要是向各个组件传输信息
- 使用时先下载.json中相关包npm i
- 输入npm start启动
代码
- todoApp.vue
<template>
<div class="todoApp" style="width:500px">
<article class="panel is-primary">
<todo-head />
<todo-input />
<todo-list />
<todo-foot />
</article>
</div>
</template>
<script>
import TodoFoot from './componentsTodo/todo-foot.vue'
import TodoHead from './componentsTodo/todo-head.vue'
import todoInput from './componentsTodo/todo-input.vue'
import TodoList from './componentsTodo/todo-list.vue'
export default {
components: {
todoInput, TodoList, TodoFoot, TodoHead },
name: 'todoApp'
}
</script>
<style lang="less" scoped>
.todoApp{
margin: 20px auto;
}
</style>
- componentsTodo文件下todo-head.vue
<template>
<div class="todo-head">
<div class="panel-heading">
<p class="title is-1 has-text-danger">添加待办事项</p>
<p class="subtitle is-3 has-text-danger">今日事,今日毕</p>
</div>
</div>
</template>
<script>
export default {
name: 'todo-head'
}
</script>
<style lang="less" scoped>
</style>
- componentsTodo文件下todo-list.vue
<template>
<div class="todo-list">
<ul v-if="todos.length > 0">
<todo-list-item v-for="todo in todos" :key="todo.id" :item="todo"/>
</ul>
<div v-else>请添加待办事项</div>
</div>
</template>
<script>
import todoListItem from './todo-list-item.vue'
export default {
components: {
todoListItem },
name: 'todo-list',
computed: {
todos () {
return this.$store.state.todos
}
}
}
</script>
<style lang="less" scoped>
</style>
- componentsTodo文件下todo-list-item.vue
<template>
<div class="todo-list-item">
<li>
<label>
<input
type="checkbox"
:checked="item.completed"
@change="changeHandle"
>
<span>{
{item.completed ? " 已" : " 未"}}完成 </span>
<span>{
{item.title}} </span>
</label>
<button @click="delSingleHandle">删除</button>
</li>
</div>
</template>
<script>
export default {
name: 'todo-list-item',
props: {
item: {
type: Object
}
},
methods: {
changeHandle () {
this.$store.commit('changSingle', {
id: this.item.id })
},
delSingleHandle () {
this.$store.commit('delSingle', {
id: this.item.id })
}
}
}
</script>
<style lang="less" scoped>
li {
margin-left: 10px;
}
li span{
font-size: 30px;
}
</style>
- componentsTodo文件下todo-foot.vue
<template>
<div class="todo-foot">
<label class="panel-inline">
<input
type="checkbox"
:checked="checkboxAllStatus"
@change="checkboxAllChang({statu: !checkboxAllStatus})"
>
全选
</label>
<span class="panel-inline">已完成{
{CompletedTodo}}项 一共{
{total}}项</span>
<div class="panel-block">
<button class="button is-primary is-outlined is-fullwidth" @click="clearAll">
清空所有事项
</button>
</div>
</div>
</template>
<script>
import {
mapGetters, mapMutations } from 'vuex'
export default {
name: 'todo-foot',
computed: {
...mapGetters(['total', 'CompletedTodo', 'checkboxAllStatus'])
},
methods: {
...mapMutations(['checkboxAllChang', 'clearAll'])
}
}
</script>
<style lang="less" scoped>
div{
margin-top: 10px;
}
</style>
- main.js入口配置
import Vue from 'vue'
import App from './todoApp.vue'
import store from './store'
import 'bulma/css/bulma.min.css'
Vue.config.productionTip = false
new Vue({
store,
render: h => h(App)
}).$mount('#app')
- store下的index.js配置文件
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
todos: []
},
getters: {
total (state) {
return state.todos.length
},
CompletedTodo (state) {
return state.todos.filter(item => item.completed).length
},
checkboxAllStatus (state) {
return state.todos.every(item => item.completed)
}
},
mutations: {
addTodoItem (state, payload) {
state.todos.push({
id: state.todos.length === 0 ? 0 : state.todos[state.todos.length - 1].id + 1,
title: payload.title,
completed: false
})
},
changSingle (state, payload) {
state.todos.forEach(item => {
if (item.id === payload.id) {
item.completed = !item.completed
}
})
},
delSingle (state, payload) {
state.todos = state.todos.filter(item => item.id !== payload.id)
},
checkboxAllChang (state, payload) {
state.todos.forEach(item => {
item.completed = payload.statu
})
},
clearAll (state) {
state.todos = []
}
}
})
export default store
- package.json配置包
{
"name": "project-name",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "npm run serve",
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"bulma": "^0.9.4",
"core-js": "^3.8.3",
"vue": "^2.6.14",
"vue-router": "^3.5.3",
"vuex": "^3.6.2"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"@vue/eslint-config-standard": "^6.1.0",
"eslint": "^7.32.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-vue": "^8.0.3",
"less": "^4.0.0",
"less-loader": "^8.0.0",
"vue-template-compiler": "^2.6.14"
}
}