web本地存储
浏览器通过Window.localStorage和Window.sessionStorage属性实现本地存储机制
四个API:setItem().getItem().removeItem().clear()
localStorage
<body>
<h2>localStorage</h2>
<button onclick="saveData()">点我保存一个数据</button>
<button onclick="readData()">点我读取一个数据</button>
<button onclick="deleteData()">点我删除一个数据</button>
<button onclick="deleteAllData()">点我删除所有数据</button>
<script>
let p={name:"张三",age:18}
function saveData(){
localStorage.setItem("msg1","Hello")
localStorage.setItem("msg2","8888888")
localStorage.setItem("msg3",JSON.stringify(p)) // 用JSON.stringify()将数据转化为JSON字符串
}
function readData(){ //先保存后读取,读取有输出
console.log(localStorage.getItem("msg1"))
console.log(localStorage.getItem("msg2"))
const result=localStorage.getItem("msg3")
console.log(JSON.parse(result)) //用JSON.parse方法解析JSON字符串
console.log(localStorage.getItem("msg4")) //没有msg4,所以读取结果是null
}
function deleteData(){ //先保存后读取
localStorage.removeItem("msg1")
}
function deleteAllData(){
localStorage.clear() //删除所有数据,不是clearItem()
}
</script>
</body>
sessionStorage
和 localStorage用法相同,但是localStorage当上次搜索过的页面再次打开时还有搜索记录,但是sessionStorage无搜索记录
TodoList案例-存储完善
App.vue
// 进行本地存储,使用户可以在刷新页面的基础上保留其添加删除的数据
// 首先对数据进行保存,那么要监视todos是否发生变化,发生变化就用新的todos取代
watch:{
todos:{
deep:true, //深度监视,当刷新时勾选的内容不会消失
handler(newvalue){ //handle(newvalue,oldvalue)新的todos和旧的todos
localStorage.setItem("todos",JSON.stringify(newvalue))
}
}
data(){
return {
// todos:[
// {id:"001",title:"打代码",done:"true"}, //id一般用字符串,done表示完成
// {id:"002",title:"睡觉",done:"false"},
// {id:"003",title:"吃饭",done:"true"}
// ]
// 读取数据
todos:JSON.parse(localStorage.getItem("todos")) || []
// 如果不加" || []",当用户什么也不输入,todos取空数组,而不会报错(其他组件用到todos可能会报错)
}
},
组件自定义事件
自定义绑定事件
要求通过点击按钮将StudentInfo和SchoolInfo组件中的学生学校名字传给App(子组件传给父组件)
有三种方式:
通过父组件给子组件传递函数类型的props实现:子给父传递数据(同样实现子传父,但是不属于自定义事件)
App.vue
<SchoolInfo :getSchoolName="getSchoolName"></SchoolInfo>
methods:{
//把学校名字给App
getSchoolName(schoolname){
console.log("@@@",schoolname)
},
SchoolInfo.vue
<button @click="sendSchoolName">点我把学校名字给App</button>
props:["getSchoolName"],
methods:{
sendSchoolName(){
this.getSchoolName(this.schoolName)
}
}
第一种方法:通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(使用@或v-on)
App.vue
<StudentInfo @xuesheng="getStudentName"/>
methods:{
//把学生名字给App
getStudentName(studentname){
console.log("@@@",studentname)
}
},
StudentInfo.vue
<button @click="sendSchoolName">点我把学校名字给App</button>
methods:{
sendSchoolName(){
// 触发studentInfo组件实例身上的xuesheng事件
this.$emit("xuesheng",this.studentName)
}
}
第二种方法:通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(使用ref)
App.vue
<StudentInfo ref="student"/>
//把学生名字给App
getStudentName(studentname){
console.log("@@@",studentname)
}
},
mounted(){
this.$refs.student.$on("xuesheng",this.getStudentName)
}
}
StudentInfo.vue
<button @click="sendSchoolName">点我把学校名字给App</button>
methods:{
sendSchoolName(){
// 触发studentInfo组件实例身上的xuesheng事件
this.$emit("xuesheng",this.studentName)
}
}
显示传入App中的名字:
App.vue
<h2>传给App的名字是:{{name}}</h2>
data(){
return {
msg:"你好啊",
name:""
}
//把学生名字给App
getStudentName(studentname){
console.log("@@@",studentname)
this.name=studentname //在App中写入传入参数
},
解绑
给谁添加的自定义事件,就去对应组件中添加解绑事件
根据上边可知给StudentInfo组件添加的自定义事件,所以在StudentInfo中解绑
StudentInfo.vue
<button @click="unbind">点我解绑</button>
"shili"是为了解释解绑多个而新添加的一个自定义事件
// 解绑
unbind(){ //绑定、触发、解绑都写自定义的名称
//this.$off("xuesheng") //只适合解绑一个
this.$off(["xuesheng","shili"]) //适合解绑多个(要用数组)
// this.$off() //所有自定义事件全部解绑
}