??:山不向我走來,我便向它走去
更多Vue知識請點擊——Vue.js
一、瀏覽器本地存儲(WebStorage)
存儲內(nèi)容大小一般支持5MB左右(不同瀏覽器可能還不一樣)
瀏覽器端通過 Window.sessionStorage
和 Window.localStorage
屬性來實現(xiàn)本地存儲機制。
1.相關(guān)API
(1) xxxxxStorage.setItem('key', 'value');
該方法接受一個鍵和值作為參數(shù),會把鍵值對添加到存儲中,如果鍵名存在,則更新其對應(yīng)的值。
(2) xxxxxStorage.getItem('person');
該方法接受一個鍵名作為參數(shù),返回鍵名對應(yīng)的值。
(3) xxxxxStorage.removeItem('key');
該方法接受一個鍵名作為參數(shù),并把該鍵名從存儲中刪除。
(4)xxxxxStorage.clear()
該方法會清空存儲中的所有數(shù)據(jù)。
- 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()">點我保存一個數(shù)據(jù)</button>
<button onclick="readDate()">點我讀取一個數(shù)據(jù)</button>
<button onclick="deleteDate()">點我刪除一個數(shù)據(jù)</button>
<button onclick="deleteAllDate()">點我清空一個數(shù)據(jù)</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()">點我保存一個數(shù)據(jù)</button>
<button onclick="readDate()">點我讀取一個數(shù)據(jù)</button>
<button onclick="deleteDate()">點我刪除一個數(shù)據(jù)</button>
<button onclick="deleteAllDate()">點我清空一個數(shù)據(jù)</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
存儲的內(nèi)容會隨著瀏覽器窗口關(guān)閉而消失。
(2) LocalStorage
存儲的內(nèi)容,需要手動清除才會消失(調(diào)用clear或者清除緩存)。
(3) xxxxxStorage.getItem(xxx)
如果xxx對應(yīng)的value獲取不到,那么getItem的返回值是null。
(4)JSON.parse(null)
的結(jié)果依然是null。
3.TodoList中的本地存儲
我們上一次做的案例(TodoList案例)還不夠完善,當我們重新刷新頁面時,我們的數(shù)據(jù)就會丟失,這里我們可以利用本地存儲,讓數(shù)據(jù)存儲下來。
這里面的幾個細節(jié):
1、用watch監(jiān)視todos數(shù)據(jù)的變化,如果數(shù)據(jù)改變那么瀏覽器本地存儲就存?zhèn)€緩存,名字還叫todos,值是更新后的數(shù)組
- 要轉(zhuǎn)化為JSON字符串(
JSON.stringify()
)瀏覽器才能顯示
2、只監(jiān)視是沒用的,如果只監(jiān)視不讀取,那么數(shù)據(jù)會緩存到瀏覽器,但是頁面刷新網(wǎng)頁不會同步,所以一定要在data中讀取瀏覽器中的數(shù)據(jù),當然頁面一上來可能沒有緩存(也沒添加任何數(shù)據(jù)),那么這時候JSON.parse(localStorage.getItem('todos'))
就是null(這樣會報錯的),所以再來個邏輯或,如果是null那么就todos初始化為空數(shù)組,然后再自己往里加數(shù)據(jù),后面再刷新就會直接讀瀏覽器了(總結(jié):初始化時如果有就讀,沒有就初始值為空數(shù)組)
3、還有,watch中要配置深度監(jiān)視deep,否則頁面刷新已經(jīng)勾選的就重置了,這是因為watch監(jiān)視todos只會監(jiān)視todos里面的元素,也就是每個對象的地址,但是對象屬性的變化監(jiān)測不到,但是加了deep就監(jiān)視到了
data() {
return {
// JSON.parse將格式完好的json字符串轉(zhuǎn)換為json對象
//如果有就讀,沒有就初始值為空數(shù)組
todos: JSON.parse(localStorage.getItem('todos')) || []
};
},
watch: {
//這個寫法只能監(jiān)視到todo對象的增加刪除這些淺層的,如果想監(jiān)視到里面屬性的變化,比如done的true還是false,就要開啟深度監(jiān)視
// todos(value) {
// localStorage.setItem('todos', JSON.stringify(value))
// },
todos: {
//開啟深度監(jiān)視
deep: true,
handler(value) {
localStorage.setItem('todos', JSON.stringify(value))
},
},
},
-
JSON.stringify
將Js對象或值轉(zhuǎn)換為JSON格式化的字符串 -
JSON.parse
將格式完好的json字符串轉(zhuǎn)換為json對象
二、組件自定義事件
組件自定義事件是指在Vue中,我們可以自己定義并使用的事件。與內(nèi)置事件不同,組件自定義事件是由開發(fā)者自己定義的,包含事件名和事件回調(diào)等內(nèi)容。它是一種用于組件間通信的方式,特別適用于子組件向父組件傳遞數(shù)據(jù)。通過定義好的自定義事件,我們可以在子組件中觸發(fā)事件,并將需要傳遞的數(shù)據(jù)作為參數(shù)傳遞給父組件。這樣,父組件就可以在事件回調(diào)中獲取到子組件傳遞過來的數(shù)據(jù),并進行相應(yīng)的處理。
1、引出組件自定義事件
在之前我們想要實現(xiàn)子組件給父組件傳數(shù)據(jù),都是通過父組件給子組件傳遞函數(shù)類型的props實現(xiàn),此處要求School.vue把name傳給App.vue。我們以前的做法如下:
- App.vue:
<template>
<div class="app">
<h1>{{ msg }}</h1>
<!-- 通過父組件給子組件傳遞函數(shù)類型的props實現(xiàn):子給符傳遞數(shù)據(jù) -->
<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
上面的子給父傳數(shù)據(jù),如今我們也可以換一種方式實現(xiàn),那就是通過父組件給子組件綁定一個自定義事件實現(xiàn)。www
事件被觸發(fā),就會調(diào)用getStudentName
。
然后在Student組件中觸發(fā)這個事件,使用$emit
,第一個參數(shù)是事件名,后面的是實參,使用函數(shù)可以觸發(fā)Student中的zzy事件
- App.vue:
<template>
<div class="app">
<h1>{{ msg }}</h1>
<!-- 通過父組件給子組件綁定一個自定義事件實現(xiàn):子給符傳遞數(shù)據(jù)(第一種寫法,使用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() {
//觸發(fā)Student組件實例身上的www事件
this.$emit('www', this.name)
},
},
}
</script>
<style scoped>
.student {
background-color: pink;
}
</style>
(2)使用ref
使用ref也可以讓父組件給子組件綁定一個自定義事件。
使用ref獲取組件實例,然后使用$on
綁定zzy事件,第一個參數(shù)是事件名,第二個參數(shù)是事件觸發(fā)后的回調(diào)函數(shù)。
觸發(fā)方式和上面一樣,用$emit
如果想只觸發(fā)一次,用$once
- App.vue:
<template>
<div class="app">
<h1>{{ msg }}</h1>
<!-- 通過父組件給子組件綁定一個自定義事件實現(xiàn):子給符傳遞數(shù)據(jù)(第一種寫法,使用v-on或@) -->
<!-- <Student v-on:www="getStudentName" /> -->
<!-- 通過父組件給子組件綁定一個自定義事件實現(xiàn):子給符傳遞數(shù)據(jù)(第二種方法,使用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的區(qū)別。
注意:
- 通過
this.$refs.xxx.$on('xxx',回調(diào))
綁定自定義事件時,回調(diào)要么配置在methods中然后通過this.getStudentName
傳過來,要么用箭頭函數(shù),否則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() {
//觸發(fā)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、總結(jié)
1、一種組件間通信的方式,適用于:子組件 ===> 父組件
2、使用場景:A是父組件,B是子組件,B想給A傳數(shù)據(jù),那么就要在A中給B的標簽綁定自定義事件(事件的回調(diào)在A中,用來接收數(shù)據(jù))。
3、綁定自定義事件:
(1) 第一種方式,在父組件中:
<Demo @www="test"/>或 <Demo v-on:www="test"/>
(2)第二種方式,在父組件中:
<Demo ref="demo"/>
......
mounted(){ this.$refs.xxx.$on('www',this.test) }
(3)若想讓自定義事件只能觸發(fā)一次,可以使用.once修飾符,或$once方法。
4、觸發(fā)自定義事件:this.
e
m
i
t
(
′
a
t
g
u
i
g
u
′
,
數(shù)據(jù)
)
給誰綁的就找誰觸發(fā)
5
、解綁自定義事件
t
h
i
s
.
emit('atguigu',數(shù)據(jù))給誰綁的就找誰觸發(fā) 5、解綁自定義事件this.
emit(′atguigu′,數(shù)據(jù))給誰綁的就找誰觸發(fā)5、解綁自定義事件this.off(‘a(chǎn)tguigu’)
6、組件上也可以綁定原生DOM事件,需要使用native修飾符。
7、注意:通過this.
r
e
f
s
.
x
x
x
.
refs.xxx.
refs.xxx.on(‘a(chǎn)tguigu’,回調(diào))綁定自定義事件時,回調(diào)要么配置在methods中,要么用箭頭函數(shù),否則this指向會出問題!
5、案例:給TodoList添加自定義事件
Header和Footer用到了子傳父(Item是孫傳父了,自定義事件沒發(fā)解決)
App里標簽寫,Header里觸發(fā),然后把值傳過去。
此處只展示改動部分:文章來源:http://www.zghlxwxcb.cn/news/detail-664721.html
- App.vue:
<TodolistHeader @addTodo="addTodo" />
<TodolistFooter
:todos="todos"
@checkAllTodo="checkAllTodo"
@clearAllTodo="clearAllTodo"
/>
- TodolistHeader.vue:
//3.借助App里的函數(shù),把用戶的輸入從Header傳給App里面的todos 然后再通過App把todos傳給List,用這種捷徑(借助App)就巧妙地實現(xiàn)了Header和List的兄弟組件通信
// this.addTodo(todoObj)
//使用自定義函數(shù)
this.$emit('addTodo', todoObj)
- TodolistFooter.vue:
methods: {
checkAll(e) {
// this.checkAllTodo(e.target.checked)
this.$emit('checkAllTodo', e.target.checked)
},
clearAll() {
// this.clearAllTodo() //點擊調(diào)用App里邊的方法,把所有為true的刪掉
this.$emit('clearAllTodo')
},
},
此處不使用props了記得把props里的對應(yīng)項刪掉文章來源地址http://www.zghlxwxcb.cn/news/detail-664721.html
到了這里,關(guān)于Vue2-瀏覽器本地存儲(WebStorage)及完善TodoList案例、組件自定義事件及完善TodoList案例的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!