父子之間組件傳值
父組件向子組件傳值
父組件向子組件傳data中的值
首先,我們知道子組件默認是無法訪問父組件中的data上的數據和methods中的方法,其次,如果我們想要子組件取到父組件中data中的msg值,該怎麼辦呢?
先區分父組件中的data和子組件中data
子組件中的data數據,並不是通過父組件傳遞過來的,而是子組件自身私有的,比如:子組件通過ajax請求回來的數據,都可以放在data身上,注意:子組件的data必須是個方法,有返回值
var vm = new Vue({
el:'#app',
data:{
msg: '123 啊-父組件中的數據'
},
methods:{},
components: {
com1: {
data(){
return {
title: '123',
content: 'qqq'
}
},
template: '<h1>這是子組件 --- {{ parentmsg }}</h1>',
}
}
});
父組件向子組件傳值:
通過屬性綁定(v-bind)的方式,把需要傳遞給子組件的數據,以屬性綁定的形式,傳遞到子組件內部,供子組件使用;然後在子組件中的props數組中定義從父組件傳遞過來的屬性。
注意:子組件中的data上的數據,是可讀可寫的,props中的數據都是隻讀的,是無法重新賦值的
<body>
<div id="app">
<com1 v-bind:parentmsg="msg"></com1>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg: '123 啊-父組件中的數據'
},
methods:{},
components: {
com1: {
data(){
return {
title: '123',
content: 'qqq'
}
},
template: '<h1>這是子組件 --- {{ parentmsg }}</h1>',
props: ['parentmsg'],
}
}
});
</script>
</body>
父組件向子組件傳遞方法
父組件向子組件傳遞方法,使用的是事件綁定機制:v-on (<com2 v-on:func=“show”>)
當我們自定義了一個事件屬性之後,子組件就能通過某些方式(this.$emit(‘func’,this.sonmsg),看父組件的方法是否有參數),來調用傳遞進去的這個方法
<body>
<div id="app">
<com2 v-on:func="show"></com2>
</div>
<template id="tmp1">
<div>
<h1>這是子組件</h1>
<input type="button" value="這是子組件中的按鈕- 點擊它,觸發父組件傳遞過來的func方法" @click="myclick">
</div>
</template>
<script>
var com2 = {
template : '#tmp1',
data(){
return {
sonmsg: {name:'小頭兒子', age:6}
}
},
methods: {
myclick(){
//當點擊子組件按鈕時,如何拿到父組件傳遞過來的func方法,並調用這個方法
// emit英文意思:觸發,調用意思
this.$emit('func',this.sonmsg)
}
}
}
var vm = new Vue({
el:'#app',
data:{
datamsgFormSon: null
},
methods:{
show(data){
// console.log(data)
this.datamsgFormSon = data
}
},
components: {
com2
}
});
</script>
</body>
實例:評論列表
分析:發表評論的業務邏輯
1.評論數據存到哪裏去? 存放到本地localStorage中localStorage.setItem(‘cmts’,’’)
2.先組織一個最新的評論數據對象
3.想辦法,把第二步得到的評論對象,保存到localStorage中
3.1 localStorage只支持存放字符串數據,要先序列化成一個對象,調用JSON.stringify
3.2 在保存最新的評論數據之前,要先從localStorage獲取到之前的評論數據(string),轉換爲一個數組對象, 然後把最新的評論push到這個數組
3.3 如果獲取到的localStorage中的評論字符串,爲空不存在,則可以返回一個‘[]’讓JSON.parse去轉換
3.4 把最新的評論列表數組,再次調用JSON.stringify轉化爲數組字符串,然後調用localStorage.setItem()
知識點:在點擊發表評論時,希望能夠自動刷新列表從localStorage中獲得最新列表。而該方法爲localComments(),是父組件的方法,子組件是如何調用父組件的方法的。
知識點:JSON.parse() 從一個字符串解析出JSON對象;JSON.stringify()從一個對象中解析出字符串。
知識點:localStorage爲本地存儲,只存儲字符串類型的對象,如果想要轉成JSON對象類型就需要用到上一個知識點。
<body>
<div id="app">
<cmt-box @func="localComments"></cmt-box>
<ul class="list-group">
<li class="list-group-item" v-for="item in list" :key="item.id">
<span class="badge">評論人:{{ item.user }}</span>
{{ item.content }}
</li>
</ul>
</div>
<template id="tmp1">
<div>
<div class="form-group">
<label>評論人:</label>
<input type="text" class="form-control" v-model='user'>
</div>
<div class="form-group">
<label>評論內容:</label>
<textarea class="form-control" v-model='content'></textarea>
</div>
<div class="form-group">
<input type="button" value="發表評論" class="btn btn-primary" @click="postComment">
</div>
</div>
</template>
<script>
var commentBox = {
data(){
return {
user: '',
content: ''
}
},
template: '#tmp1',
methods: {
postComment(){
var comment = {id: Date.now(), user: this.user, content: this.content}
// 從localStorage中獲取所有的評論
var list = JSON.parse(localStorage.getItem('cmts') || '[]')
list.unshift(comment)
// 重新保存最新的評論數據
localStorage.setItem('cmts',JSON.stringify(list))
this.user = this.content = ''
this.$emit('func')
}
}
}
var vm = new Vue({
el:'#app',
data:{
list:[
{id: Date.now(), user:'李白', content:'天生我材必有用'},
{id: Date.now(), user:'江小白', content:'勸君更進一杯酒'},
{id: Date.now(), user:'小馬', content:'我姓馬,風吹草低見牛羊的馬'}
]
},
created(){
this.localComments()
},
methods:{
localComments(){ // 從本地localStorage中加載評論列表
var list = JSON.parse(localStorage.getItem('cmts') || '[]')
this.list = list
}
},
components:{
'cmt-box': commentBox
}
});
</script>
</body>
子組件向父組件傳值
使用this.$refs來獲取元素和組件。
首先,瞭解ref的功能,通過ref就能不操作DOM元素獲取到h3的值,可以從控制檯看到有$refs對象,給h3加上ref=myh3,就能看到$refs中有對象,鍵爲myh3,值爲DOM元素,在方法中,通過this.$refs.myh3.innerText就可以獲取到該元素
<body>
<div id="app">
<input type="button" value="獲取元素" @click="getElement">
<h3 ref="myh3">哈哈哈,今天天氣太好了!!!</h3>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{},
methods:{
getElement(){
console.log(this.$refs.myh3.innerText)
}
},
});
</script>
</body>
在父組件中通過** this.$refs.mylogin.show()**就可調用子組件的show方法,此時控制檯的$refs中的mylogin對應的值就是子組件
<body>
<div id="app">
<input type="button" value="獲取元素" @click="getElement">
<h3 ref="myh3">哈哈哈,今天天氣太好了!!!</h3>
<hr>
<login ref="mylogin"></login>
</div>
<script>
var login={
template: '<h1>登錄組件</h1>',
data(){
return {
msg: 'son msg'
}
},
methods: {
show(){
console.log('調用了子組件的方法')
}
}
}
var vm = new Vue({
el:'#app',
data:{},
methods:{
getElement(){
this.$refs.mylogin.show()
}
},
components:{
login
}
});
</script>
</body>