本文状态:未完成
一、产品原型
参考 Windows todo设计一个简单的移动端todo页面原型
二、开发教程
1、新建Todolist.vue
先通过脚手架配置好vue项目:@vue/cli
在项目src\views下面新建Todo.vue
<template>
<div class="todo">
<h1>Todolist</h1>
<input type="text" v-model="content" @keypress="add"><button @click="add">Add</button>
<p>{{content}}</p>
<div class="section-title">待办</div>
<ul class="todolist underway">
<TodoItem :="todo" v-for="todo in underway" :key="todo.id" :class="{done:todo.status}" v-model="todo.status" />
</ul>
<div class="section-title">已完成</div>
<ul class="todolist completed">
<TodoItem :="todo" v-for="todo in completed" :key="todo.id" :class="{done:todo.status}" v-model="todo.status" />
</ul>
</div>
</template>
<script>
import TodoItem from '../components/TodoItem';
export default {
name: "Todo",
components:{
TodoItem
},
data(){
return{
content:'hello world!',
checked:'',
todos:[
{
id:1,
content:'这是内容1',
status:false
},
{
id:2,
content:'这是内容2',
status:true
},
{
id:3,
content:'这是内容3',
status:true
},
{
id:4,
content:'这是内容4',
status:false
},
{
id:5,
content:'这是内容5',
status:true
}
],
}
},
methods:{
add(){
this.todos.push({
id:this.todos.length+1,
content:this.content,
status:false
})
}
},
computed:{
underway(){
return this.todos.filter(todos=>!todos.status);
},
completed(){
return this.todos.filter(todos=>todos.status);
}
}
}
</script>
<style scoped>
.section-title{font-weight: bold;font-size: 18px;}
.todolist li{list-style: none;}
.todolist li.done{text-decoration:line-through; }
</style>
2、添加组件
<template>
<li>
<input type="checkbox" :name="id" :id="id" :value="content" :checked="modelValue" @input="onInput"/>
<label :for="id">{{content}}</label>
</li>
</template>
<script>
export default {
name: "TodoItem",
data(){
return{
}
},
props:{
id:Number,
content:String,
modelValue:Boolean
},
methods:{
onInput(e){
this.$emit('update:modelValue',e.target.checked);
}
}
}
</script>
<style scoped>
</style>
2、添加路由
router\index.js中添加
const routes = [
//...
{
path: '/todo',
name: 'Todo',
component: ()=> import('../views/Todo')
}
3、入口文件增加Todo页面入口(可以不要这一步)
App.vue 文件
<router-link to="/todo">Todo</router-link>
// router-view 公用的不用多次添加
<router-view/>
4、预览页面
现在就可以npm run serve
运行查看,
打开首页后,点击Todo就可以打开todo页面,也可以直接在浏览器输入下面地址查看
http://localhost:8080/todo
四、备注
父子组件相互传递数据
==单条参数==
<!-- 父组件 -->
<template>
<p>{{ name }}</p>
<TodoItem v-model="name" />
</template>
<script>
import Son from '../components/Son';
export default {
name: "Father",
components:{
Son
},
data(){
return{
name:'Ketty'
}
}
}
</script>
<!-- 子组件 -->
<template>
<input type="text" :value="modelValue" @input="onInput"/>
</template>
<script>
export default {
name: "Son",
props:{
modelValue:String
},
methods:{
onInput(e){
this.$emit('update:modelValue',e.target.value);
}
}
}
</script>
<style scoped>
</style>
==多条参数==
<!-- 父组件 -->
<template>
<p>{{ name }}</p>
<p>{{ addr }}</p>
<TodoItem v-model:name="name" v-model:addr="addr"/>
</template>
<script>
import Son from '../components/Son';
export default {
name: "Father",
components:{
Son
},
data(){
return{
name:'Ketty',
addr:""
}
}
}
</script>
<!-- 子组件 -->
<template>
<input type="text" :value="name" @input="onNameInput"/>
<input type="text" :value="addr" @input="onAddrInput"/>
</template>
<script>
export default {
name: "Son",
props:{
name:String,
addr:String
},
methods:{
onNameInput(e){
this.$emit('update:name',e.target.value);
},
onAddrInput(e){
this.$emit('update:addr',e.target.value);
}
}
}
</script>