Vue CLI 本地存储 自定义事件

这篇具有很好参考价值的文章主要介绍了Vue CLI 本地存储 自定义事件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

3.8. WebStorage(js 本地存储)

存储内容大小一般支持 **5MB **左右(不同浏览器可能还不一样)

浏览器端通过Window.sessionStorageWindow.localStorage属性来实现本地存储机制

相关API

  • xxxStorage.setItem(‘key’, ‘value’):该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值
  • xxxStorage.getItem(‘key’):该方法接受一个键名作为参数,返回键名对应的值
  • xxxStorage.removeItem(‘key’):该方法接受一个键名作为参数,并把该键名从存储中删除
  • xxxStorage.clear():该方法会清空存储中的所有数据

备注

  • SessionStorage:存储的内容会随着浏览器窗口关闭而消失
  • LocalStorage:存储的内容,需要手动清除才会消失
  • xxxStorage.getItem(xxx):如果 xxx 对应的 value 获取不到,那么getItem()的返回值是null

localStorage

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>localStorage</title>
</head>
<body>
    <h2>localStorage</h2>
    <button onclick="saveDate()">点我保存数据</button><br/>
    <button onclick="readDate()">点我读数据</button><br/>
    <button onclick="deleteDate()">点我删除数据</button><br/>
    <button onclick="deleteAllDate()">点我清空数据</button><br/>

    <script>
        let person = {
            name:"JOJO",
            age:20
        };

        function saveDate() {
            localStorage.setItem('msg', 'localStorage');
            localStorage.setItem('person', JSON.stringify(person));
        }
        function readDate() {
            console.log(localStorage.getItem('msg'));
            const person = localStorage.getItem('person');
            console.log(JSON.parse(person))
        }
        function deleteDate() {
            localStorage.removeItem('msg');
            localStorage.removeItem('person');
        }
        function deleteAllDate() {
            localStorage.clear();
        }
    </script>
</body>
</html>

sessionStorage

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>sessionStorage</title>
</head>
<body>
    <h2>sessionStorage</h2>
    <button onclick="saveDate()">点我保存数据</button><br/>
    <button onclick="readDate()">点我读数据</button><br/>
    <button onclick="deleteDate()">点我删除数据</button><br/>
    <button onclick="deleteAllDate()">点我清空数据</button><br/>

    <script>
        let person = {
            name:"JOJO",
            age:20
        };

        function saveDate() {
            sessionStorage.setItem('msg', 'sessionStorage');
            sessionStorage.setItem('person', JSON.stringify(person));
        }
        function readDate() {
            console.log(sessionStorage.getItem('msg'));
            const person = sessionStorage.getItem('person');
            console.log(JSON.parse(person))
        }
        function deleteDate() {
            sessionStorage.removeItem('msg');
            sessionStorage.removeItem('person');
        }
        function deleteAllDate() {
            sessionStorage.clear();
        }
    </script>
</body>
</html>

使用本地存储优化Todo-List

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

<script> 
    // 引入组件
    import MyFooter from './components/MyFooter';
    import MyHeader from './components/MyHeader';
    import MyList from './components/MyList';

    export default { 
        name:'App', 
        components:{
            MyFooter,
            MyHeader,
            MyList
        },
        data() {
            return {
                // 从本地存储中获得数据,null就创建空数组[]
                todos: JSON.parse(localStorage.getItem('todos')) || []
            }
        },
        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) {
                this.todos = this.todos.filter( todo => todo.id !== id )
            },
            // 全选or取消全选 
            checkAllTodo(done){
                this.todos.forEach((todo)=>{
                    todo.done = done;
                });
            },
            // 清除所有已经完成的todo
            clearAllTodo(){
                this.todos = this.todos.filter((todo)=>{
                    return !todo.done;
                })
            }
        },
        // 数据发生改变就放到本地存储中,注意深度侦听,以及JSON转化为字符串
        watch: {
            todos: {
                deep:true,
                handler(value) {
                    localStorage.setItem('todos', JSON.stringify(value));
                }
            }
        }
    }
</script>

<style>
    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>

3.9. 组件的自定义事件

  1. 一种组件间通信的方式,适用于:子组件 ===> 父组件
  2. 使用场景:子组件想给父组件传数据,那么就要在父组件中给子组件绑定自定义事件(事件的回调在A中)
  3. 绑定自定义事件
    1. 第一种方式,在父组件中<Demo @事件名=“方法”/>或<Demo v-on:事件名=“方法”/>
    2. 第二种方式,在父组件中this. r e f s . d e m o . refs.demo. refs.demo.on(‘事件名’,方法)
      <Demo ref="demo"/>
      ......
      mounted(){
          this.$refs.xxx.$on('atguigu',this.test);
      }
      
    3. 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法
  4. 触发自定义事件this.$emit(‘事件名’,数据)
  5. 解绑自定义事件this.$off(‘事件名’)
  6. 组件上也可以绑定原生DOM事件,需要使用native修饰符 @click.native="show"上面绑定自定义事件,即使绑定的是原生事件也会被认为是自定义的,需要加native,加了后就将此事件给组件的根元素
  7. 注意:通过this. r e f s . x x x . refs.xxx. refs.xxx.on(‘事件名’,回调函数)绑定自定义事件时,回调函数要么配置在methods中,要么用箭头函数,否则 this 指向会出问题

src/App.vue

<template> 
    <div class="app">
        <h1>{{ msg }},学生姓名是:{{ studentName }}</h1>

        <!-- 通过父组件给子组件传递函数类型的props实现子给父传递数据 -->
        <School :getSchoolName="getSchoolName"/>

        <!-- 通过父组件给子组件绑定一个自定义事件实现子给父传递数据(第一种写法,使用@或v-on) -->
        <!-- <Student @atguigu="getStudentName" @demo="m1"/> -->

        <!-- 通过父组件给子组件绑定一个自定义事件实现子给父传递数据(第二种写法,使用ref) -->
        <Student ref="student" @click.native="show"/> <!-- 🔴native -->
    </div> 
</template> 

<script> 
    // 引入组件
    import Student from './components/Student.vue';
    import School from './components/School.vue';

    export default { 
        name:'App', 
        components:{ 
            Student,
            School
        },
        data() {
            return {
                msg:'你好啊!',
                studentName:''
            }
        },
        methods: {
            getSchoolName(name) {
                console.log('App收到了学校名:', name);
            },
            getStudentName(name,...params) {
                console.log('App收到了学生名:', name, params);
                this.studentName = name;
            },
            m1() { 
                console.log('demo事件被触发了!') 
            },
            show() { 
                alert(123);
            }
        },
        mounted() {
            this.$refs.student.$on('atguigu', this.getStudentName);
            // 绑定自定义事件 // this.$refs.student.$once('atguigu',this.getStudentName) // 绑定自定义事件(一次性)
        }
    }
</script>

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

src/components/Student.vue

<template>
    <div class="student">
        <h2>学生姓名:{{ name }}</h2>
        <h2>学生性别:{{ sex }}</h2>
        <h2>当前求和为:{{number}}</h2>
        <button @click="add">点我number++</button>
        <button @click="sendStudentlName">把学生名给App</button>
        <button @click="unbind">解绑atguigu事件</button>
        <button @click="death">销毁当前Student组件的实例(vc)</button>
    </div>
</template>

<script>
    export default {
        name:'Student',
        data() {
            return {
                name: "liqb",
                sex: '男',
                number:0
            }
        },
        methods: {
            add() {
                console.log('add回调被调用了');
                this.number++;
            },
            sendStudentlName() {
                // 触发Student组件实例身上的atguigu事件
                this.$emit('atguigu', this.name, 666, 888, 900);
                // this.$emit('demo');
                // this.$emit('click');
            },
            unbind() {
                // 解绑
                this.$off('atguigu') // 解绑一个自定义事件
                // this.$off(['atguigu','demo']) // 解绑多个自定义事件
                // this.$off() // 解绑所有的自定义事件
            },
            death() {
                // 销毁了当前Student组件的实例,销毁后所有Student实例的自定义事件全都不奏效
                this.$destroy();
            }
        }
    }
</script>

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

src/components/School.vue

<template>
    <div class="school">
        <h2 >学校地址:{{address}}</h2>
        <h2>学校名称:{{name}}</h2>
        <button @click="sendSchoolName">把学校名给App</button>
    </div>
</template>

<script>
    export default {
        name:'School',
        props: ['getSchoolName'],
        data() {
            return {
                name: "莆田学院",
                address: '福建莆田'
            }
        },
        methods: {
            sendSchoolName() {
                this.getSchoolName(this.name);
            }
        }
    }
</script>

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

使用自定义事件优化Todo-List

src/App.vue

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

<script> 
    // 引入组件
    import MyFooter from './components/MyFooter';
    import MyHeader from './components/MyHeader';
    import MyList from './components/MyList';

    export default { 
        name:'App', 
        components:{
            MyFooter,
            MyHeader,
            MyList
        },
        data() {
            return {
                // 从本地存储中获得数据,null就创建空数组[]
                todos: JSON.parse(localStorage.getItem('todos')) || []
            }
        },
        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) {
                this.todos = this.todos.filter( todo => todo.id !== id )
            },
            // 全选or取消全选 
            checkAllTodo(done){
                this.todos.forEach((todo)=>{
                    todo.done = done;
                });
            },
            // 清除所有已经完成的todo
            clearAllTodo(){
                this.todos = this.todos.filter((todo)=>{
                    return !todo.done;
                })
            }
        },
        // 数据发生改变就放到本地存储中,注意深度侦听,以及JSON转化为字符串
        watch: {
            todos: {
                deep:true,
                handler(value) {
                    localStorage.setItem('todos', JSON.stringify(value));
                }
            }
        }
    }
</script>

<style>
    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/MyHeader.vue

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

<script>
    import {nanoid} from 'nanoid';
    
    export default {
        name: "Header",
        data(){
            return {
                title:'' // 收集用户输入的title
            }
        },
        methods: {
            add(){
                // 校验数据
                if(!this.title.trim()) return alert('输入不能为空')
                // 将用户的输入包装成一个todo对象
                const todoObj = { 
                    id: nanoid(), 
                    title:this.title, 
                    done:false 
                };
                // 通知App组件去添加一个todo对象
                this.$emit('addTodo', todoObj);
                // 清空输入
                this.title = '';
            }
        }
    }
</script>

<style scoped>
    .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>

src/components/MyFooter文章来源地址https://www.toymoban.com/news/detail-466320.html

<template>
    <div class="todo-footer" v-show="total">
        <label>
            <input type="checkbox" v-model="isAll"/>
        </label>
        <span>
            <span>已完成{{doneTotal}}</span> / 全部{{total}}
        </span>
        <button class="btn btn-danger" @click="clearAll">清除已完成任务</button>
    </div>
</template>

<script>
    export default {
        name: "Footer",
        props: ['todos'],
        computed: {
            // 总数
            total() {
              return this.todos.length;  
            },
            // 已完成数
            doneTotal() {
                // 此处使用reduce方法做条件统计
                return this.todos.reduce((pre, todo) => pre + (todo.done ? 1 : 0), 0);
            },
            // 控制全选框
            isAll:{
                // 全选框是否勾选
                get(){
                    return this.doneTotal === this.total && this.total > 0;
                },
                // isAll被修改时set被调用
                set(value){
                    this.$emit('checkAllTodo', value);
                }
            }
        },
        methods: {
            clearAll() {
                this.$emit('clearAllTodo');
            }
        }
    }
</script>

<style scoped>
    .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>

到了这里,关于Vue CLI 本地存储 自定义事件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue cli创建项目时键盘操作无效;vue3.0项目搭建自定义配置

    在创建vue3.0项目时,在建好的文件夹,鼠标右键 git bash 使用 vue create my-vue3.0创建新项目时,键盘方向键失效,无法选中对应的选项(交互提示符不工作) 方案一 使用电脑自带的 cmd 运行 vue create my-vue3.0。 方案一 在 git bash 窗口中用 winpty vue.cmd create demo 命令创建项目。只是换

    2024年04月09日
    浏览(35)
  • vue-cli自定义创建项目-eslint依赖冲突解决方式

    创建项目步骤 概览: 在安装 npm安装时会报错 依赖冲突原因: @vue/eslint-config-standard@6.1.0 依赖于 eslint-plugin-vue 的 ^7.0.0 版本,但是项目中安装了更高版本的 eslint-plugin-vue 解决方式:降级eslint-plugin-vue到@vue/eslint-config-standard支持的版本 解决后: 再进行npm安装,就能成功

    2024年04月09日
    浏览(40)
  • vue-cli4前端实现下载本地Excel模板,以及下载静态文件的坑

    a标签的下载功能: 1:bobl ----二进制流文件 Blob对象标识一个不可变、原始数据的类文件对象。Blob表示的不一定是JavaScript原生格式的数据 2:responseType responseType它表示服务器响应的数据类型,由于后台返回来的是二进制数据,所以要把它设为‘blob’ 通过设置responseType为blo

    2024年02月02日
    浏览(34)
  • Vue:插槽,与自定义事件

                 

    2024年02月11日
    浏览(29)
  • Vue2:解绑自定义事件

    上一节,我们学习了,自定义事件绑定到组件上。 现在,我们学习下,给组件解绑自定义事件的几种方法。 首先,我们试想一下,这个功能的适用场景? 一般同学都会想,解绑?那就注释掉代码就是了呗。 这个办法也可以,但是,不好,因为每次都要修改代码。 现在,我

    2024年01月18日
    浏览(37)
  • Vue本地存储及用法

    目录 1.本地存储是什么? 2.本地存储的应用场景 3.存储的使用 4. 练习用法 1.本地存储是什么?         以文件的方式存储在本地,通过把数据存在浏览器中,用户不必每次都向服务器请求 获取同一个信息。在你离线时,使用本地存储的数据而不是向远端服务器上请求 数

    2024年02月09日
    浏览(38)
  • vue小测试之拖拽、自定义事件

    在开始之前我去复习了一下,clientX、clientY、pageX、pageY的区别,对于不熟悉offsetLeft和offsetTop的也可以在这里去复习一下。 vue拖拽指令之offsetX、clientX、pageX、screenX_wade3po的博客-CSDN博客_vue offset 鼠标事件都是在浏览器视口中的特定位置发生的。这个位置信息保存在事件对象的

    2024年02月09日
    浏览(28)
  • Vue2:给组件绑定自定义事件

    我们在页面开发中,难免要使用事件。 在之前的学习中,我们学过 @click、@keyup、@change 等事件,这些是 Vue 自带的事件。 它一般是用在原生的HTML元素上的。在组件上使用需要加 native 修饰 比如: 这一篇说的自定义事件,可以绑定到我们自己的 Vue 组件上。 实现 子组件给父组

    2024年01月19日
    浏览(42)
  • Vue 组件化: 计算属性、内容分发、自定义事件

    目录 1. 计算属性 1.1 计算属性的特点 2. 内容分发 2.1 使用插槽的示例 3. 自定义事件 什么是计算属性 ? 计算属性的重点突出在 属性 两字, 首先它是个 属性 , 其次这个属性有 计算 的能力, 这里的计算就是个函数; 简单来说, 它就是一个能够将计算结果缓存起来的属性 (将行为转

    2024年02月08日
    浏览(38)
  • Vue中TodoList案例_本地存储

    App.vue 效果 :数据存储再localStroage中,刷新浏览器保存的数据仍在。   

    2024年02月15日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包