Vue learning notes (I) vue2 based todolist to-do list addition / deletion query case | node based JS building projects using Vue cli scaffolding

You 2022-06-23 18:55:19 阅读数:948

vuelearningnotesvue2vue

One 、 Reference material


Two 、 Running environment


  • Windows11
  • Visual Studio Code v2022
  • Node.js v16.5.01
  • Vue/cli v5.0.6

Requirements case description :

Use Vue2 Modular programming is used to realize the following case ( The style is written casually according to the tutorial , Here to be familiar with Vue2 Mainly )

 Insert picture description here

Project structure :

 Insert picture description here

explain :

Vue2 Support modular programming , One Vue Suffixed files represent a Vue Components , These usually include :

1) HTML Code , namely <template> label ,
2) JS Code , namely <script> label , Usually back Key-Value The object of form , Say something about Vue Parameters of components , Including variables and functions .
3)CSS Style code , namely <style> label , Usually use scoped The restriction style is only valid within the current component .

3、 ... and 、 Develop modules according to requirements

 Insert picture description here
According to the interface, this Todo The case is divided into three modules , Namely Header、Body and Footer, among Body Is made up of multiple to-do items , therefore Body It can also be divided into multiple TodoItem, So there is 4 A module .

It should be noted that , stay Vue2 In Engineering ,App.vue Be similar to SpringBoot Start class in , Is mainly imported in HTML The components of , So the storage and modification of data will be put in App.vue in , Other components need to pass through App Transfer relevant data or functions to complete the case .

Four 、 Code implementation

App.vue

<template>
<div id="app">
<h1><img src="./assets/logo.png"> be based on Vue2 Of TodoList Case study </h1>
<TodoHeader :fnAddTodo="fnAddTodo" ></TodoHeader>
<TodoBody :todoList="todoList" :fnCheckTodo="fnCheckTodo" :fnDeleteTodo="fnDeleteTodo"></TodoBody>
<TodoFooter :todoList="todoList" :fnUpdateTodo="fnUpdateTodo" :fnClearFinishedTodo="fnClearFinishedTodo"></TodoFooter>
</div>
</template>
<script> import TodoHeader from './components/TodoHeader.vue' import TodoBody from './components/TodoBody.vue' import TodoFooter from './components/TodoFooter.vue' export default {
 name: 'App', data(){
 return {
 todoList: [ {
id: '001', title: ' having dinner ', done: true}, {
id: '002', title: ' sleep ', done: false}, {
id: '003', title: ' play ', done:false} ], } }, methods: {
 // function : Add a new to-do  fnAddTodo(todoObj){
 this.todoList.unshift(todoObj) }, // function : Switch the status of the to-do list  fnCheckTodo(id){
 this.todoList.forEach((todoObj) => {
 if(id === todoObj.id) todoObj.done = !todoObj.done }) }, // function : Delete to-do  fnDeleteTodo(id){
 this.todoList = this.todoList.filter(todoObj => todoObj.id !== id) }, // function : Status of batch operation to-do items  fnUpdateTodo(done){
 this.todoList.forEach((todoObj) => todoObj.done = done) }, // function : Clear completed to DOS  fnClearFinishedTodo(){
 if(confirm(' Are you sure you want to delete ?')) this.todoList = this.todoList.filter((todoObj) => !todoObj.done) } }, components: {
TodoHeader, TodoBody, TodoFooter} } </script>
<style scoped> h1{
 text-align: center;} img{
 width: 50px; height: 50px;} #app{
 width: 600px; margin: 0 auto; } </style>

TodoHeader.vue

<template>
<div>
<label for="add"> To do list </label>
<input id="add" v-model="title" @keydown.enter="add" placeholder=" Please enter the task title , Press enter to confirm ">
<button @click="add"> add to </button>
</div>
</template>
<script> // Third party Library npm i nanoid import {
nanoid} from 'nanoid' export default {
 name: 'TodoHeader', data() {
 return {
 title: '' } }, methods: {
 // add to Todo add(){
 if(!this.title.trim()) return alert(' Tips : The entered to-do list cannot be empty !') // encapsulation Todo object  const todoObj = {
 id: nanoid(), title: this.title, done: false } // Call callback function  this.fnAddTodo(todoObj) // Empty  this.title = '' } }, // Introduction of upper layer App Methods  props: ['fnAddTodo'] } </script>
<style scoped> div{
 background: gray; padding: 20px; font-size: 1.2em; } button, input{
 font-size: 1.1em; } button{
 float: right; } </style>

TodoBody.vue

<template>
<div>
<ul>
<li v-for="todoObj in todoList" :key="todoObj.id">
<TodoItem :todoObj="todoObj" :fnCheckTodo="fnCheckTodo" :fnDeleteTodo="fnDeleteTodo"></TodoItem>
</li>
</ul>
</div>
</template>
<script> import TodoItem from './TodoItem.vue' export default {
 name: 'TodoBody', components: {
TodoItem}, props: ['todoList', 'fnCheckTodo', 'fnDeleteTodo'] } </script>
<style scoped> div{
 background: pink; padding: 20px; font-size: 1.1em; } ul{
 list-style: none; padding-left: 0px; } </style>

TodoItem.vue

<template>
<nav>
<input type="checkbox" :checked="todoObj.done" @change="handlerCheckTodo(todoObj.id)">
<span>{
{ todoObj.title }}</span>
<button @click="handlerDeleteTodo(todoObj.id)"> Delete </button>
</nav>
</template>
<script> export default {
 name: 'TodoItem', methods: {
 handlerCheckTodo(id){
 this.fnCheckTodo(id) }, handlerDeleteTodo(id){
 if(confirm(' Are you sure you want to delete Id by [' + id + '] To-do list for ?')) this.fnDeleteTodo(id) } }, // introduce Body From the todoObj and App From the fnCheckTodo Method  props: ['todoObj', 'fnCheckTodo', 'fnDeleteTodo'], } </script>
<style scoped> nav{
 background: rgb(196, 100, 100); padding: 20px; font-size: 1.1em; } button{
 float:right; font-size: 1.1em; display: none; } input{
 width:1.5em; height:1.5em } nav:hover{
 background: rgb(31, 101, 167); } nav:hover button{
 display: block; } </style>

<template>
<nav>
<input type="checkbox" :checked="todoObj.done" @change="handlerCheckTodo(todoObj.id)">
<span>{
{ todoObj.title }}</span>
<button @click="handlerDeleteTodo(todoObj.id)"> Delete </button>
</nav>
</template>
<script> export default {
 name: 'TodoItem', methods: {
 handlerCheckTodo(id){
 this.fnCheckTodo(id) }, handlerDeleteTodo(id){
 if(confirm(' Are you sure you want to delete Id by [' + id + '] To-do list for ?')) this.fnDeleteTodo(id) } }, // introduce Body From the todoObj and App From the fnCheckTodo Method  props: ['todoObj', 'fnCheckTodo', 'fnDeleteTodo'], } </script>
<style scoped> nav{
 background: rgb(196, 100, 100); padding: 20px; font-size: 1.1em; } button{
 float:right; font-size: 1.1em; display: none; } input{
 width:1.5em; height:1.5em } nav:hover{
 background: rgb(31, 101, 167); } nav:hover button{
 display: block; } </style>

TodoFooter.vue

<template>
<nav v-show="totalTodoList">
<input type="checkbox" v-model="isAll">
Completed {
{ totalFinishedTodo }} / All {
{ totalTodoList }}
<button @click="fnClearFinishedTodo"> Cleanup completed </button>
</nav>
</template>
<script> export default {
 name: 'TodoFooter', props: ['todoList', 'fnUpdateTodo', 'fnClearFinishedTodo'], // Compute properties  computed:{
 // Calculate completed to DOS  totalFinishedTodo(){
 return this.todoList.reduce((pre, todoObj) => pre + (todoObj.done ? 1 : 0), 0) }, // All to-do items  totalTodoList(){
 return this.todoList.length }, isAll: {
 // Default check condition of select all button : All to-do items have been completed  get(){
 return this.totalTodoList > 0 && this.totalFinishedTodo == this.totalTodoList }, set(value){
 return this.fnUpdateTodo(value) } } } } </script>
<style scoped> nav{
 background: greenyellow; padding: 20px; font-size: 1.1em; } input{
 height: 1.5em; width: 1.5em; } button{
 float:right; font-size: 1.1em; } </style>

5、 ... and 、 Summary of key points

5.1 Vue2 Componentized coding process

  1. Split static components : Components should be split according to functional points , Do not name with Html Element conflict
  2. Implement dynamic components : Consider where the data is stored , Is the data in use by a single component or by multiple components .
  • A single component is in use : Put it on the component itself
  • Multiple components in use : On their common upper layer components ( High cohesion , Low coupling )
  1. Implement interaction : Start with binding events

5.2 props Applicable scenario

  1. Parent component ==> Child components Data communication
  2. Child components ==> Parent component signal communication ( The parent component is required to give a function to the child component first )

5.3 Use with caution v-model

v-model Property can implement DOM Data and Vue Two way binding of object attributes , however v-model Bound value cannot be props The value passed , because props It can't be modified .

5.4 props

props The value passed to the component is the value of the object type , When modifying the attributes in an object ,Vue No errors are reported , But this is not recommended .

5.5 Personal summary

I just got in touch with you these days Vue, After all, it is an encapsulated framework , I feel it's easy to get started , And the engineering design idea is similar to the back-end design idea , I used this framework to do the lesson design long before I knew it , It was used before JQuery, Lead to HTML、CSS and JavaScript The relationship among the three is chaotic , Now use Vue Component-based programming , The code is much more elegant .

版权声明:本文为[You]所创,转载请带上原文链接,感谢。 https://qdmana.com/2022/174/202206231738391797.html