使用 vue.js 构建一个简单的 todoList 应用

1.安装 Vue-cli

npm install -g vue-cli

2. 使用脚手架初识化项目

vue init webpack my-project

在这里插入图片描述

3.运行项目

cd my-project
npm run dev

4.正式编写

由于是简单应用,所以直接改造 main.js 和 index.htnl
index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vue-notes</title>
  </head>
  <body>
    <div id="app">
      <p>{{title}}</p>
      <p v-if="showSub">{{subTitle}}</p>
    </div>
    <!-- built files will be auto injected -->
  </body>
</html>
main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
// import App from './App'
// import router from './router'

Vue.config.productionTip = false

/* eslint-disable no-new */
// new Vue({
//   el: '#app',
//   router,
//   components: { App },
//   template: '<App/>'
// })

new Vue({
	// 将 inndex.html 文件里面的 id="app",这个 div 作为整个应用的容器
  el: '#app',
  // data 存放的是变量
  data () {
    return {
      title: 'hello Vue.js',
      subTitle: 'Vue is good',
      showSub: true
    }
  }
})
以上是变量的渲染,既然是 todoList ,就是一个列表,接下来进行列表的渲染
main.js
new Vue({
  el: '#app',
  data () {
    return {
      title: 'hello Vue.js',
      subTitle: 'Vue is good',
      showSub: true,
      todos: [
        '吃饭',
        '睡觉',
        '写代码'
      ]
    }
  }
})
index.html
<body>
    <div id="app">
      <p>{{title}}</p>
      <p v-if="showSub">{{subTitle}}</p>
      <ul>
        <li v-for="todo in todos">{{todo}}</li>
      </ul>
    </div>
    <!-- built files will be auto injected -->
  </body>
列表渲染出来了,但是数据是固定的,接下来要把用户输入的值,渲染到界面上
index.html
<body>
    <div id="app">
      <p>{{title}}</p>
      <p v-if="showSub">{{subTitle}}</p>
      // input 输入框,绑定 mytodo 变量
      <div class="">
        <input type="text" v-model="mytodo">
        // button 绑定点击事件 handleClick
        <button @click="handleClick">添加</button>
      </div>
      <ul>
        <li v-for="todo in todos">{{todo}}</li>
      </ul>
    </div>
    <!-- built files will be auto injected -->
  </body>
main.js
new Vue({
  el: '#app',
  data () {
    return {
      title: 'hello Vue.js',
      subTitle: 'Vue is good',
      showSub: true,
      mytodo: '',
      todos: [
        '吃饭',
        '睡觉',
        '写代码'
      ]
    }
  },
  methods: {
    handleClick () {
    // 将用户输入的值, push 到 todo 这个列表里面
      this.todos.push(this.mytodo)
      // 输入框内容置空
      this.mytodo = ''
    }
  }
})
接下来要实现,点击 todo 变成灰色,告诉用户这件事已经做完了,并且在页面中添加用户 todo 的数据
index.html
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vue-notes</title>
    <style>
      li.done {
        text-decoration: line-through;
        color: #ccc;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <p>{{title}}</p>
      <p v-if="showSub">{{subTitle}}</p>
      <div class="">
        <input type="text" v-model="mytodo">
        <button @click="handleClick">添加</button>
      </div>
      <ul>
      // 给 todo 添加一个 toggle 函数 同时将 todo 的 Index 传入
        <li :class="{'done': todo.done}" @click="toggle(index)" v-for="(todo, index) in todos">{{index}}-----{{todo.text}}</li>
      </ul>
      // todo 的数量 remain 是未完成的数量
      <p>{{remain}}/{{todos.length}}</p>
    </div>
    <!-- built files will be auto injected -->
  </body>
main.js
new Vue({
  el: '#app',
  data () {
    return {
      title: 'hello Vue.js',
      subTitle: 'Vue is good',
      showSub: true,
      mytodo: '',
      // 改变数据的结构
      todos: [
        {
          text: '吃饭',
          done: false
        },
        {
          text: '睡觉',
          done: false
        },
        {
          text: '写代码',
          done: false
        }
      ]
    }
  },
  // 利用 computed 实时计算 todo 未完成的数量
  computed: {
    remain () {
    // filter 过滤掉已完成的数量,求取未完成的数量
      return this.todos.filter(v => !v.done).length
    }
  },
  methods: {
    handleClick () {
      this.todos.push({
        text: this.mytodo,
        done: false
      })
      this.mytodo = ''
    },
    // 点击 todo 调用 toggle 函数,将 todo 的状态 进行取反
    toggle (i) {
      this.todos[i].done = !this.todos[i].done
    }
  }
})
接下来要把完成的 todo 进行清空
index.html
<body>
    <div id="app">
      <p>{{title}}</p>
      <p v-if="showSub">{{subTitle}}</p>
      <div class="">
        <input @keyup.enter="handleClick" type="text" v-model="mytodo">
        <button @click="handleClick">添加</button>
        // 清空已完成的 todo
        <button @click="clean">清空</button>
      </div>
      <ul>
        <li :class="{'done': todo.done}" @click="toggle(index)" v-for="(todo, index) in todos">{{index}}-----{{todo.text}}</li>
      </ul>
      <p>{{remain}}/{{todos.length}}</p>
    </div>
    <!-- built files will be auto injected -->
  </body>
main.js
methods: {
    handleClick () {
      this.todos.push({
        text: this.mytodo,
        done: false
      })
      this.mytodo = ''
    },
    toggle (i) {
      this.todos[i].done = !this.todos[i].done
    },
    // 清空已完成的 todo
    clean () {
      this.todos = this.todos.filter(v => !v.done)
    }
  }
最后我们把这个改造成单组件
在 components 里面创建一个 todoList.vue
todoList.vue
<template>
    <div>
    <p>{{title}}</p>
      <p v-if="showSub">{{subTitle}}</p>
      <div class="">
        <input @keyup.enter="handleClick" type="text" v-model="mytodo">
        <button @click="handleClick">添加</button>
        <button @click="clean">清空</button>
      </div>
      <ul>
        <li
          :class="{'done': todo.done}"
          @click="toggle(index)"
          v-for="(todo, index) in todos"
          :key="index"
        >{{index}}-----{{todo.text}}</li>
      </ul>
      <p>{{remain}}/{{todos.length}}</p>
    </div>
</template>

<script>
export default {
  data () {
    return {
      title: 'hello Vue.js',
      subTitle: 'Vue is good',
      showSub: true,
      mytodo: '',
      todos: [
        {
          text: '吃饭',
          done: false
        },
        {
          text: '睡觉',
          done: false
        },
        {
          text: '写代码',
          done: false
        }
      ]
    }
  },
  computed: {
    remain () {
      return this.todos.filter(v => !v.done).length
    }
  },
  methods: {
    handleClick () {
      this.todos.push({
        text: this.mytodo,
        done: false
      })
      this.mytodo = ''
    },
    toggle (i) {
      this.todos[i].done = !this.todos[i].done
    },
    clean () {
      this.todos = this.todos.filter(v => !v.done)
    }
  }
}
</script>

<style lang="css" scoped>
li.done {
        text-decoration: line-through;
        color: #ccc;
    }
</style>

main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vue-notes</title>
    <style>
    </style>
  </head>
  <body>
    <div id="app">
    </div>
    <!-- built files will be auto injected -->
  </body>
</html>

App.vue
<template>
  <div id="app">
    <todoList></todoList>
  </div>
</template>

<script>
import todoList from './components/todoList'
export default {
  name: 'App',
  components: {
    todoList
  }
}
</script>

<style>
</style>

gitee地址
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值