Vue父子組件數(shù)據(jù)雙向綁定(父?jìng)髯?、子傳父)及ref、$refs、is、:is的使用與區(qū)別
既然有父?jìng)髯幽敲纯隙ㄓ凶觽鞲?,有子傳父肯定也有兩者之間相互綁定
這里我們先看一下子傳父的寫(xiě)法:
一、子傳父:$emit()
看代碼:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>子傳父</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <style type="text/css"> button { margin-left: 5px; } </style> <body> <div id="app"> <cpn1 @itemclick="cpnclick"></cpn1> </div> <template id="cpn1"> <div> <button type="button" v-for="item in menu" :key="item.id" @click="btnclick(item)">{{item.name}}</button> </div> </template> <script type="text/javascript"> const cpn = { template: "#cpn1", data() { return { menu: [{ id: 'one', name: '首頁(yè)' }, { id: 'two', name: '分類' }, { id: 'three', name: '購(gòu)物' }, { id: 'four', name: '我的' }, ], } }, methods: { btnclick(item) { this.$emit('itemclick', item) // 子傳父 在子組件中做一個(gè)點(diǎn)擊事件通過(guò)$emit派發(fā)出 給父組件 同時(shí)可以攜帶參數(shù) } } }; const vm = new Vue({ el: '#app', methods: { cpnclick(item) { console.log('cpnclick' + item.name); } }, components: { "cpn1": cpn } }) </script> </body> </html>
打印效果:
兩者之間的關(guān)系:
1、父組件可以使用 props 把數(shù)據(jù)傳給子組件。
2、子組件可以使用 $emit 觸發(fā)父組件的自定義事件。
二、監(jiān)聽(tīng)原生點(diǎn)擊事件:.native
不加.native時(shí),不會(huì)觸發(fā)原生的點(diǎn)擊事件
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>不加native修飾符</title> </head> <style> div{ cursor: pointer; } </style> <body> <div id="app"> <cpn @click="handelClick"></cpn> // 這里沒(méi)有加native修飾符 </div> <!-- 子組件 --> <template id="cpn"> <div> 我是子組件 </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script> <script> const cpn = { template:'#cpn', } const app = new Vue({ el: "#app", methods: { handelClick(){ console.log('click'); } }, components:{ cpn } }) </script> </body> </html>
效果如下:
不加修飾符是不會(huì)監(jiān)聽(tīng)到原生點(diǎn)擊事件的。
如果是加了.native修飾符時(shí):
添加方法:
<cpn @click.native="handelClick"></cpn>
效果如下圖所示:
三、組件通信的案例:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id="app"> <cpn :number1="num1" :number2="num2"></cpn> </div> <template id="cpn"> <div> <h2>{{datanum1}}</h2> <input type="text" v-model="datanum1"/> <h2>{{datanum2}}</h2> <input type="text" v-model="datanum2"/> </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script> <script> const cpn = { template:'#cpn', data(){ return { datanum1:this.number1, datanum2:this.number2, } }, props:{ number1:{ type:[String,Number] }, number2:{ type:[String,Number] }, } } const app = new Vue({ el: "#app", data() { return { num1:1, num2:2 } }, components:{ cpn } }) </script> </body> </html>
效果如下:
四、實(shí)現(xiàn)父子之間的值的雙向綁定
在子組件中添加監(jiān)聽(tīng)器,利用props和$emit來(lái)進(jìn)行父子之間的雙向綁定
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id="app"> <cpn :number1="num1" :number2="num2" @dataclick1="changeClick1" @dataclick2="changeClick2"></cpn> </div> <template id="cpn"> <div> <h2>{{datanum1}}</h2> <h3>number1:{{number1}}</h3> <input type="text" v-model="datanum1" /> <h2>{{datanum2}}</h2> <h3>number2:{{number2}}</h3> <input type="text" v-model="datanum2" /> </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script> <script> const cpn = { template: '#cpn', data() { return { datanum1: this.number1, datanum2: this.number2 } }, props: { number1: { type: [String, Number] }, number2: { type: [String, Number] } }, watch: { datanum1(n) { console.log('datanum1被監(jiān)聽(tīng)了'); this.$emit('dataclick1', n / 100) }, datanum2(n) { console.log('datanum2被監(jiān)聽(tīng)了'); this.$emit('dataclick2', n * 100) } } } const app = new Vue({ el: "#app", data() { return { num1: 1, num2: 2 } }, methods: { changeClick1(value) { this.num1 = value }, changeClick2(value) { this.num2 = value } }, computed: { }, components:{ cpn } }) </script> </body> </html>
效果
一個(gè)是除10一個(gè)是
五、父訪問(wèn)子 $refs
JavaScript中獲取元素可以使用document.querySelector,那可以在Vue中使用嗎?
我們可以測(cè)試一下
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <p id="bb" @click="handelClick" ref="aa">Nanchen</p> </div> <script type="text/javascript"> const vm = new Vue({ el: '#app', data() { return { } }, methods: { handelClick(){ var bb = document.querySelector('bb'); console.log(bb); } } }) </script> </body> </html>
打印結(jié)果:
答案是可以的,但是如果使用原生JS獲取元素的話,那么用Vue就沒(méi)有意義了,Vue中有特定的語(yǔ)法
官網(wǎng)解釋:
$refs方式:ref 被用來(lái)給元素或子組件注冊(cè)引用信息。引用信息將會(huì)注冊(cè)在父組件的 $refs 對(duì)象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子組件上,引用就指向組件實(shí)例
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <p id="bb" @click="handelClick" ref="aa">Nanchen</p> </div> <script type="text/javascript"> const vm = new Vue({ el: '#app', data() { return { } }, methods: { /* handelClick(){ var bb = document.querySelector('bb'); console.log(bb); } */ handelClick() { console.log(this.$refs.aa); } } }) </script> </body> </html>
效果與上圖一致:
六、使用$refs獲取組件中的值
既然可以獲取普通元素那么也可以獲得組件中的元素或者值
看這個(gè)例子:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id="app"> <cpn ref="aaa"></cpn> <button @click="handelClick">點(diǎn)擊</button> </div> <!-- 子組件 --> <template id="cpn"> <div> 我是子組件 </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script> <script> const cpn = { template:'#cpn', data(){ return { name:'我是子組件的name' //獲取子組件的屬性 } }, } const app = new Vue({ el: "#app", methods: { handelClick(){ console.log(this.$refs.aaa.name); } }, components:{ cpn } }) </script> </body> </html>
效果如下:
下面看一個(gè)擴(kuò)展:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <count ref="one" @change="handclick"></count> <count ref="two" @change="handclick"></count> <h2>{{total}}</h2> </div> <script type="text/javascript"> Vue.component('count',{ template: `<div @click="handclick"> {{number}} </div>`, data(){ return{ number:0 } }, methods:{ handclick(){ this.number++; this.$emit('change') } } }) const vm = new Vue({ el:'#app', data(){ return{ total:0 } }, methods:{ handclick(){ this.total= this.$refs.one.number + this.$refs.two.number } } }) </script> </body> </html>
效果如下:
不僅如此,ref還可以調(diào)用組件中的方法:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id="app"> <hello-world ref="hello"></hello-world> <button @click="getHello">獲取helloworld組件中的值</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script> <script> Vue.component('helloWorld',{ template:`<div>helloWorld</div>`, data(){ return { number:0 } }, methods:{ /*handelClick(){ console.log('我是子組件的方法'); }*/ } }) const app = new Vue({ el: "#app", data: { }, methods: { getHello(){ /* this.$refs.hello.handelClick(); */ console.log(this.$refs.hello.$el.innerHTML); } }, }) </script> </body> </html>
效果如下:
六、is與:is
is
作用:解決了html模板的限制。
看下面這段代碼:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <table> <row></row> </table> </div> <script type="text/javascript"> Vue.component('row',{ template: '<tr><td>111</td></tr>' }) const vm = new Vue({ el:'#app', data(){ return{ } }, }) </script> </body> </html>
會(huì)正常輸出
但是:
會(huì)發(fā)現(xiàn)tr并不在table中,
解決辦法:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id="app"> <table> <tr is="row"></tr> </table> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script> <script> Vue.component('row', { template: '<tr><td>111</td></tr>' }) const app = new Vue({ el: "#app", }) </script> </body> </html>
打印結(jié)果:
用:is還可以用來(lái)綁定動(dòng)態(tài)組件
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <component :is="type"></component> <button type="button" @click="changeClick">切換</button> </div> <script type="text/javascript"> // 這里要定義兩個(gè)全局組件 Vue.component('child-one',{ template:'<div>child-one</div>' }), Vue.component('child-two',{ template:'<div>child-two</div>' }) const vm = new Vue({ el:'#app', data(){ return{ type:'child-one' } }, methods:{ changeClick(){ this.type = this.type === 'child-one' ? 'child-two' :'child-one' } } }) </script> </body> </html>
效果如下:
以上就是Vue父子組件數(shù)據(jù)雙向綁定(父?jìng)髯印⒆觽鞲福┘皉ef、$refs、is、:is的使用與區(qū)別的詳細(xì)內(nèi)容,更多關(guān)于Vue父子組件數(shù)據(jù)雙向綁定的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- vue子組件改變父組件傳遞的prop值通過(guò)sync實(shí)現(xiàn)數(shù)據(jù)雙向綁定(DEMO)
- Vue.js實(shí)現(xiàn)數(shù)據(jù)雙向綁定的代碼示例
- 使用Vue.js實(shí)現(xiàn)數(shù)據(jù)的雙向綁定
- 淺析Vue3中通過(guò)v-model實(shí)現(xiàn)父子組件的雙向數(shù)據(jù)綁定及利用computed簡(jiǎn)化父子組件雙向綁定
- vue中如何解除數(shù)據(jù)之間的雙向綁定
- vue3中reactive數(shù)據(jù)被重新賦值后無(wú)法雙向綁定的解決
- proxy實(shí)現(xiàn)vue3數(shù)據(jù)雙向綁定原理
- vue自定義組件實(shí)現(xiàn)v-model雙向綁定數(shù)據(jù)的實(shí)例代碼
- vue 數(shù)據(jù)雙向綁定的實(shí)現(xiàn)方法
- Vue項(xiàng)目開(kāi)發(fā)實(shí)現(xiàn)父組件與子組件數(shù)據(jù)間的雙向綁定原理及適用場(chǎng)景
相關(guān)文章
解決vue-cli 配置資源引用的絕對(duì)路徑問(wèn)題
這篇文章主要介紹了vue-cli 配置資源引用的絕對(duì)路徑的問(wèn)題,本文通過(guò)圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-09-09vue.js 表格分頁(yè)ajax 異步加載數(shù)據(jù)
Vue.js通過(guò)簡(jiǎn)潔的API提供高效的數(shù)據(jù)綁定和靈活的組件系統(tǒng).這篇文章主要介紹了vue.js 表格分頁(yè)ajax 異步加載數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下2016-10-10vue基于html2canvas和jspdf?生成pdf?、解決jspdf中文亂碼問(wèn)題的方法詳解
這篇文章主要介紹了vue基于html2canvas和jspdf?生成pdf?、解決jspdf中文亂碼問(wèn)題的方法,結(jié)合實(shí)例形式詳細(xì)描述了中文亂碼問(wèn)題的原因、解決方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下2023-06-06vue2.0使用Sortable.js實(shí)現(xiàn)的拖拽功能示例
本篇文章主要介紹了vue2.0使用Sortable.js實(shí)現(xiàn)的拖拽功能示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-02-02Vue實(shí)現(xiàn)push數(shù)組并刪除的例子
今天小編就為大家分享一篇Vue實(shí)現(xiàn)push數(shù)組并刪除的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11