美文网首页
🎑 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