0. 前情提要
0.1. 进度提要
网页大致的样子已经出来的。
- 每个task有checkbox和删除的功能。
- 页面排版有了header、tasks 和 add,但并没有实质的功能。
0.2. 知识点小结
-
组件
-
组件是可复用的 Vue 实例
-
一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
data: function(){ return { count: 0 } }
-
通常一个应用会以一棵嵌套的组件树🎄的形式来组织
ja
-
每个组件必须只有一个根元素,就是用一个
<div>
tag把全部东西包起来<div class="blog-post">� <h3>{{ title }}</h3>� <div v-html="content"></div>� </div>
-
-
Prop
- Prop 是你可以在子组件上注册的一些自定义特性。当一个父组件的值传递给一个 prop 特性的时候,它就变成了那个子组件实例的一个属性。
- 一个组件默认可以拥有任意数量的 prop
-
v-bind
我们可以使用 v-bind 来动态传递 prop ,从父级传到子级。
<blog-post� v-for="post in posts"� v-bind:key="post.id"� v-bind:title="post.title"�> </blog-post>�
-
v-on & $emit
通过事件向父级组件发送消息,从子级传到父级。
自定义事件的系统来解决这个问题。我们可以调用内建的
$emit
方法并传入事件的名字,来向父级组件触发一个件:<button v-on:click="$emit('enlarge-text')">� Enlarge text �</button>�
-
v-model
v-model是一个语法糖,利用v-bind和v-on实现双向绑定
<input v-model="searchText">
等价于:
<input v-bind:value="searchText" v-on:input="searchText = $event.target.value">
1. 完善add new task这个功能
1.1 创建newTodo
当用于点了add按钮后,vue要生成一个newTodo的object,然后把它传到父级的App.vue中,等待写入数据库。
这个newTodo长这样:
newTodo = {
id: 'ID', // 这里使用uuid这个库生成一个id,但是如果使用mongodb之类其实会自动生成
title: 'TITLE', // 使用v-model,把用户的文字存进来
completed: false // 因为task都是还没做的
}
所以首先,需要安装uuid。
在shell中跑一下
npm install uuid
接着,AddTodo.vue改成这样👇:
<template>
<form v-on:submit="addTodo">
<input type="text" v-model="title" name="title" placeholder="Add new task ...">
<input type="submit" value="Add" class="btn">
</form>
</template>
<script>
import uuid from 'uuid'
export default {
name: "AddTodo",
data(){ return { title:''} }, // related to v-model
methods:{
addTodo(e){
e.preventDefault();// make sure id is unique
const newTodo = {
id: uuid.v4(), // generate id
title: this.title,
completed: false
};
this.$emit('add-todo', newTodo); // pass newTodo to parent component
this.title = ''; // reset placeholder to default
}
}
}
</script>
1.2 在App.vue中修改data
接着,修改App.vue,使用新建的addTodo这个method,把子级的newTodo传入data中👇:
<template>
<div id="app">
<Header />
<AddTodo v-on:add-todo="addTodo"/>
<Todos v-bind:todos="todos" v-on:del-todo="deleteTodo"/>
</div>
</template>
<script>
import Todos from './components/Todos'
import Header from "./components/layout/Header";
import AddTodo from "./components/AddTodo";
export default {
name: 'app',
components: {
AddTodo,
Header,
Todos
},
data(){
return {
todos: [...]
}
},
methods: {
deleteTodo(id){
this.todos = this.todos.filter(todo => todo.id != id)
},
addTodo(newTodo){
this.todos = [...this.todos, newTodo]
}
}
}
</script>
1.3 结构diagram
内部的关系,大概是这样👇:
![](https://img.haomeiwen.com/i3307176/a2f66f2dd7e74919.png)
2. 使用jsonplaceholder模拟一个后端
2.0 使用axios来请求
2.0.1
-
安装axios
npm install axios
-
🌰 get请求
axios.get('/user?ID=12345') .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
-
🌰 post请求
axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
2.0.2 Jsonplaceholder
此处用Jsonplaceholder的todo来模拟一个对后端请求。它的 REST API:
http://jsonplaceholder.typicode.com/todos
2.1 get请求后端的tasks
因为随后会向API请求数据,就不需要本地的data了,就直接清除App.vue里头的data,像这样👇
export default{
// balah balah...
data(){
return { todos: [] }
}
}
接下来,在App.vue中增加一个created()的method,从后端GET请求数据👇
import ...
import axios from "axios";
export default {
name: 'app',
components: {...},
data(){ return { todo: [] }},
methods: { ... },
created(){
axios.get('http://jsonplaceholder.typicode.com/todos?_limit=5')
.then( res => this.todos = res.data )
.catch( err => console.log(err) );
}
}
2.2 post上传task到后端
因为jsonplaceholder会生成id,所以在AddTodo.vue中,就不需要uuid了,把它comment掉就好了。
接着,在App.vue的methods中,把addTodo改成POST请求👇
addTodo(newTodo){
axios.post('http://jsonplaceholder.typicode.com/todos', newTodo)
.then( res => this.todos = [...this.todos, newTodo] )
.catch( err => console.log(err))
2.3 请求删除后端的task
同理,把delete也改成POST请求:
deleteTodo(id){
axios.delete(`http://jsonplaceholder.typicode.com/todos/${id}`, id)
.then( res => this.todos = this.todos.filter(todo => todo.id != id) )
.catch( err => console.log(err) )
}
3. vue-router
3.1 警告🤞🤞🤞
- 接下来用vue ui安装vue-router,会覆盖掉全部的App.vue。所以要backup一下,等安装完,再把原先App.vue的内容复制回Home.vue。
- 如果用npm安装完vue-router,会无法运行。网上说仿佛是webpack和npm之前的啥问题...解决的办法是把webpack降级。
npm install webpack@4.28.4
(感觉这个教程顺序完全不对...之后要先安装vue-router,再开始写。晚点重来一次...)
3.2 调整一下
-
把Home.vue中的header全部删掉。
-
把header放到App.vue中。
<template>
<div id="app">
<Header />
<router-view/>
</div>
</template>
- 把router link放到Header.vue中。
<template>
<header class="header">
<h1>Todo List</h1>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</header>
</template>
好的...👍
完结...🤞🤞
撒花...🙌🙌🙌
好像之后得再写一遍,一方面是vue-router那个部分跟💩一样...另一方面则是巩固一下学习。
明天要坐游轮🚢去冲绳啦哈哈~~~临行前还是能做完还是比较开心的!
Ronn Liu 🙋♂️
2019/01/22 📌
网友评论