Application Programming vue assembly 2

Write a few small examples to understand the component-based programming ideas vue, here is a demo.

Effect icon:
Here Insert Picture Description
Demand:
header portion of the input tasks performed add , displayed in the list;
list each item entry, the mouse moved , the background is grayed out and displays the delete button click on the button. Delete the item; the mouse out of time, recovery aS;
footer section: 1. The number of display list and status check has been completed and the number of the total number ; 2. completed when the number is 0, the display is not clear completed task button ; 3. when the number of completed equal to the total number of time , 4. when the check box full. list list is empty , the whole box is not checked; 5. when active Select checked , all entries are checked, to check all the time to check.

Project directory:
Here Insert Picture Description
Code:

1.index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vue_demo</title>
<!--    <link rel="stylesheet" href="./static/css/bootstrap.css">-->
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

2.main.js

import Vue from 'vue'
import App from './App'

import './base.css' // 全局引入base.css文件

new Vue({
  el: '#app',
  components: { App },
  template: '<App/>'
})

3.App.vue

<template>
  <div class="todo-container">
    <div class="todo-wrap">
      <Header :addProject="addProject"/>
      <List :projects="projects" :deleteProject="deleteProject"/>
      <todo-footer :projects="projects" :deleteAllComplete="deleteAllComplete"
        :setSelect="setSelect"/>
    </div>
  </div>
</template>

<script>
  import Header from './components/Header'
  import List from './components/List'
  import TodoFooter from './components/Footer'

  export default {
    name: 'App',
    data () {
      return {
        projects: [
          {
            content: '吃饭',
            complete: false,
          },
          {
            content: '睡觉',
            complete: true,
          },
          {
            content: 'coding',
            complete: false,
          },
        ],
      }
    },
    methods: {
      addProject (project) {  //添加project
        this.projects.push(project)
      },
      deleteProject (index) { //根据index删除project
        this.projects.splice(index,1)
      },

      deleteAllComplete () {  //删除所有完成的任务
        //将project中complete为true的过滤掉,留下false为一个新的数组,重新赋值
        this.projects = this.projects.filter(project => !project.complete)
      },
      setSelect (isAllCheck) {  //根据全选框值设置多选框是否勾选
        this.projects.forEach(project => project.complete = isAllCheck)
      }
    },
    components: { Header, List, TodoFooter},

  }
</script>

<style>
  /*app*/
  .todo-container {
    width: 600px;
    margin: 0 auto;
  }
  .todo-container .todo-wrap {
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 5px;
  }
</style>

4.Header.vue

<template>
  <div class="todo-header">
    <input type="text" placeholder="请输入你的任务名称,按回车键确认"
      @keyup.enter="addItem" v-model="content"/>
  </div>
</template>

<script>
    export default {
      props: {
        addProject: Function
      },
      data () {
        return {
          content: '',
        }
      },
      methods: {
        addItem () {
          // 1.检查输入的合法性
          const content = this.content.trim()
          if (!content) { // content默认不为空字符串,可不写 === ''
            alert("不能为空")
            return
          }
          // 2.根据输入生成一个project对象
          const project = {
            content: this.content,
            complete: false
          }
          // 3.将对象添加到projects中
          this.addProject(project)
          // 4.清空输入
          this.content = ''
        }
      }
    }
</script>

<style>
  /*header*/
  .todo-header input {
    width: 560px;
    height: 28px;
    font-size: 14px;
    border: 1px solid #ccc;
    border-radius: 4px;
    padding: 4px 7px;
  }

  .todo-header input:focus {
    outline: none;
    border-color: rgba(82, 168, 236, 0.8);
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
  }

</style>

5.List.vue

<template>
  <ul class="todo-main">
    <Item v-for="(project,index) in projects" :key="index" :project="project"
      :index="index" :deleteProject="deleteProject"/>
  </ul>
</template>

<script>
    import Item from "../components/Item";
    export default {
      name: 'List',
      components: {Item},
      props: {
        projects: Array,
        deleteProject: Function
      }
    }
</script>

<style>
  /*main*/
  .todo-main {
    margin-left: 0px;
    border: 1px solid #ddd;
    border-radius: 2px;
    padding: 0px;
  }

  .todo-empty {
    height: 40px;
    line-height: 40px;
    border: 1px solid #ddd;
    border-radius: 2px;
    padding-left: 5px;
    margin-top: 10px;
  }
</style>

6.Item.vue

<template>
<!-- onmouseover="" onmouseout="" -->
  <li @mouseenter="handleEnter(true)" @mouseleave="handleEnter(false)" :style="{background: bgColor}">
    <label>
      <input type="checkbox" v-model="project.complete"/>
      <span>{{project.content}}</span>
    </label>
    <button class="btn btn-danger" v-show="isShow" @click="deleteItem">删除</button>
  </li>
</template>

<script>
    export default {
      name: 'Item',
      props: {
        project: Object,
        index: Number,
        deleteProject: Function
      },
      data () {
        return {
          bgColor: 'white',
          isShow: false
        }
      },
      methods: {
        handleEnter (isEnter) {
          if (isEnter) {
            this.bgColor = '#aaaaaa'
            this.isShow = true
          }else {
            this.bgColor = 'white'
            this.isShow = false
          }
        },
        deleteItem () {
          const {deleteProject, project, index} = this
          if (window.confirm(`确认删除${project.content}吗`)) {
            deleteProject(index)
          }
        }
      }
    }
</script>

<style>
  /*item*/
  li {
    list-style: none;
    height: 36px;
    line-height: 36px;
    padding: 0 5px;
    border-bottom: 1px solid #ddd;
  }

  li label {
    float: left;
    cursor: pointer;
  }

  li label li input {
    vertical-align: middle;
    margin-right: 6px;
    position: relative;
    top: -1px;
  }

  li button {
    float: right;
    display: none;
    margin-top: 3px;
  }

  li:before {
    content: initial;
  }

  li:last-child {
    border-bottom: none;
  }
</style>

7.Footer.vue

<template>
  <div class="todo-footer">
    <label>
      <input type="checkbox" v-model="isAllCheck"/>
    </label>
    <span>
          <span>已完成{{completeSize}}</span> / 全部{{projects.length}}
        </span>
    <button class="btn btn-danger" v-show="completeSize" @click="deleteAllComplete">清除已完成任务</button>
  </div>
</template>

<script>
    export default {
      name: 'Footer',
      props: {
        projects: Array,  //project数组
        deleteAllComplete: Function,  //清除已完成任务
        setSelect: Function //根据全选框来设置其他所有多选框
      },
      computed: {
        completeSize () {
          // 遍历projects,初始化preTotal为0,若project.complete为true则加1,返回最终preTotal值
          return this.projects.reduce((preTotal,project) => preTotal+(project.complete?1:0), 0)
        },
        isAllCheck: {
          get(){  //获取多选框的值,当已完成数等于全部数量且已完成数大于0时,勾选(默认>0,可以不写)
            return this.completeSize === this.projects.length && this.completeSize
          },
          set(value){ //监视多选框的值,value是当前多选框最新的值
            this.setSelect(value)
          }
        }
      }
    }
</script>

<style>
  /*footer*/
  .todo-footer {
    height: 40px;
    line-height: 40px;
    padding-left: 6px;
    margin-top: 5px;
  }

  .todo-footer label {
    display: inline-block;
    margin-right: 20px;
    cursor: pointer;
  }

  .todo-footer label input {
    position: relative;
    top: -1px;
    vertical-align: middle;
    margin-right: 5px;
  }

  .todo-footer button {
    float: right;
    margin-top: 5px;
  }
</style>

Extended Description

  1. In many cases use the arrow function template string, the function default parameters, the expansion operator, object initialization abbreviated ES6 new features such as writing, you can read the entry es6
  2. Vue can use on official tutorial and reference vue API: https://cn.vuejs.org/v2/guide/
  3. If the number is greater than 0 (val> 0), writing may be greater than 0, the default is greater than 0; when the string is empty (! STR), default string is not empty
  4. About Footer.vue used in reduce()function: for an accumulation operation of the array
    array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
    reduce function accepts a function and a function initialValue initial value (passed initial value).
    Wherein the function function accepts four parameters were total (each calculated return value), currentValue (value of the current element of the array), currentIndex (current index value array element), arr (current array element)

Guess you like

Origin www.cnblogs.com/itzlg/p/11879709.html