上一篇講述了公司——辦公室——員工的神奇組合,那麼現在就要開始來說說,他們中間是怎麼發佈任務的。vue裏面就提供了一個好東西,叫props,這一篇裏面,我會把在props裏面踩的坑都寫出來。說起props,其實就是父組件和子組件傳遞信息的工具,用我的話講就是,辦公室的老大給員工說,“我要給你什麼任務一樣”
prop用法
上面就是一個具體的用法,但這種傳值的方式,只是傳入一個字符串。同樣的我們也可以用v-bind:message='hello'來傳字符串,當然具體的prop怎麼傳值,可以看官網prop ,推薦用v-bind來對prop傳值,動態靜態都能玩。
prop的單向數據流
來說說這個強大的坑了,在這之前,我們先來說幾個在使用prop進行數據傳輸的時候,要注意的點:
- 父子組件數據傳輸是單向的,只能由父組件傳給子組件,子組件無法直接傳給父組件(很好理解,辦公室的老大可以給你下命令,你敢給你的老大下命令嗎,要是可以,那不就亂套了,這也是vue爲了不混亂而設定的)
- 子組件無法更改props中的值(老闆下的命令不能改啊)
- 父組件的傳值方式爲初始化傳值,即第一次傳值後,接下來父組件的值發生改變不會再同步到子組件(老闆給你下了一次任務,難得還會跟你說這個任務要怎麼做嗎?)
這三個點我就不一一演示了,那麼我們就來寫一個最簡單的
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Company</title>
<style>
li{
list-style: none;
}
.is-finished{
text-decoration: line-through;
}
</style>
</head>
<body>
<div id="app-1">
<todo-item :list="task"></todo-item>
</div>
<template id="task-template">
<ul>
<li>{{list}}</li>
</ul>
</template>
<script src="../script/vue.js"></script>
<script>
Vue.component('todo-item', {
template: '#task-template',
props:['list'],//props中的值無法被改變
data:function () {
return {
}
}
})
var main=new Vue({
el:'#app-1',
data:{
task:'寫後臺'
}
})
</script>
</body>
</html>
用data獲取prop中的值
這樣就從老闆那拿到了一個任務了,然後你說:“這個任務也太簡單了吧,我要改個難度大的”,可是老闆給你的就這樣,能怎麼辦?當然有辦法,我們不還有個data和computed嘛,如果是想要把props中的數據自己用,可以用data函數,把數據賦值給自己的屬性中;如果只是想在上面做一些變化,就可以用computed,個人會喜歡用data來進行保存
data:function () {
return {
mytask:this.list
}
}
監聽父組件的值的改變
這樣即拿到了父組件的值,又可以對它進行修改,解決了第二個點。那根據第三個點,萬一老闆突然改任務了怎麼辦,他又不告訴你,不方,vue已經幫我們準備了一個好東西——watch,監聽props傳來的數值的變化,同步更新到自己的data數據中去。把老闆說的話都記下來,然後去做。
watch:{
list(val){
this.mytask=val;
}
}
prop中引用類型的坑
我們知道,在js中,數據類型分成兩種,一種是基礎數據類型,一種是引用數據類型(想了解兩個的區別的話可以看這裏 )。那麼假如我們接到的任務不是一個,而是一組。現在的情況是,辦公室不止你一個人,老闆給你和另外兩個人都安排了一個任務組,也就是說,3個人做同一個任務。那麼按我們之前說的,我們自己用自己的data保存下來了,但是呢,我們看自己的任務太簡單,想再往裏面加任務,卻發現神奇的事情發生了,代碼如下
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Company</title>
<style>
li{
list-style: none;
}
.is-finished{
text-decoration: line-through;
}
</style>
</head>
<body>
<div id="app-1">
<todo-item :list="task"></todo-item>
<todo-item :list="task"></todo-item>
<todo-item :list="task"></todo-item>
</div>
<template id="task-template">
<ul>
<li v-for="task in mytask">{{task}}</li>
<button @click="add">加任務</button>
</ul>
</template>
<script src="../script/vue.js"></script>
<script>
Vue.component('todo-item', {
template: '#task-template',
props:['list'],//props中的值無法被改變
data() {
return {
mytask:this.list
}
},
methods:{
add(){
this.mytask.push('練英語')
}
},
watch:{
list(val){
this.mytask=val;
}
}
})
var main=new Vue({
el:'#app-1',
data:{
task:['寫後臺','寫CSDN']
}
})
</script>
</body>
</html>
當我們點擊其中一個的時候,發現三個人的任務都增加了,也就意味着,我沒辦法再自己加自己的任務了,這就是引用類型和基本類型的區別。當我們改變自己的任務內容時,老闆的發佈的任務的內容也會改變。不是說老闆的命令不能改的?是老闆的任務並沒有改,emmm具體看這裏
這個時候,深度克隆瞭解一下。
踩的坑差不多就這樣,還有對象啊什麼的,其實也是差不多。好好玩一下,就懂了