vue組件傳值(高級(jí))、屬性傳值、反向傳值、跨級(jí)傳值實(shí)例詳解
一、屬性傳值——父?jìng)髯?/h2>
父組件通過(guò)屬性傳值給子組件 父組件修改數(shù)據(jù)后會(huì)刷新頁(yè)面并重新傳值給子組件
子組件可以修改父組件傳的值并刷新自己的頁(yè)面 但是并不會(huì)修改父組件中的值
父組件App:
<template> <div id="app"> <Box v-for="(item, index) in arr" :key="item.id" :employee="item.employee" :salary="item.salary"></Box> <p>總工資:{{total}}</p> </div> </template> <script> import Box from "./Box.vue"; export default { data() { return { arr: [ { id: 1, employee: "haha", salary: 3221 }, { id: 2, employee: "xixi", salary: 4262 }, { id: 3, employee: "yoyo", salary: 3122 } ] }; }, components: { Box }, computed:{ total(){ let sum=0 for (let i = 0; i < this.arr.length; i++) { sum+=this.arr[i].salary } return sum } } }; </script>
子組件Box:
<template> <div> <span>員工:{{employee}} 工資:{{salary}}</span> <button @click="change">漲工資</button> </div> </template> <script> export default { props:["employee","salary"], methods:{ change(){ this.salary+=500 } } } </script>
結(jié)果顯示:
二、反向傳值——子傳父$emit
在父組件中綁定事件 事件被觸發(fā)后獲取子組件傳的值 修改data中的數(shù)據(jù) 刷新頁(yè)面
在子組件修改數(shù)據(jù)后 觸發(fā)子組件中的父組件的事件 并傳新值$emit("事件","值")
父組件App:
<template> <div id="app"> <Box @mychange="fn" v-for="(item, i) in arr" :key="item.id" :employee="item.employee" :salary="item.salary" :index="i"></Box> <p>總工資:{{total}}</p> </div> </template> <script> import Box from "./Box.vue"; export default { data() { return { arr: [ { id: 1, employee: "haha", salary: 3221 }, { id: 2, employee: "xixi", salary: 4262 }, { id: 3, employee: "yoyo", salary: 3122 } ] }; }, components: { Box }, methods:{ fn(newsalary,index){ //父組件接收到子組件傳來(lái)的新值更新自己的數(shù)據(jù) 并重新傳值 刷新頁(yè)面 this.arr[index].salary=newsalary this.$set(this.arr,index,this.arr[index]) } }, computed:{ total(){ let sum=0 for (let i = 0; i < this.arr.length; i++) { sum+=this.arr[i].salary } return sum } } }; </script>
子組件Box:
<template> <div> <span>員工:{{employee}} 工資:{{salary}}</span> <button @click="change">漲工資</button> </div> </template> <script> export default { props:["employee","salary","index"], methods:{ change(){ let newsalary=this.salary+500 //觸發(fā)父組件的事件 同時(shí)將修改后的數(shù)據(jù)傳給父組件 this.$emit("mychange",newsalary,this.index) } } } </script>
結(jié)果顯示:
三、反向傳值——子傳父--sync
子:this.$emit("updata:a","更改的值")
父:<Box :a.sync="msg"></Box>
.sync 幫忙修改了父組件的數(shù)據(jù) 不用父組件再綁定事件獲取新值修改自己的數(shù)據(jù)
父組件App:
<template> <div> <h1>app組件--{{msg}}</h1> <Box :a1.sync="msg"></Box> </div> </template> <script> import Box from "./Box.vue" export default { data() { return { msg: "app的數(shù)據(jù)", } }, components: { Box }, } </script>
子組件Box:
<template> <div> <h2>box組件--a1--{{a1}}</h2> <button @click="change">修改a1中的數(shù)據(jù)</button> </div> </template> <script> export default { props:["a1"], methods:{ change(){ console.log("點(diǎn)擊了按鈕") // 由以下兩步操作,變?yōu)榱艘徊剑? //this.a1="box修改了a1的值" // this.$emit("myevent","box修改了a1的值") this.$emit("update:a1","box修改了a1的值") } } } </script>
結(jié)果顯示:
四、反向傳值——子傳父--v-model
v=model <----語(yǔ)法糖----> :value="msg" @input="fn"
父:<Box :v-model="msg"></Box>
子:props:["value"] this.$emit("input","修改的值") 觸發(fā)input事件
父組件中:
<template> <div class="app"> <h2>app組件--{{msg}}</h2> <Box v-model="msg"></Box> </div> </template> <script> import Box from "./Box.vue" export default { data() { return { msg:"app組件的數(shù)據(jù)" } }, components: { Box }, methods:{ } } </script>
子組件中:
<template> <div class="box"> <h2>box組件--{{value}}</h2> <button @click="change">change</button> </div> </template> <script> export default { props:["value"], methods:{ change(){ this.$emit("input","box修改了數(shù)據(jù)") } } } </script>
結(jié)果顯示:
v-model指令的修飾符:
1、lazy修飾符--雙向綁定時(shí),當(dāng)光標(biāo)離開(kāi)時(shí)才更新對(duì)應(yīng)的變量
- 用戶(hù)使用v-model之后,用戶(hù)每次修改輸入內(nèi)容,都會(huì)將后臺(tái)的數(shù)據(jù)同時(shí)綁定。
- 為了避免這種情況的發(fā)生,使用lazy修飾符來(lái)進(jìn)行限定。
- 只有當(dāng)用戶(hù)的input中失去焦點(diǎn)或用戶(hù)點(diǎn)擊回車(chē)后,才會(huì)將后臺(tái)的數(shù)據(jù)進(jìn)行修改更新。
- 類(lèi)似于懶加載和防抖的設(shè)計(jì)。
<input type="text" v-model.lazy="message">
2、number修飾符--自動(dòng)將用戶(hù)的輸入值轉(zhuǎn)為數(shù)值類(lèi)型
- 當(dāng)用戶(hù)在input中輸入數(shù)字時(shí),瀏覽器會(huì)默認(rèn)將輸入的數(shù)字轉(zhuǎn)化為string類(lèi)型。
- 使用number修飾符來(lái)將輸入的數(shù)字重新轉(zhuǎn)為number類(lèi)型。
<input type="text" v-model.number="age">
3.trim修飾符--自動(dòng)忽略輸入內(nèi)容的首尾空白字符
- 用戶(hù)可能輸入的字符串中含有空格,這樣系統(tǒng)在處理時(shí)可能會(huì)出現(xiàn)錯(cuò)誤。
- 使用trim修飾符來(lái)去掉字符串首部或者尾部的所有空格。
<input type="text" v-model.trim="userName">
五、多層(跨級(jí))組件傳值
父元素傳的所有屬性$attrs(屬性傳遞)
父元素傳的所有監(jiān)聽(tīng)器$listener(事件傳遞)
App:<Box1 :b1="msg" @x="xchange"></Box1> 事件雖然綁在子組件 但是是孫組件在觸發(fā)事件
Box1:<Box2 v-bind="$attrs" v-on="$listener"></Box2> Box1只是作為中間人 將綁定的屬性和事件都傳給子組件Box2
Box2:props:["b1"] 觸發(fā)上層傳下來(lái)的App的事件 修改App組件的數(shù)據(jù) 再更新數(shù)據(jù) 重新刷新頁(yè)面
App組件中:
<template> <div> <h1>app-{{msg}}</h1> <button @click="change1">點(diǎn)擊修改app組件的msg</button> <Box1 :b1="msg" @x="xchange"></Box1> </div> </template> <script> import Box1 from "./Box1.vue" export default { data() { return { msg: "app組件的數(shù)據(jù)" } }, methods:{ change1(){ this.msg="app組件修改了msg的數(shù)據(jù)" }, xchange(arg){ this.msg=arg } }, components:{ Box1 } } </script>
Box1組件中:
<template> <div> <h1>{{$attrs.b1}}</h1> <Box2 v-bind="$attrs" v-on="$listeners"></Box2> </div> </template> <script> import Box2 from "./Box2.vue" export default { components:{ Box2 }, methods:{ look(){ console.log(this.$attrs) } } } </script>
Box2組件中:
<template> <div> <h3>box2--{{b1}}</h3> <button @click="change">change</button> </div> </template> <script> export default { props:["b1"], methods:{ change(){ this.$emit("x","box2修改了數(shù)據(jù)") } } } </script>
結(jié)果顯示:
六、$ parent/$root、$children/$refs
$root: 訪問(wèn)根組件vm對(duì)象,所有的子組件都可以將這個(gè)實(shí)例作為一個(gè)全局 store 來(lái)訪問(wèn)或使用,現(xiàn)在有更好的技術(shù)vuex代替。
$parent:訪問(wèn)父組件對(duì)象,直接操作父組件的data數(shù)據(jù),不需要再使用屬性傳值,但是容易出現(xiàn)渲染混亂之后只渲染一個(gè)的情況 可以連點(diǎn) this.parent.parent...
$children:訪問(wèn)子組件對(duì)象數(shù)組,不是子元素 不能保證順序,沒(méi)有按照順序加載,加載順序是混亂的也不是響應(yīng)式的
$refs:只會(huì)在組件渲染完成之后生效,并且它們不是響應(yīng)式的。應(yīng)該避免在模板或計(jì)算屬性中訪問(wèn) $refs。在組件或者原生元素綁定ref屬性(類(lèi)似于id) 在父組件中可以通過(guò) this.$refs訪問(wèn)到它
App組件:
<template> <div> <h1>app組件--{{msg}}</h1> <div> <Box1></Box1> <!--雖然Box1組件寫(xiě)在div里面 但是.$parent指的還是父組件App 而非div--> </div> </div> </template> <script> import Box1 from "./Box1.vue" export default { data() { return { msg:"app組件的數(shù)據(jù)" } }, methods: {}, components: { Box1 } } </script>
Box1組件:
<template> <div> <button @click="look">box1</button> <Box2></Box2> <Box2></Box2> <p ref="p1">ref</p> <button @click="getref">獲取ref</button> </div> </template> <script> import Box2 from "./Box2.vue" export default { components: { Box2 }, methods: { getref(){ console.log(this.$refs) }, look() { console.log(this,this.$parent,this.$children,this.$root) this.$parent.msg="box1修改了app的數(shù)據(jù)" } } } </script>
Box2組件:
<template> <div> <p>{{$parent.$parent.msg}}</p> <button @click="change1">box2-change</button> </div> </template> <script> export default { methods:{ change1(){ this.$parent.$parent.msg="box2修改了數(shù)據(jù)" } } } </script>
結(jié)果顯示:
七、Vue 依賴(lài)注入 - Provide/Inject(重點(diǎn))
注:Provide和Inject綁定并不是可響應(yīng)的
父組件使用:provide:提供數(shù)據(jù)
把data中的數(shù)據(jù)提供給子孫組件
// provide選項(xiàng)提供變量 provide: { message: 'provided by father' },
inject:["message"]
八、中央事件總線(xiàn)bus
自定義事件的語(yǔ)法:
Vue提供的技術(shù):某繼承Vue的組件有三個(gè)功能:
1.觸發(fā)x組件的a事件:x.$emit("a事件",參數(shù))
2.給x組件綁定a事件:x.$on("a事件",監(jiān)聽(tīng)器函數(shù))
3.給x組件解綁a事件:x.$off("a事件",監(jiān)聽(tīng)器函數(shù))
通過(guò)創(chuàng)建一個(gè)新的vm對(duì)象,專(zhuān)門(mén)統(tǒng)一注冊(cè)事件,供所有組件共同操作,達(dá)到所有組件隨意隔代傳值的效果:
main.js:
Vue.prototype.$bus = new Vue({ methods: { //綁定事件 on(eventname, callback) { this.$on(eventname, callback) }, //觸發(fā)事件 emit(eventname, ...arg) { this.$emit(eventname, ...arg) }, //解綁事件 off(eventname, callback) { this.$off(eventname, callback) }, } })
使用:
this.$bus.on("事件",監(jiān)聽(tīng)器函數(shù))
this.$bus.emit("事件","參數(shù)")
this.$bus.off("事件",監(jiān)聽(tīng)器函數(shù))
示例:
組件1: this.$bus.on('changedFormObject',(val) =>{ //接受并處理傳過(guò)來(lái)的值:val this.msg = val; }); 組件2: this.$bus.emit('changedFormObject',this.inputValue);//把組件2的data中的給inputValue值傳給組件1
到此這篇關(guān)于vue組件傳值(高級(jí))、屬性傳值、反向傳值、跨級(jí)傳值的文章就介紹到這了,更多相關(guān)vue組件傳值內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Vue 2.0 監(jiān)聽(tīng)文本框內(nèi)容變化及ref的使用說(shuō)明介紹
今天小編就為大家分享一篇基于Vue 2.0 監(jiān)聽(tīng)文本框內(nèi)容變化及ref的使用說(shuō)明介紹,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08Vue項(xiàng)目代碼之路由拆分、Vuex模塊拆分、element按需加載詳解
這篇文章主要介紹了Vue項(xiàng)目代碼之路由拆分、Vuex模塊拆分、element按需加載,項(xiàng)目較大路由較多時(shí),路由拆分是一個(gè)不錯(cuò)的代碼優(yōu)化方案,按不同業(yè)務(wù)分為多個(gè)模塊,結(jié)構(gòu)清晰便于統(tǒng)一管理,本文通過(guò)示例給大家詳細(xì)講解,需要的朋友可以參考下2022-11-11關(guān)于Pinia狀態(tài)持久化問(wèn)題
這篇文章主要介紹了關(guān)于Pinia狀態(tài)持久化問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2023-03-03Vue實(shí)現(xiàn)購(gòu)物小球拋物線(xiàn)的方法實(shí)例
這篇文章主要給大家介紹了Vue實(shí)現(xiàn)購(gòu)物小球拋物線(xiàn)的方法實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11vue中v-for數(shù)據(jù)狀態(tài)值變了,但是視圖沒(méi)改變的解決方案
這篇文章主要介紹了vue中v-for數(shù)據(jù)狀態(tài)值變了,但是視圖沒(méi)改變的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06使用Vue調(diào)取接口,并渲染數(shù)據(jù)的示例代碼
今天小編就為大家分享一篇使用Vue調(diào)取接口,并渲染數(shù)據(jù)的示例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-10-10