Vue2-浏览器本地存储(WebStorage)及完善TodoList案例、组件自定义事件及完善TodoList案例

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

🥔:山不向我走来,我便向它走去
更多Vue知识请点击——Vue.js

一、浏览器本地存储(WebStorage)

存储内容大小一般支持5MB左右(不同浏览器可能还不一样)
浏览器端通过 Window.sessionStorageWindow.localStorage 属性来实现本地存储机制。

1.相关API

(1) xxxxxStorage.setItem('key', 'value');该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。
(2) xxxxxStorage.getItem('person');该方法接受一个键名作为参数,返回键名对应的值。
(3) xxxxxStorage.removeItem('key');该方法接受一个键名作为参数,并把该键名从存储中删除。
(4)xxxxxStorage.clear()该方法会清空存储中的所有数据。

  • localStorage
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>localStorage</title>
  </head>
  <body>
    <h2>localStorage</h2>
    <button onclick="saveDate()">点我保存一个数据</button>
    <button onclick="readDate()">点我读取一个数据</button>
    <button onclick="deleteDate()">点我删除一个数据</button>
    <button onclick="deleteAllDate()">点我清空一个数据</button>
  </body>
  <script>
    let p = {
      name: '张三',
      age: 18,
    }
    function saveDate() {
      localStorage.setItem('msg', 'hello!')
      localStorage.setItem('msg2', 666)
      localStorage.setItem('person', JSON.stringify(p))
    }
    function readDate() {
      console.log(localStorage.getItem('msg'))
      console.log(localStorage.getItem('msg2'))

      const result = localStorage.getItem('person')
      console.log(result)
      console.log(localStorage.getItem('msg3')) //由于没有msg3所以返回null
    }
    function deleteDate() {
      localStorage.removeItem('msg2')
    }
    function deleteAllDate() {
      localStorage.clear()
    }
  </script>
</html>
  • SessionStorage
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>sessionStorage</title>
  </head>
  <body>
    <h2>sessionStorage</h2>
    <button onclick="saveDate()">点我保存一个数据</button>
    <button onclick="readDate()">点我读取一个数据</button>
    <button onclick="deleteDate()">点我删除一个数据</button>
    <button onclick="deleteAllDate()">点我清空一个数据</button>
  </body>
  <script>
    let p = {
      name: '张三',
      age: 18,
    }
    function saveDate() {
      sessionStorage.setItem('msg', 'hello!')
      sessionStorage.setItem('msg2', 666)
      sessionStorage.setItem('person', JSON.stringify(p))
    }
    function readDate() {
      console.log(sessionStorage.getItem('msg'))
      console.log(sessionStorage.getItem('msg2'))

      const result = sessionStorage.getItem('person')
      console.log(result)
      console.log(sessionStorage.getItem('msg3')) //由于没有msg3所以返回null
    }
    function deleteDate() {
      sessionStorage.removeItem('msg2')
    }
    function deleteAllDate() {
      sessionStorage.clear()
    }
  </script>
</html>

2.一些注意点

(1)SessionStorage存储的内容会随着浏览器窗口关闭而消失
(2) LocalStorage存储的内容,需要手动清除才会消失(调用clear或者清除缓存)。
(3) xxxxxStorage.getItem(xxx)如果xxx对应的value获取不到,那么getItem的返回值是null
(4)JSON.parse(null)的结果依然是null。

3.TodoList中的本地存储

我们上一次做的案例(TodoList案例)还不够完善,当我们重新刷新页面时,我们的数据就会丢失,这里我们可以利用本地存储,让数据存储下来。

这里面的几个细节:
1、用watch监视todos数据的变化,如果数据改变那么浏览器本地存储就存个缓存,名字还叫todos,值是更新后的数组

  • 要转化为JSON字符串(JSON.stringify())浏览器才能显示

2、只监视是没用的,如果只监视不读取,那么数据会缓存到浏览器,但是页面刷新网页不会同步,所以一定要在data中读取浏览器中的数据,当然页面一上来可能没有缓存(也没添加任何数据),那么这时候JSON.parse(localStorage.getItem('todos'))就是null(这样会报错的),所以再来个逻辑或,如果是null那么就todos初始化为空数组,然后再自己往里加数据,后面再刷新就会直接读浏览器了(总结:初始化时如果有就读,没有就初始值为空数组)

3、还有,watch中要配置深度监视deep,否则页面刷新已经勾选的就重置了,这是因为watch监视todos只会监视todos里面的元素,也就是每个对象的地址,但是对象属性的变化监测不到,但是加了deep就监视到了

data() {
        return {
            // JSON.parse将格式完好的json字符串转换为json对象
            //如果有就读,没有就初始值为空数组
            todos: JSON.parse(localStorage.getItem('todos')) || []
        };
    },
watch: {
    //这个写法只能监视到todo对象的增加删除这些浅层的,如果想监视到里面属性的变化,比如done的true还是false,就要开启深度监视
    // todos(value) {
    //   localStorage.setItem('todos', JSON.stringify(value))
    // },
    todos: {
      //开启深度监视
      deep: true,
      handler(value) {
        localStorage.setItem('todos', JSON.stringify(value))
      },
    },
  },
  • JSON.stringify将Js对象或值转换为JSON格式化的字符串
  • JSON.parse将格式完好的json字符串转换为json对象

二、组件自定义事件

组件自定义事件是指在Vue中,我们可以自己定义并使用的事件。与内置事件不同,组件自定义事件是由开发者自己定义的,包含事件名和事件回调等内容。它是一种用于组件间通信的方式,特别适用于子组件向父组件传递数据通过定义好的自定义事件,我们可以在子组件中触发事件,并将需要传递的数据作为参数传递给父组件。这样,父组件就可以在事件回调中获取到子组件传递过来的数据,并进行相应的处理

1、引出组件自定义事件

在之前我们想要实现子组件给父组件传数据,都是通过父组件给子组件传递函数类型的props实现,此处要求School.vue把name传给App.vue。我们以前的做法如下:

  • App.vue:
<template>
  <div class="app">
    <h1>{{ msg }}</h1>
    <!-- 通过父组件给子组件传递函数类型的props实现:子给符传递数据 -->
    <School :getSchoolName="getSchoolName" />
  </div>
</template>

<script>
import School from './components/School.vue'
export default {
  name: 'App',
  components: { School },
  data() {
    return {
      msg: '你好呀',
    }
  },
  methods: {
    getSchoolName(name) {
      console.log('App收到了学校名:', name)
    },
  },
}
</script>

<style>
.app {
  background-color: gray;
}
</style>
  • School.vue:在School中使用props接收,然后把name传过来。
<template>
  <div class="school">
    <h2>学校名称:{{ name }}</h2>
    <h2>学校地址:{{ address }}</h2>
    <button @click="sendSchoolName">把学校名给App</button>
  </div>
</template>

<script>
export default {
  name: 'School',
  // 然后在School中使用props接收,然后把name传过来。
  props: ['getSchoolName'],
  data() {
    return {
      name: '哈哈大学',
      address: '比奇堡',
    }
  },
  methods: {
    sendSchoolName() {
      this.getSchoolName(this.name)
    },
  },
}
</script>

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

2、给组件绑定自定义事件

(1)使用v-on

上面的子给父传数据,如今我们也可以换一种方式实现,那就是通过父组件给子组件绑定一个自定义事件实现。www事件被触发,就会调用getStudentName

然后在Student组件中触发这个事件,使用$emit,第一个参数是事件名,后面的是实参,使用函数可以触发Student中的zzy事件

  • App.vue:
<template>
  <div class="app">
    <h1>{{ msg }}</h1>
    <!-- 通过父组件给子组件绑定一个自定义事件实现:子给符传递数据(第一种写法,使用v-on或@) -->
    <Student v-on:www="getStudentName" />
  </div>
</template>

<script>
import Student from './components/Student.vue'
export default {
  name: 'App',
  components: { Student },
  data() {
    return {
      msg: '你好呀',
    }
  },
  methods: {
    getStudentName(name) {
      console.log('App收到了学生名:', name)
    },
  },
}
</script>

<style>
.app {
  background-color: gray;
}
</style>
  • Student.vue:
<template>
  <div class="student">
    <h2>学生姓名:{{ name }}</h2>
    <h2>学生性别:{{ sex }}</h2>
    <h2>学生年龄:{{ age }}</h2>
    <button @click="sendStudentName">把学生名给App</button>
  </div>
</template>

<script>
export default {
  name: 'Student',
  data() {
    return {
      name: 'potato',
      sex: '女',
      age: 18,
    }
  },
  methods: {
    sendStudentName() {
      //触发Student组件实例身上的www事件
      this.$emit('www', this.name)
    },
  },
}
</script>

<style scoped>
.student {
  background-color: pink;
}
</style>
(2)使用ref

使用ref也可以让父组件给子组件绑定一个自定义事件。

使用ref获取组件实例,然后使用$on绑定zzy事件,第一个参数是事件名,第二个参数是事件触发后的回调函数。
触发方式和上面一样,用$emit
如果想只触发一次,用$once

  • App.vue:
<template>
  <div class="app">
    <h1>{{ msg }}</h1>
    <!-- 通过父组件给子组件绑定一个自定义事件实现:子给符传递数据(第一种写法,使用v-on或@) -->
    <!-- <Student v-on:www="getStudentName" /> -->

    <!-- 通过父组件给子组件绑定一个自定义事件实现:子给符传递数据(第二种方法,使用ref属性) -->
    <Student ref="student" />
  </div>
</template>

<script>
import Student from './components/Student.vue'
export default {
  name: 'App',
  components: { Student },
  data() {
    return {
      msg: '你好呀',
    }
  },
  methods: {
    getStudentName(name) {
      console.log('App收到了学生名:', name)
    },
  },
   mounted() {
     // this.$refs.student.name???
     setTimeout(() => {
       //挂载完成后,隔3秒再给Student绑定事件
       this.$refs.student.$on('www', this.getStudentName)
     }, 3000)
   },
}
</script>

<style>
.app {
  background-color: gray;
}
</style>
  • Student.vue:
<template>
  <div class="school">
    <h2>学习名称:{{ name }}</h2>
    <h2>学校地址:{{ address }}</h2>
    <button @click="sendSchoolName">把学校名给App</button>
  </div>
</template>

<script>
export default {
  name: 'School',
  // 在School中使用props接收,然后把name传过来。
  props: ['getSchoolName'],
  data() {
    return {
      name: '哈哈大学',
      address: '比奇堡',
    }
  },
  methods: {
    sendSchoolName() {
      this.getSchoolName(this.name)
    },
  },
}
</script>

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

这种写法更灵活,可以异步。仔细观察使用v-on和ref的区别。

注意:

  • 通过this.$refs.xxx.$on('xxx',回调)绑定自定义事件时,回调要么配置在methods中然后通过this.getStudentName传过来,要么用箭头函数,否则this指向会出问题。

3、解绑自定义事件

使用$off解绑

$destroy销毁组件实例(组件的所有自定义事件会失效)

    <Student v-on:www="getStudentName" />
<template>
  <div class="student">
    <h2>学生姓名:{{ name }}</h2>
    <h2>学生性别:{{ sex }}</h2>
    <h2>学生年龄:{{ age }}</h2>
    <button @click="add">点我年龄+1</button>
    <button @click="sendStudentName">把学生名给App</button>
    <button @click="unbind">解绑www事件</button>
    <button @click="death">销毁当前Student组件的实例</button>
  </div>
</template>

<script>
export default {
  name: 'Student',
  data() {
    return {
      name: 'potato',
      sex: '女',
      age: 18,
    }
  },
  methods: {
    add() {
      this.age++
    },
    sendStudentName() {
      //触发Student组件实例身上的www事件
      this.$emit('www', this.name)
    },
    unbind() {
      this.$off('www') //解绑一个自定义事件
      // this.$off(['www', 'one', 'two']) //解绑多个自定义事件
      // this.$off() //解绑所有自定义事件
    },
    death() {
      this.$destroy() //销毁当前Student组件的实例,销毁后所有Student实例的自定义事件全部不奏效
    },
  },
}
</script>

<style scoped>
.student {
  background-color: pink;
}
</style>
  • 组件上写的v-on都会被当成自定义事件,即便是写@click也会当成自定义事件,想要用原生DOM事件的话,需要加native,比如@click.native = "demo"

4、总结

1、一种组件间通信的方式,适用于:子组件 ===> 父组件
2、使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B的标签绑定自定义事件(事件的回调在A中,用来接收数据)。
3、绑定自定义事件:
(1) 第一种方式,在父组件中:

<Demo @www="test"/>或 <Demo v-on:www="test"/>

(2)第二种方式,在父组件中:

<Demo ref="demo"/>
 ...... 
mounted(){ this.$refs.xxx.$on('www',this.test) }

(3)若想让自定义事件只能触发一次,可以使用.once修饰符,或$once方法。

4、触发自定义事件:this. e m i t ( ′ a t g u i g u ′ , 数据 ) 给谁绑的就找谁触发 5 、解绑自定义事件 t h i s . emit('atguigu',数据)给谁绑的就找谁触发 5、解绑自定义事件this. emit(atguigu,数据)给谁绑的就找谁触发5、解绑自定义事件this.off(‘atguigu’)
6、组件上也可以绑定原生DOM事件,需要使用native修饰符。
7、注意:通过this. r e f s . x x x . refs.xxx. refs.xxx.on(‘atguigu’,回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!

5、案例:给TodoList添加自定义事件

Header和Footer用到了子传父(Item是孙传父了,自定义事件没发解决)
App里标签写,Header里触发,然后把值传过去。

此处只展示改动部分:

  • App.vue:
<TodolistHeader @addTodo="addTodo" />
<TodolistFooter
	:todos="todos"
	@checkAllTodo="checkAllTodo"
	@clearAllTodo="clearAllTodo"
/>
  • TodolistHeader.vue:
//3.借助App里的函数,把用户的输入从Header传给App里面的todos 然后再通过App把todos传给List,用这种捷径(借助App)就巧妙地实现了Header和List的兄弟组件通信
// this.addTodo(todoObj)
//使用自定义函数
this.$emit('addTodo', todoObj)
  • TodolistFooter.vue:
methods: {
    checkAll(e) {
      // this.checkAllTodo(e.target.checked)
      this.$emit('checkAllTodo', e.target.checked)
    },
    clearAll() {
      // this.clearAllTodo() //点击调用App里边的方法,把所有为true的删掉
      this.$emit('clearAllTodo')
    },
  },

此处不使用props了记得把props里的对应项删掉文章来源地址https://www.toymoban.com/news/detail-664721.html

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

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

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

相关文章

  • vue2/3 - 解决报错 error:0308010C:digital envelope routines::unsupported(vue项目运行run或打包build时浏览器控制台报错,详细解决

    在vue2、vue3项目中,报错:error:0308010C:digital envelope routines::unsupported。vue运行编译时、上线打包后出现大概率会出现这个错误,很奇怪的报错。 其他解决教程几乎无效,本博客可完美搞定这个问题。 首先,这个错误

    2024年04月23日
    浏览(33)
  • 浏览器获取本地IP地址(不是浏览器的url地址的ip)

    浏览器输入: edge://flags/#enable-webrtc-hide-local-ips-with-mdns Anonymize local IPs exposed by WebRTC 状态改为disable JS方法: function f() { if(typeof window != \\\'undefined\\\'){ var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; var rtc = new RTCPeerConnection() rtc.createDataChannel(\\\'\\\'

    2024年02月02日
    浏览(45)
  • selenium 调用本地浏览器插件

    本文所有教程及源码、软件仅为技术研究。不涉及计算机信息系统功能的删除、修改、增加、干扰,更不会影响计算机信息系统的正常运行。不得将代码用于非法用途,如侵立删! selenium 使用本地浏览器插件 环境 win10 Python3.9 selenium 4.10 查看chrome配置文件路径 地址栏输入 ​

    2024年02月09日
    浏览(57)
  • oss/obs对象存储上传图片,在浏览器输入地址却是下载图片。不能直接在浏览器上查看。

    1.问题 oss/obs对象存储上传图片获取链接地址后,在浏览器输入地址却是下载。不能直接在浏览器上面浏览图片信息。 2.解决 上传文件的时候需要设置:content-type类型,需要指示浏览器这是什么类型,这样才能在浏览器上面浏览图片信息。浏览器是根据response-headerl里面的Con

    2024年02月15日
    浏览(30)
  • web浏览器打开本地exe应用

    浏览器打开本地exe程序我们可以使用ActiveXObject方法,但是只支持IE,谷歌、火狐等浏览器并不支持此操作。 那问题来了,我们又该如何操作? 经过本博主的不断学习探索终于找到了一条,像百度网盘那样打本地exe应用的办法。我们可以通过添加注册表. 向系统添加一个类似于

    2024年02月13日
    浏览(32)
  • Docker本地部署Firefox火狐浏览器并远程访问

    🔥 博客主页 : 小羊失眠啦. 🎥 系列专栏 : 《C语言》 《数据结构》 《Linux》 《Cpolar》 ❤️ 感谢大家点赞👍收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 Firefox是一款免费开源的网页浏览器

    2024年02月05日
    浏览(48)
  • 用谷歌浏览器打开本地unity webgl报错

    unity打包webgl,双击index.html,用谷歌浏览器打开,报错: Failed to download file Build/Test4_Build_WebGL.framework.js.unityweb. Loading web pages via a file:// URL without a web server is not supported by this browser. Please use a local development web server to host Unity content, or use the Unity Build and Run option. 可以把文件放到

    2024年02月11日
    浏览(52)
  • 浏览器js打开本地exe程序(超详细、可用)

    目的::打开游览器链接,弹出打开本地exe操作 新建txt文件输入以下代码,可自行配置路径,路径必须为\\\\,且最后的 不可省略。 保存txt文件,并修改为xxx.reg文件。最后双击运行 执行HTML代码即可实现目的   双击66666666666666666666

    2024年02月11日
    浏览(44)
  • js~在浏览器中对用户名和密码进行存储

    btoa() 和 atob() 是 JavaScript 中的标准函数,通常在现代浏览器中都能正常工作。然而,它们在处理非 ASCII 字符时可能存在一些兼容性问题。 这些函数的主要限制在于它们仅支持 ASCII 字符集,对于非 ASCII 字符(如 Unicode 字符)可能会产生不可预测的结果。在处理非 ASCII 字符时

    2024年02月09日
    浏览(30)
  • 浏览器的存储,cookie(httponly)、localStorage、sessionStorage、indexed对比

    浏览器提供了多种客户端存储机制,每种机制都有其特定的用途、特性和限制。以下是对 cookie 、 localStorage 、 sessionStorage 和 IndexedDB 的对比: 1. Cookie 存储大小 : 通常限制为4KB。 生命周期 : 可以设置过期时间。如果没有设置,它的生命周期将与会话持续相同,即关闭浏览器后

    2024年02月10日
    浏览(32)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包