上一節學習了父組件與子組件之間的簡單通信,回想一下大體以下:javascript
props
$emit
可是也存在一些遺留問題,好比:我想在父組件中點擊行事件修改彈出框的顯示隱藏
其實上一節已經實現了效果,只是同時也獲得了一大串的大紅字~滿山紅真的讓人很臉紅的說啊...html
今天不上班,有一成天的自由時間,時間真的是一個很珍貴的東西呀,因此但凡是與時間有關的產物都會頗有價值!vue
回到正題吧,今天能夠慢慢的想一下如何來完成上一次沒有完成的功能。java
SeaConch:先說好啊,這樣作不對
vuex
旁白:不對你爲何還要寫呢!?npm
SeaConch:由於我就是這樣過來的啊...
函數
既然父組件能夠經過子組件定義的props
屬性傳遞對象
,那爲何不直接修改它來實現修改父組件呢?學習
SeaConch:好像頗有道理的樣子!來試試~
優化
不皮啦,好好記錄!this
父組件代碼稍多,最後在貼完整的吧。
student-list (父
)組件關鍵代碼:
html: <student-list-info ... :visible="this.display" > </student-list-info> javascript: data () { return { ... display: false } },
student-list-info (子
)組件完整代碼:
<template> <div> <el-button icon="el-icon-more" @click="changeDisplay(true)" circle></el-button> <el-dialog title="查詢" :visible.sync="this.visible"> <el-form :model="student"> <el-form-item label="姓名"> <el-input v-model="student.name"></el-input> </el-form-item> <el-form-item label="性別"> <el-input v-model="student.sex"></el-input> </el-form-item> <el-form-item label="年齡"> <el-input v-model.number="student.age" type="number"></el-input> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="changeDisplay(false)">取 消</el-button> <el-button type="primary" @click="doConfirm(student)">確 定</el-button> </div> </el-dialog> </div> </template> <script> export default { name: 'student-list-info', props: [ 'student', 'visible'/* 新增 */ ], methods: { // 確認按鈕 doConfirm (student) { this.$emit('confirm', student) this.changeDisplay(false) }, // 修改顯示狀態 changeDisplay (value) { this.visible = value } } } </script> <style scoped> </style>
npm run dev
誒~竟然能夠用~
控制檯:我笑了
打開控制檯才發現,原來一切都是假的!看到那廣闊的紅色疆土了嗎?那是朕爲你打下的江山!
其實錯誤是在說vue
並不推薦
這樣修改prop
的值,而且咱們應該避免這樣作
,以避免在父組件發生改變時得到一個驚喜
好吧好吧,你說的有理,而且成功的說服了我,我改。
既然不能再子組件中修改,那就轉移到父組件中修改吧。
關鍵字固然是$emit
啦。
1.修改子組件
子組件只修改一個地方就能夠啦
// 修改顯示狀態 changeDisplay (value) { // this.visible = value this.$emit('switch', value) }
2.修改父組件
父組件須要給子組件@
一個switch
事件供其觸發
html: <student-list-info ... :visible="this.display" @switch="onSwitch" > </student-list-info> javascript: // 切換顯示狀態 onSwitch (value) { this.display = value }
好啦,run
再次查看效果,此次沒有錯誤了
不過這樣看來的話,關於組件之間的值傳遞有些麻煩...
經查閱,vuex
好像能夠很好的解決這個問題,但漸進式的vue
容許咱們暫時不用他,你會知道何時該使用vuex的
,逼格滿滿~
不過彷佛Step 2.
也是能夠優化的,再來個Step 3.
吧
.sync
實際是一種簡單化的方法,咱們來應用一下吧。
1.父組件再也不須要Step 2.
中新增的switch
事件了:
<student-list-info style="float: left" @confirm="onConfirm" :student="this.student" :visible.sync="display" > </student-list-info>
注意::visible.sync="display"
這裏display
沒有帶this.
而且也不能夠帶this.
帶上會報錯,錯誤看不太明白,不過既然帶上this.
會出錯,那可能和更新事件的做用域有關係吧。
2.子組件中只須要修改一下changeDisplay函數
:
// 修改顯示狀態 changeDisplay (value) { // this.visible = value // this.$emit('switch', value) this.$emit('update:visible', value) }
run
一下
結果是成功的。
點擊彈出框的X
好像報錯,我去看一下。
改好了,把他本來的關閉事件屏蔽掉啦。
父組件完整代碼:
<template> <div> <el-row> <student-list-info style="float: left" @confirm="onConfirm" :student="this.student" :visible.sync="display" > </student-list-info> </el-row> <hr> <h3>學員列表</h3> <el-table :data="tableData" @row-click="onRowClick" border stripe style="width: 100%"> <el-table-column prop="name" label="姓名" width="180"> </el-table-column> <el-table-column prop="sex" label="性別" width="180"> </el-table-column> <el-table-column prop="age" label="年齡"> </el-table-column> </el-table> </div> </template> <script> import studentListInfo from './student-list-info' export default { name: 'student-list', // 組件 components: { studentListInfo }, data () { return { tableData: [{ name: '張楚嵐', sex: '男', age: '23' }, { name: '馮寶寶', sex: '女', age: '99' }, { name: '趙方旭', sex: '男', age: '59' }, { name: '肖自在', sex: '男', age: '36' } ], student: { name: '', sex: '', age: 0 }, display: false /* 新增 */ } }, // 方法集 methods: { // 確認事件 onConfirm (item) { this.tableData.push(item) }, // 點擊行事件 onRowClick (row) { this.display = true this.student = { name: row.name, sex: row.sex, age: row.age } } } } </script> <style scoped> </style>
子組件完整代碼:
<template> <div> <el-button icon="el-icon-more" @click="changeDisplay(true)" circle></el-button> <el-dialog title="查詢" :visible="visible" @close='onClosed'> <el-form :model="student"> <el-form-item label="姓名"> <el-input v-model="student.name"></el-input> </el-form-item> <el-form-item label="性別"> <el-input v-model="student.sex"></el-input> </el-form-item> <el-form-item label="年齡"> <el-input v-model.number="student.age" type="number"></el-input> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="changeDisplay(false)">取 消</el-button> <el-button type="primary" @click="doConfirm(student)">確 定</el-button> </div> </el-dialog> </div> </template> <script> export default { name: 'student-list-info', props: [ 'student', 'visible'/* 新增 */ ], methods: { // 確認按鈕 doConfirm (student) { this.$emit('confirm', student) this.changeDisplay(false) }, // 修改顯示狀態 changeDisplay (value) { this.$emit('update:visible', value) }, // 對話框關閉事件 onClosed () { this.$emit('update:visible', false) } } } </script> <style scoped> </style>
如今能夠點擊行,彈出對話框查看啦~
本節主要是記錄了我想要從子組件修改父組件的屬性的一個過程,這裏也首次出現了vuex
,閒下來的時候去看一下怎麼使用吧,下回見~