24-案例-记事本-组件版

核心步骤:

        1. 拆分基础组件
                新建组件 -> 拆分存放结构 -> 导入注册使用
        2.  渲染待办任务
                提供数据(公共父组件) -> 父传子传递 list ->  v-for 渲染
        3. 添加任务
                收集数据 v-model -> 监听事件 -> 子传父传递任务 -> 父组件 unshift
        4. 删除任务
                监听删除携带 id -> 子传父传递 id -> 父组件 filter删除
        5. 底部合计 和 清空功能
                底部合计: 父传子传递 list ->  合计展示
                清空功能: 监听点击 -> 子传父通知父组件 -> 父组件清空
        6. 持久化存储: watch监视数据变化,持久化到本地

代码示例:

1. XxHeader.vue : 子传父,将输入框内容传递给父组件,父组件进行添加

<template>
    <!-- 输入框 -->
    <header>
        <h1>记事本</h1>
        <!-- 回车和点击都监听 -->
        <input 
        @keyup.enter="handleAdd"
        placeholder="请输入任务" v-model="doName">
        <button @click="handleAdd">添加任务</button>
    </header>
</template>
<script>

export default {
    data() {
        return {
            doName: ""
        }
    },
    methods:{
        handleAdd(){
            // console.log(this.doName)
            if (this.doName.trim() ===''){
                alert("任务名称不能为空")
                return
            }

            this.$emit('add',this.doName)
            this.doName=""
        }
    }
}
</script>

2. XxMain.vue: 父传子,渲染数据; 点击删除:子传父id,父组件进行过滤

<template>
<!-- 列表区域 -->
<section>
    <ul>
        <li v-for="(item,index) in list" :key="item.id">
            <div >
                <span>{{ index + 1 }}<label>{{ item.name }}</label></span>
                <button @click="handleDel(item.id)">X</button>
            </div>
        </li>
    </ul>
</section>
</template>

<script>
export default{
    props:{
        list:Array
    },
    methods:{
        handleDel(id){
            // console.log(id)
            this.$emit('del',id)
        }
    }
}

</script>

3. XxFooter.vue: 父传子,统计长度; 点击清空,子传父,父组件清空数据

<template>
    <!-- 统计和清空 -->
    <footer>
        <!-- 统计 -->
        <span>合 计:<strong>{{ list.length }}</strong></span>
        <!-- 清空 -->
        <button @click="clear">
            清空任务
        </button>
    </footer>
</template>

<script>
export default{
    props:{
        list:Array
    },
    methods:{
        clear(){
            this.$emit('clear')
        }
    }

}

</script>

4. App.vue

<template>
  <div id="app">
    <XxHeader @add="handleAdd"></XxHeader>
    <XxMain :list="list" @del="handleDel"></XxMain>
    <XxFooter :list="list" @clear="handleClear"></XxFooter>
  </div>
</template>

<script>

import XxHeader from './components/XxHeader.vue'
import XxMain from './components/XxMain.vue'
import XxFooter from './components/XxFooter.vue'

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


// 添加功能:
//1. 收集表单数据 -> v-model
//2. 监听事件 (回车 + 点击 都要进行监听)
//3. 子传父,将任务名称传递给父组件App.vue
//4. 父组件进行添加 unshift (自己的数据自己负责)


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


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


export default {
  data() {
    return {
      // 先从本地获取,没有的话取默认值
      list:JSON.parse(localStorage.getItem("list")) || [
        { id: 1, name: "唱" },
        { id: 2, name: "跳" },
        { id: 3, name: "rap" },
      ]
    }

  },
  methods: {
    handleAdd(doName) {
      // console.log(doName)
      this.list.unshift({
        id: +new Date(),
        name: doName
      })
    },
    handleDel(id) {
      // console.log("接收到子组件传递的id",id)
      this.list = this.list.filter(item => item.id !== id)
    },
    handleClear() {
      this.list = []
    }

  },

  watch: {
    list:{
      deep:true,
    handler(newValue){
      //存储到本地
      localStorage.setItem('list',JSON.stringify(newValue))

    }
    }

  },

  components: {
    XxHeader,
    XxMain,
    XxFooter
  }

}

</script>
<style></style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值