美文网首页
🎑 VUE小教程-建一个TODO list (下)

🎑 VUE小教程-建一个TODO list (下)

作者: 秋衣队长 | 来源:发表于2019-01-23 03:00 被阅读0次

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

内部的关系,大概是这样👇:


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 警告🤞🤞🤞

  1. 接下来用vue ui安装vue-router,会覆盖掉全部的App.vue。所以要backup一下,等安装完,再把原先App.vue的内容复制回Home.vue。
  2. 如果用npm安装完vue-router,会无法运行。网上说仿佛是webpack和npm之前的啥问题...解决的办法是把webpack降级。
npm install webpack@4.28.4

(感觉这个教程顺序完全不对...之后要先安装vue-router,再开始写。晚点重来一次...)

3.2 调整一下

  1. 把Home.vue中的header全部删掉。

  2. 把header放到App.vue中。

<template>
  <div id="app">
    <Header />
    <router-view/>
  </div>
</template>
  1. 把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 📌

相关文章

网友评论

      本文标题:🎑 VUE小教程-建一个TODO list (下)

      本文链接:https://www.haomeiwen.com/subject/cgfrjqtx.html