vue黑马案例之小黑记事本组件版(含素材)

素材领取:点击我领取素材
提取码:1024

我们的需求如下:
1.拆分基础组件
2.渲染待办任务
3.添加任务
4.删除任务
5.底部合计 和 清空功能
6.持久化存储

分析:
渲染功能:
1.提供数据: 提供在公共的父组件 App.vue
2.通过父传子,将数据传递给TodoMain
3.利用 v-for渲染

添加功能:
1.手机表单数据 v-model
2.监听事件(回车+点击都要添加)
3.子传父,讲任务名称传递给父组件 App.vue
4.进行添加 unshift(自己的数据自己负责)
5.清空文本框输入的内容
6.对输入的空数据 进行判断

删除功能
1.监听事件(监听删除的点击) 携带id
2.子传父,讲删除的id传递给父组件的App.vue
3.进行删除filter(自己的数据 自己负责)

底部合计:父传子 传list 渲染
清空功能:子传父 通知父组件 → 父组件进行更新
持久化存储:watch深度监视list的变化 -> 往本地存储 ->进入页面优先读取本地数据

父组件代码:

<template>
  
  <section id="app">
    
    <TodoHeader @add="handlerAdd">TodoHeader>
    
    <TodoMain :list="list" @handlerDel="del">TodoMain>
    <TodoFooter @clear="handlerClear" :list="list">TodoFooter>
  section>
template>
<script>
import TodoHeader from "./components/TodoHeader.vue"
import TodoMain from "./components/TodoMain.vue"
import TodoFooter from "./components/TodoFooter.vue"
export default {
  data() {
    return {
      // 准备一个数组存放数据 持久保存到本地
      list: JSON.parse(localStorage.getItem("list")) || [
        { id: 1, name: "打篮球" },
        { id: 2, name: "踢足球" }
      ]
    }
  },
  methods: {
    handlerAdd(values) {
      // 我们使用unshift()方法向数组的最前面添加数据
      this.list.unshift({
        // 使用时间戳作为id值
        id: +new Date(),
        name: values
      })
    },
    del(id) {
      // 使用filter去过滤数组完成删除
      this.list = this.list.filter(item => item.id !== id)
    },
    handlerClear() {
      this.list = []
    }
  },
  watch: {
    list: {
      deep: true,
      handler(newValue) {
        localStorage.setItem("list", JSON.stringify(newValue))
      }
    }
  },
  components: {
    TodoHeader,
    TodoMain,
    TodoFooter
  }
}
script>

子组件TodoHeader代码:

<template>
    
    <header class="header">
        <h1>小黑记事本h1>
        
        
        <input @keyup.enter="handlerAdd" v-model="msg" placeholder="请输入任务" class="new-todo" />
        
        <button @click="handlerAdd" class="add">添加任务button>
    header>
template>
<script>
export default {
    data() {
        return {
            msg: ""
        };
    },
    methods: {
        handlerAdd() {
            // 当msg为空时 我们需要返回 
            if (this.msg.trim() == "") {
                alert("请输入值")
                return
            }
            // 子传父 使用this.$emit()
            this.$emit('add', this.msg);
            // 添加完之后 我们需要把表单的值赋为空
            this.msg = ""
        }
    },
};
script>

子组件TodoMain代码:

<template>
    
    <section class="main">
        <ul class="todo-list">
            
            <li class="todo" v-for="(item, index) in list" :key="item.id">
                <div class="view">
                    
                    <span class="index">{{ index + 1 }}.span> <label>{{ item.name }}label>
                    
                    <button @click="del(item.id)" class="destroy">button>
                div>
            li>
        ul>
    section>
template>
<script>
export default {
    // 我们使用props
    props: {
        list: Array
    },
    methods: {
        del(id) {
            // 子传父
            this.$emit('handlerDel', id);
        }
    },
};
script>

子组件TodoFooter代码:

<template>
  
  <footer class="footer">
    
    
    <span class="todo-count">合 计:<strong> {{ list.length }} strong>span>
    
    
    
    <button @click="clear" class="clear-completed">
      清空任务
    button>
  footer>
template>
<script>
export default {
  // 我们把list通过父传子的方法传入
  props: {
    list: Array
  },
  methods: {
    clear() {
      // 子传父
      this.$emit('clear');
    }
  },
};
script>

感谢大家的阅读,如有不对的地方,可以向我提出,感谢大家!

你可能感兴趣的:(vue.js,javascript,ecmascript)