Todo-List案例版本四

news2024/11/15 20:09:28

全局事件总线

使用步骤

1.定义全局事件总线

new Vue({
    ...
    beforeCreated(){
        Vue.prototype.$bus=this    //安装全局事件总线,$bus就是当前应用的vm
    }
    ...
})

2.使用事件总线

a.接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身

export default{
    methods(){
        demo(data){...}
    }
    ...
    mounted(){
        this.$bus.$on('xxx',this.demo)
    }
}

b.提供数据:this.$bus.$emit('xxx',data)

3.最好在beforeDestroy钩子中,用$off()去解绑当前组件所用到的事件

实例

src/main.js

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

Vue.config.productionTip = false

Vue.prototype.x={a:1,b:2}

//创建vm
new Vue({
    el: '#app',
    render: h => h(App),
    beforeCreate(){
        Vue.prototype.$bus=this
    }
})

src/App.vue

<template>
    <div class="app">
        <h1>{{ msg }}</h1>
        <School/>
        <Student/>
    </div>
</template>

<script>
import Student from './components/Student'
import School from './components/School'

export default {
    name: 'App',
    data() {
        return {
            msg: '你好啊!'
        }
    },
    components: { Student, School }
}
</script>

<style scoped>
.app {
    background-color: gray;
    padding: 5px;
}
</style>

src/components/Student.vue

<template>
    <div class="student">
        <h2>学生姓名:{{ name }}</h2>
        <h2>学生性别:{{ sex }}</h2>
        <button @click="sendStudentName">发送学生名字到学校</button>
    </div>
</template>

<script>
export default {
    name: 'Student',
    data() {
        return {
            name:'张三',
            sex:'男'
        }
    },
    methods:{
        sendStudentName(){
            this.$bus.$emit('hello',this.name)
        }
    }
}
</script>

<style lang="less">
    .student{
        background-color: pink;
        padding: 5px;
        margin-top: 30px;
    }
</style>

src/components/School.vue

<template>
    <div class="school">
        <h2>学校名称:{{ name}}</h2>
        <h2>学校地址:{{ address }}</h2>
    </div>
</template>

<script>
export default {
    name: 'School',
    data() {
        return {
            name:'黑马',
            address:'广州'
        }
    },
    mounted(){
        this.$bus.$on('hello',(data)=>{
            console.log('我是School组件,收到了数据',data);
        })
    },
    beforeDestroy(){
        this.$bus.$off('hello')
    }
}
</script>

<style scoped>
    .school{
        background-color: skyblue;
        padding: 5px;
    }
</style>

以上是对全局事件总线的运用,接下来是案例使用

(161条消息) Todo-List案例版本三_bubbleJessica的博客-CSDN博客

使用全局事件总线完善 

src/main.js

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

Vue.config.productionTip = false

//创建vm
new Vue({
    el: '#app',
    render: h => h(App),
    beforeCreate(){
        Vue.prototype.$bus=this //安装全局事件总线
    }
})

src/App.vue

<template>
    <div id="root">
        <div class="todo-container">
            <div class="todo-wrap">
                <MyHeader @addToDo="addToDo" />
                <MyList :todos="todos" />
                <MyFooter :todos="todos" @checkAllTodo="checkAllTodo" @clearAllTodo="clearAllTodo" />
            </div>
        </div>
    </div>
</template>

<script>
import MyHeader from './components/MyHeader'
import MyList from './components/MyList'
import MyFooter from './components/MyFooter'

export default {
    name: 'App',
    data() {
        return {
            // 由于todos是MyHeader组件和MyFooter组件都在使用,所以放在App中(状态提升)
            todos: JSON.parse(localStorage.getItem('todos')) || []
        }
    },
    components: { MyHeader, MyList, MyFooter },
    methods: {
        // 添加一个todo
        addToDo(todoObj) {
            this.todos.unshift(todoObj)
        },
        // 勾选or取消勾选一个todo
        checkTodo(id) {
            this.todos.forEach((todo) => {
                if (todo.id === id) todo.done = !todo.done
            })
        },
        // 删除一个todo
        deleteTodo(id) {
            // 注意:filter不改变原数组,只是新建一个数组
            this.todos = this.todos.filter((todo) => {
                return todo.id !== id
            })
        },
        // 全选or取消全选
        checkAllTodo(done) {
            this.todos.forEach((todo) => {
                todo.done = done
            })
        },
        // 清除所有已完成的todo
        clearAllTodo() {
            this.todos = this.todos.filter((todo) => {
                return !todo.done
            })
        }
    },
    watch: {
        // todos简写不包含深度监视
        // todos(value) {
        //     localStorage.setItem('todos', JSON.stringify(value))
        // }

        // todos完整版深度监视
        todos:{
            deep:true,
            handler(value){
                localStorage.setItem('todos', JSON.stringify(value))
            }
        }
    },
    mounted(){
        this.$bus.$on('checkTodo',this.checkTodo)
        this.$bus.$on('deleteTodo',this.deleteTodo)
    },
    beforeDestroy() {
        this.$bus.$off('checkTodo')
        this.$bus.$off('deleteTodo')
    },
}
</script>

<style>
/*base*/
body {
    background: #fff;
}

.btn {
    display: inline-block;
    padding: 4px 12px;
    margin-bottom: 0;
    font-size: 14px;
    line-height: 20px;
    text-align: center;
    vertical-align: middle;
    cursor: pointer;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
    border-radius: 4px;
}

.btn-danger {
    color: #fff;
    background-color: #da4f49;
    border: 1px solid #bd362f;
}

.btn-danger:hover {
    color: #fff;
    background-color: #bd362f;
}

.btn:focus {
    outline: none;
}

.todo-container {
    width: 600px;
    margin: 0 auto;
}

.todo-container .todo-wrap {
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 5px;
}
</style>

src/components/MyList.vue

<template>
    <ul class="todo-main">
        <MyItem
             v-for="todoObj in todos" 
             :key="todoObj.id" 
             :todo="todoObj" 
        />
    </ul>
</template>

<script>
import MyItem from './MyItem.vue'

export default {
    name: 'MyList',
    props:['todos'],
    components: { MyItem }
}
</script>

<style scoped>
/*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>

src/components/MyItem.vue

<template>
    <li>
        <label>
            <input type="checkbox" :checked="todo.done" @change="handleCheck(todo.id)" />
            <!-- 以下代码也能实现功能,但是不太推荐,因为有点违反规则,因为修改了props,只不过vue没有监测到(vue监测到的情况是对象全部被变化 -->
            <!-- <input type="checkbox" v-model="todo.done"/> -->
            <span>{{ todo.title }}</span>
        </label>
        <button class="btn btn-danger" @click="handleDelete(todo.id)">删除</button>
    </li>
</template>

<script>
export default {
    name: 'MyItem',
    //声明接收todo对象
    props: ['todo'],
    methods: {
        handleCheck(id) {
            // 通知App组件将对应的todo对象的done值取反
            // console.log(id);
            // this.checkTodo(id)
            this.$bus.$emit('checkTodo',id)
        },
        handleDelete(id){
            if(confirm('确定删除吗?')){
                // this.deleteTodo(id)
                this.$bus.$emit('deleteTodo',id)
            }
                
        }
    }
}
</script>

<style scoped>
/*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;
}

li:hover {
    background-color: #ddd;
}

li:hover button {
    display: block;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/739490.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Outlook---撤回(或替换)已发出的邮件

0 Preface/Foreword 发送邮件时&#xff0c;发现邮件发错了&#xff0c;或者忘了添加附件&#xff0c;那么就需要用到撤回或者替换功能。 1 撤回/替换邮件方法 步骤如下&#xff1a; 第一步&#xff1a;双击打开邮件&#xff1b; 第二步&#xff1a;找到撤回按键

自锁电路分析与应用

原理图分享 今天工作中遇到一个设计很妙的电路&#xff0c;请教了一下硬件的工程师。 大家自己直接看图可以分享出这个电路的作用吗&#xff0c;可以在评论区告诉我哦&#xff01; 自锁电路 如上图就是一个自锁电路&#xff0c;和下面的电路一样&#xff1a; 电路现象描述&a…

23.RTC实时时钟

1.STM32 RTC介绍&#xff1a; &#xff08;1&#xff09;RTC简介&#xff1a; STM32的实时时钟(RTC)是一个独立的定时器。STM32的RTC模块拥有一组连续计数的计数器&#xff0c;在相应软件配置下&#xff0c;可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和…

虚幻5-could not find root physics body 布料系统问题解决方法

不做不知道自己身体好&#xff0c;又碰到问题了&#xff1a; could not find root physics body 1.据说是Skeleton 和SkeletaMesh傻傻分不清楚 &#xff08;但就是排查后&#xff0c;就不是这个问题&#xff09; 2.重新创造一个Physic Asset吧 Creating a New Physics Asse…

【C语言初阶(13)】三子棋游戏(优化:多子棋实现)

文章目录 一、游戏的实现思路二、游戏的实现步骤1. 菜单函数2. 设置棋盘3. 初始化棋盘4. 打印棋盘5. 玩家下棋6. 电脑下棋7. 多子棋判断输赢8. 判断棋盘是否已满 三、模块化代码实现1. test.c2. game.h3. game.c 四、结果演示 由于模块化编程的需要&#xff0c;我们需要把整个游…

解决Bridge材质导入到Blender为白色的问题

文章目录 前言一、复现问题二、解决方案总结 前言 一、复现问题 在Bridge上看到一块不错的草皮, 导入成功后是白色材质: 二、解决方案 以前用这个方法导入过模型, 那时候还没启用汉化, 也没什么材质问题. 这次操作之前刚启用了汉化, 我猜是汉化导致: 取消勾选’新建数据’, 重…

【Java】-初识java

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ 如 果 你 喜 欢 作 者 的 文 章 &#xff0c;就 给 作 者 点 点 关 注 吧&#xff01; 文章目录 前言…

Linux 基础之 TOP 命令详解

文章目录 一、前言二、Top说明 一、前言 TOP 命令是 Linux 常用的性能分析工具&#xff0c;能够实时显示系统中各个进程资源占用状况&#xff0c;类似于 Windows 的任务管理器。 二、Top说明 当使用一个工具时&#xff0c;对此最快的了解方式就是查看说明&#xff0c;那就是…

6.任务调度:保存和还原现场,时间片轮转

实现任务调度&#xff0c;模拟时间片 1.任务调度 在进行上下文切换时&#xff0c;需要保存和切换以下内容&#xff1a; 寄存器&#xff1a;包括通用寄存器&#xff08;如 EAX、EBX、ECX等&#xff09;和特殊寄存器&#xff08;如程序计数器 PC、堆栈指针 SP、基址指针 BP等&a…

LeetCode | C++ 动态规划——完全背包、518. 零钱兑换 II、377. 组合总和 Ⅳ

目录 完全背包518. 零钱兑换 II377. 组合总和 Ⅳ参考 完全背包 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包…

【数据挖掘】时间序列教程【九】

第5章 状态空间模型和卡尔曼滤波 状态空间模型通常试图描述具有两个特征的现象 有一个底层系统具有时变的动态关系,因此系统在时间上的“状态”t 与系统在时间的状态t−1有关 .如果我们知道系统在时间上的状态t−1 ,那么我们就有了我们需要知道的一切,以便对当时的状态进行推…

12-ATF架构下的启动流程

快速链接: . 👉👉👉 个人博客笔记导读目录(全部) 👈👈👈 付费专栏-付费课程 【购买须知】:Secureboot从入门到精通-[目录] 👈👈👈目录 1、Boot模型2、Boot示例3、Runtime模型4、异常跳转模型5、启动跳转模型

四川佳洲智谷:在AI潮水里加速快跑!

2023年6月28日夏季新品发布会上&#xff0c;摩卡掌舵人李国兴发布了国内首个AI原生HRSaaS整体解决方案——摩卡Eva。该产品的发布&#xff0c;标志着Moka正式成为业内第一家真正交付AI原生HRSaaS产品的公司。 随着AIGC浪潮的到来&#xff0c;越来越多的企业开始意识到人工智能的…

对抗性人工智能如何威胁您的机器学习模型

人工智能&#xff08;AI&#xff09;的出现给社会的几乎每个领域带来了革命性的变化。然而&#xff0c;人工智能的前景光明的能力也伴随着重大挑战&#xff0c;特别是在网络安全方面。 保护机器学习工作流程对于保护这些组织免受新兴威胁至关重要&#xff0c;而对抗性人工智能…

DeRPnStiNK靶机复盘

DeRPnStiNK靶机复盘 拿到靶机后我们第一步先扫描靶机地址。 nmap -sP 192.168.197.0/24扫描出我们的靶机地址。 扫描出来后我们再单独对这个ip进行扫描&#xff0c;发现开了三个端口 然后扫描一下目录&#xff0c;发现一个wordpress登陆网址和一个phpmyadmin登陆地址。 我们…

SOLARIS系统下ORACLE数据恢复案例

服务器数据恢复环境&#xff1a; 两台SPARC SOLARIS操作系统服务器通过光纤交换机共享一台存储作为集群使用。平时是一台服务器&#xff08;以下称为主服务器&#xff09;在运行&#xff0c;如果该服务器发生故障宕机&#xff0c;只需要将这台服务器关机后开启另外一台服务器&a…

Keepalived 安装与配置

安装 Keepalived apt -y install keepalived 里边有一个杠y&#xff0c;就是我安装的时候里面有yes&#xff0c;就直接是yes 添加 Keepalived 配置 安装好之后, 下一步就开始去来写这个配置文件了&#xff0c;就在这里面去建一个 etc 当中&#xff0c;就是在这个 etc 当中建一个…

关于swagger突然跳转登录页面,swagger打开跳转login页面BUG

今天建了一个初始项目&#xff0c;引入swagger之后&#xff0c;启动调用&#xff0c;却总跳转到一个登录页面&#xff0c;手足无措 启动项目后&#xff0c;打开swagger进行测试&#xff0c;但是跳转到下图页面 最后原因是导入了security的包&#xff0c;导致权限安全拦截 注释…

【Spring boot】RedisTemplate中String、Hash、List设置过期时间

Redis中String设置时间的方法 redisTemplate.opsForValue().set("loginCode","254588",2, TimeUnit.SECONDS);//过期时间2秒 redisTemplate.opsForValue().set("loginCode","254588",2, TimeUnit.MINUTES);//过期时间2分钟 redisTemp…

PyQt5及PySide2总结

PyQt5 1. 通过UIC转换成python代码后需在文件中直接添加即可运行。 方便使用代码补全但每次改动ui会生成在原文件中&#xff0c;不小心会发生覆盖&#xff0c;每次都需要将之前的代码重新补充到新生成的文件中。 from PyQt5 import QtCore, QtGui, QtWidgets if __name__ &…