功能展示
我认为重点部分是路由的代码直接奉上
···
// 该文件专门用于创建整个应用的路由器
// import { userSetter } from ‘core-js/fn/symbol’
import VueRouter from ‘vue-router’
// 引入组件
// import Todo from ‘…/components/TodoList.vue’
import Login from ‘…/components/Login.vue’
import User from ‘…/components/User.vue’
import Register from ‘…/components/Register.vue’
// import router from ‘10todolist案例/router’
import TodoList from ‘…/components/TodoList.vue’
import Todo from ‘…/components/Todo.vue’
import Time from ‘…/components/Time.vue’
import PersonalInformation from ‘…/components/PersonalInformation.vue’
// 创建并暴露一个路由器
// export default new VueRouter({
const router =new VueRouter({
routes: [
// 路由的重定向,自动跳转到一个路由
{
path: ‘/’,
redirect: ‘/Login/User’
},
//登录页面的路由,想进去除了todolist里的退出,还有重定向
{
path: '/Login',
component: Login,
// 登录
children: [{
path: 'User',
component: User
},
// 注册
{
path: 'Register',
component: Register
},
]
},
// todoList路由,登录是进入链接
{
path: '/Todo',
name: 'Todo',
component: Todo,
beforeEnter:(to,from,next)=>{
const Names=JSON.parse(localStorage.getItem("Names"))||[]
for(let i=0;i<Names.length;i++){
if(Names[i].loginName==to.query.loginName){
if(Names[i].loginPass==to.query.loginPass){
next()
return alert("欢迎回到你的代办事项")
}else{
return alert("密码不正确")
}
}
}
return alert("用户名不存在")
},
children: [{
path: 'TodoList',
component: TodoList
},
{
path: 'Time',
component: Time
},
{
path: 'PersonalInformation',
component: PersonalInformation,
}
]
},
// {
// path:'/about.html',
// component:About
// },
// {
// path:'/home.html',
// component:Home
// },
]})
export default router
// 暴露出去
// 全局前置路由守卫——初始化的时候被调用,每次路由切换之前被调用
// router是不是需要引用
//
从这里也可以看到一些结构其他整体的结构
组件部分
其中组件部分,除了路由中所展示的这些之外,就是最主要的TODOlist的主体部分,首先是TODO这个组件,它包括三部分,分别是头部列表以及尾部,其中,列表部分又有许多事物组件组成,
组件间通信
除此之外,在功能方面,主要有两大问题,第一就是组件间通信,这里除了用传统的将参数直接给紫组建dry或者是副主件给自组建一个方法,让自助件给父组件传值也就是prop方法,还有就是全局事件总线,其他组件间通信的方法也有很多,这里主要只用了这两种
<template>
<div id="root">
<div class="todo-container">
<div class="todo-wrap">
<MyHeader :addTodo="addTodo" />
<MyList
:todos="todos"
/>
<MyFooter
:todos="todos"
:checkAllTodo="checkAllTodo"
:clearAllTodo="clearAllTodo"
/>
</div>
</div>
</div>
</template>
<script>
// import pubsub from 'pubsub-js'
import MyHeader from "./MyHeader.vue";
import MyList from "./MyList";
import MyFooter from "./MyFooter";
export default {
name: "TodoList",
components: { MyHeader, MyList, MyFooter },
data() {
return {
// todos:[
// {id:'001',title:'抽烟',done:true},
// {id:'002',title:'喝酒',done:false},
// {id:'003',title:'开车',done:true},
// ]
todos: JSON.parse(localStorage.getItem("todos")) || [],
};
},
methods: {
// 添加一个todo
addTodo(todoObj) {
// 将新项添加到数组起始位置:
this.todos.unshift(todoObj);
},
// 勾选or取消勾选一个todo
checkTodo(id) {
this.todos.forEach((todo) => {
if (todo.id === id) todo.done = !todo.done;
});
},
//更新数据
updateTodo(id,title) {
this.todos.forEach((todo) => {
if (todo.id === id) todo.title = title;
});
},
// 删除一个todo
deleteTodo(id) {
// 可精简代码,这里为了方便理解就不精简啦
this.todos = this.todos.filter((todo) => {
return todo.id !== id;
});
},
//全选or取消全选
checkAllTodo(done) {
this.todos.forEach((todo) => {
todo.done = done;
});
},
//清除所有已经完成的todo
clearAllTodo() {
this.todos = this.todos.filter((todo) => {
return !todo.done;
});
},
},
watch: {
todos: {
deep: true,
handler(value) {
localStorage.setItem("todos", JSON.stringify(value));
},
},
},
// $bus是作为vue原型属性的一个vm,
// $on是某个方法绑定到这个$bus,
// $off是解除之前绑定的方法
// $emit触发方法的绑定
mounted(){
this.$bus.$on('checkTodo',this.checkTodo)
this.$bus.$on('deleteTodo',this.deleteTodo)
this.$bus.$on('updateTodo',this.updateTodo)
// this.pubId=pubsub.subscribe('deleteTodo',this.deleteTodo)
},
beforeDestroy(){
this.$bus.$off('checkTodo')
this.$bus.$off('deleteTodo')
this.$bus.$off('updateTodo')
// pubsub.unsubscribe(this.pubId)
}
};
</script>
<style>
/*base*/
body {
background: #fff;
}
.btn {
display: inline-block;
padding: 4px 12px;
margin-bottom: 0;
font-size: 14px;
line-height: 20px;
text-align: center;
vertical-align: middle;
cursor: pointer;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),
0 1px 2px rgba(0, 0, 0, 0.05);
border-radius: 4px;
}
.btn-danger {
color: #fff;
background-color: #da4f49;
border: 1px solid #bd362f;
}
.btn-edit{
color: #fff;
background-color: skyblue;
border: 1px solid rgb(103,159,180);
margin-right:5px;
}
.btn-danger:hover {
color: #fff;
background-color: #bd362f;
}
.btn:focus {
outline: none;
}
.todo-container {
width: 600px;
margin: 0 auto;
}
.todo-container .todo-wrap {
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
}
</style>
路由跳转
另一个主要问题就是路由的跳转,除了最简单的router-link还有一个就是使用路由器的push方法,也就是编程式导航
<template>
<div>
<router-link
class="list-group-item"
active-class="active"
:to="{
path:'/Todo/Todolist',
query:{
loginName:$route.query.loginName,
loginPass:$route.query.loginPass,
}
}"
>TodoList</router-link>
<router-link
class="list-group-item"
active-class="active"
:to="{
path:'/Todo/Time',
query:{
loginName:$route.query.loginName,
loginPass:$route.query.loginPass,
}
}"
>Time</router-link>
<router-link
class="list-group-item"
active-class="active"
:to="{
path:'/Todo/PersonalInformation',
query:{
loginName:$route.query.loginName,
loginPass:$route.query.loginPass,
}
}"
>个人信息</router-link>
<div>
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: "Todo",
};
</script>
<style>
li{
list-style:none;
}
</style>
this.$router.push({
path: “/Todo”,
query: {
loginName: this.loginName,
loginPass: this.loginPass,
},