Vue組件傳參11種方式舉例介紹
1. props 和 emit
vue2
父組件
<son count="100" @addCount = "addCount"></son> addCount(val) {}
子組件
props: ['count'] // [{count: Number}] [{count: {type: Number, default: 0}],this.$emit('addCount', value)
vue3
父組件
<son count="100" @addCount = "addCount"></son> constaddCount = (val) => {}
子組件
const props = defineProps(['count']) // defineProps({ count: Number }) defineProps<{ count?: number }>(),const emit = defineEmits(['addCount']) functionbuttonClick() { emit('addCount') }
2. $attrs 和 $listeners
$attrs // 組件傳值, 除了已在prop聲明的值和 class樣式名 style行內(nèi)樣式 $listeners // 組件傳函數(shù), 除了.native// 父組件 <Son :num="num" @addNum='addNum'></Son> // 子組件 <GrandSon></GrandSon><div>{{$attrs.num}}</div> // 孫子組件 <div @click="clickFn">{{$attrs.num}}</div>methods:{ clickFn(){ this.$listeners.addNum() } }
3. v-model
vue2
vue2 v-mode 是 :value="msg" @input="msg=$event" 的語(yǔ)法糖
父組件
<TabsVue v-model="activeComponent" />
子組件
props:{ activeComponent:{ type:string, default:'' } } this.$emit('update:activeComponent',value)
vue3
vue3 v-mode 是 :modelValue="msg" @update:modelValue="msg=$event" 的語(yǔ)法糖
父組件
<TabsVue v-model:activeComponent="activeComponent" />
子組件
const props = defineProps({ activeComponent: { type: String, default: '庫(kù)存信息', }, }); const emit = defineEmits(['update:activeComponent']); functiontabsChange(index: number) { activeIndex.value = index; emit('update:activeComponent', props.data[index]); }
4. 作用域插槽
<template> <div> <!--默認(rèn)插槽--> <slot></slot> <!--另一種默認(rèn)插槽的寫(xiě)法--> <slot name="default"></slot> <!--具名插槽--> <slot name="footer"></slot> <!--作用域插槽--> <slot v-bind:user="user" name="header"></slot> </div> </template> <!--使用--> <children> <!--跑到默認(rèn)插槽中去--> <div>123</div> <!--另一種默認(rèn)插槽的寫(xiě)法--> <template v-slot:default></template> <!--跑到具名插槽 footer 中去--> <template v-slot:footer></template> <!--縮寫(xiě)形式--> <template #footer></template> <!--獲取子組件的值--> <template v-slot:header="slot">{{slot.user}}</template> <!--結(jié)構(gòu)插槽值--> <template v-slot:header="{user: person}">{{person}}</template> <!--老式寫(xiě)法,可以寫(xiě)到具體的標(biāo)簽上面--> <template slot="footer" slot-scope="scope"></template> </children>
5. $refs, $root, $parent, $children
$root 獲取根組件
$parent 獲取父組件
$children 獲取子組件(所有的子組件,不保證順序)
$refs 組件獲取組件實(shí)例,元素獲取元素
6. provide 和 inject
vue2
父組件
provide(){ return{ color:this.color } }
子孫組件
<h3>{color}</h3> exportdefault{ inject:['color'] //inject: { color: 'color' } inject: {color: {from: 'colorcolor',default:#333}} }
vue3
父組件
import { provide } from'vue'; provide('money',money) provide('changeMoneyFn',number=>{ money.value-=number })
子孫組件
import { inject } from"vue"; const money =inject('money') const changeMoneyFn=inject('changeMoneyFn')
7. mitt/ event-bus
event-bus
/* eventbus.js 暴露總結(jié)總線文件 */// 這里我們?cè)趈s中暴露這個(gè)事件總線對(duì)象 import Vue from 'vue' export default new Vue()
// 注冊(cè)事件 bus.$on("getScore", data => { this.yoursore = data; }); // 觸發(fā)事件 bus.$emit("getScore", this.score);
mitt
/* eventbus.js 暴露總結(jié)總線文件 */// 這里我們?cè)趈s中暴露這個(gè)事件總線對(duì)象 import mitt from"mitt"; const emitter = mitt(); exportdefault emitter;
// 注冊(cè)事件import emitter from"./utils/eventbus.js"; emitter.on("getScore", data => { this.yoursore = data; }); // 觸發(fā)事件import emitter from"./utils/eventbus.js"; emitter.emit("getScore", this.score)
8. pina/vuex
vuex
聲明
import { createApp } from'vue'import { createStore } from'vuex'// 創(chuàng)建一個(gè)新的 store 實(shí)例const store = createStore({ state () { return { count: 0 } }, mutations: { increment (state) { state.count++ } }, actions: {}, getters: {}, modules: {} }) const app = createApp({ /* 根組件 */ }) // 將 store 實(shí)例作為插件安裝 app.use(store)
使用
1. 直接調(diào)用 this.$store.state.name// 跨模塊訪問(wèn) state 數(shù)據(jù): store.rootState.user.profile.tokenthis.$store.commit('setCount', 5) // 跨模塊訪問(wèn)mutation方法 : store.commit('permission/setRoutes', [], { root: true })this.$store.dispatch("asyncSetCount", 5) this.$store.getters.validList2. 計(jì)算屬性調(diào)用 computed: { name(){ returnthis.$store.state.name; }, validList(){ returnthis.$store.getters.validList; } } 3. 方法調(diào)用 4. 引入輔助函數(shù), 延展運(yùn)算符展開(kāi)調(diào)用 import { mapState, mapMutations, mapActions, mapGetters } from'vuex'computed: { ...mapState(['name']), ...mapGetters(['validList']) } methods: { ...mapMutations(['setCount']), ...mapActions(['asyncSetCount']) } 5. 模塊化調(diào)用 import { mapMutations } from'vuex'this.$store.state.user.tokenthis.$store.commit('user/setNewState', 666) methods: { ...mapMutations(["user/setNewState"]), setNewState(data) { this['user/setNewState'](data) } } 6. createNamespacedHelpers 創(chuàng)建基于某個(gè)命名空間輔助函數(shù) import { createNamespacedHelpers, mapGetters } from"vuex"; const { mapMutations } = createNamespacedHelpers("user"); exportdefault { computed: { ...mapGetters(["token", "name"]), }, methods: { ...mapMutations(["setNewState"]), }, }; < h3 > name: { { name } }< /h3> < button @click="setNewState(666)" > 修改數(shù)據(jù) < /button >
pina
聲明
import { createPinia } from'pinia' app.use(createPinia())
import { defineStore } from'pinia'// useStore 可以是 useUser、useCart 之類(lèi)的任何東西// 第一個(gè)參數(shù)是應(yīng)用程序中 store 的唯一 idexportconst useStore = defineStore('main', { state: () => { return { // 所有這些屬性都將自動(dòng)推斷其類(lèi)型counter: 0, } }, getters: { doubleCount: (state) => state.counter * 2, }, actions: { increment() { this.counter++ }, }, })
使用
import { useStore } from'@/stores/counter'const store = useStore() const { counter, doubleCount } = storeToRefs(store) store.$reset() // 將狀態(tài) 重置 到其初始值 store.counter++ store.$patch({ counter: store.counter + 1, }) store.$state = { counter: 666 } pinia.state.value = {}
9. 路由傳參
this.$router 相當(dāng)于一個(gè)全局的路由器對(duì)象,包含了很多屬性和對(duì)象(比如 history 對(duì)象),任何頁(yè)面都可以調(diào)用其 push(), replace(), go() 等方法。
跳轉(zhuǎn)帶參 //字符串this.$router.push('home') //對(duì)象this.$router.push({path:'/user/${userId}'}) //命名的路由this.$router.push({name:'user', params:{userId: '123'}}) //帶查詢(xún)參數(shù),變成 /register?plan=privatethis.$router.push({path:'register', query:{plan:private}})
this.$route 表示當(dāng)前路由對(duì)象,每一個(gè)路由都會(huì)有一個(gè) route 對(duì)象,是一個(gè)局部的對(duì)象,可以獲取對(duì)應(yīng)的 name, path, params, query 等屬性。
params
1. router-link導(dǎo)航aaaa 父組件 <router-link to="/child/123"> </router-link> 子組件 this.$route.params.num 路由配置 {path:'/child/:num',name:'child',component:Child} 地址欄 /child/123 顯示參數(shù),刷新不丟失 2.$router.push跳轉(zhuǎn) 父組件 <li @click='this.$router.push({path:'/child/${itemId}'})'> </li> 子組件 this.$route.params.id 路由配置 {path:'/child/:id',name:'child',component:Child} 地址欄 /child/1 顯示參數(shù),刷新不丟失 3.通過(guò)name確定路由,params傳參 父組件 <li @click='this.$router.push({name:'child',params:{id:1}})'> </li> 子組件 this.$route.params.id 路由配置 {path:'/child',name:'child',component:Child} 地址欄 /child 不顯示參數(shù),刷新丟失
query
1.path匹配路由,通過(guò)query傳參 父組件 <li @click='this.$router.push({path:'/child',query:{id:1}})'> </li> 子組件 this.$route.query.id 路由配置 {path:'/child',name:'child',component:Child} 地址欄 /child?id=1 顯示參數(shù),刷新不丟失
path
獲取當(dāng)前路由地址 this.$route.path
meta
獲取路由meta屬性值 this.$route.meta
10. 全局變量
將屬性掛載到window對(duì)象
window.myName = 'fish'// window['mayName'] = 'fish'
11. 本地存儲(chǔ)
LocalStorage
// 存儲(chǔ)數(shù)據(jù)localStorage.setItem("info",JSON.stringify(info)); // 獲取數(shù)據(jù)const info = JSON.parse(localStorage.getItem("info")); // 移除數(shù)據(jù)localStorage.removeItem("info"); // 清除localStorage.clear()
SessionStorage
// 存儲(chǔ)數(shù)據(jù) sessionStorage.setItem("info",JSON.stringify(info)); // 獲取數(shù)據(jù)const info = JSON.parse(sessionStorage.getItem("info")); // 移除數(shù)據(jù) sessionStorage.removeItem("info"); // 清除 sessionStorage.clear()
總結(jié)
到此這篇關(guān)于Vue組件傳參11種方式的文章就介紹到這了,更多相關(guān)Vue組件傳參方式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue實(shí)現(xiàn)導(dǎo)出word文檔的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何使用vue實(shí)現(xiàn)導(dǎo)出word文檔(包括圖片),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-01-01在Vuex使用dispatch和commit來(lái)調(diào)用mutations的區(qū)別詳解
今天小編就為大家分享一篇在Vuex使用dispatch和commit來(lái)調(diào)用mutations的區(qū)別詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09一個(gè)因@click.stop引發(fā)的bug的解決
這篇文章主要介紹了一個(gè)因@click.stop引發(fā)的bug的解決,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01uni-app中vue3表單校驗(yàn)失敗的問(wèn)題及解決方法
最近遇到這樣的問(wèn)題在app中使用uni-forms表單,并添加校驗(yàn)規(guī)則,問(wèn)題是即使輸入內(nèi)容,表單校驗(yàn)依然失敗,本文給大家分享uni-app中vue3表單校驗(yàn)失敗的問(wèn)題及解決方法,感興趣的朋友一起看看吧2023-12-12electron-vue利用webpack打包實(shí)現(xiàn)多頁(yè)面的入口文件問(wèn)題
項(xiàng)目需要在electron的項(xiàng)目中新打開(kāi)一個(gè)窗口,利用webpack作為靜態(tài)資源打包器,發(fā)現(xiàn)在webpack中可以設(shè)置多頁(yè)面的入口,今天來(lái)講一下我在electron中利用webpack建立多頁(yè)面入口的踩坑經(jīng)驗(yàn),需要的朋友可以參考下2019-05-05幾個(gè)你不知道的技巧助你寫(xiě)出更優(yōu)雅的vue.js代碼
本文參考自油管上某個(gè)國(guó)外大神的公開(kāi)演講視頻,學(xué)習(xí)了一下覺(jué)得很不錯(cuò),所以在項(xiàng)目中也使用了這些不錯(cuò)的技巧。趁周末有空,寫(xiě)個(gè)博客記錄一下2018-06-06Vue實(shí)現(xiàn)側(cè)邊菜單欄手風(fēng)琴效果實(shí)例代碼
本文通過(guò)一段簡(jiǎn)單的代碼給大家介紹了基于純vue實(shí)現(xiàn)側(cè)邊菜單欄手風(fēng)琴效果,代碼很簡(jiǎn)單,感興趣的朋友跟隨腳本之家小編一起看看吧2018-05-05vue.js學(xué)習(xí)筆記之綁定style樣式和class列表
數(shù)據(jù)綁定一個(gè)常見(jiàn)需求是操作元素的 class 列表和它的內(nèi)聯(lián)樣式。這篇文章主要介紹了vue.js綁定style和class的相關(guān)資料,需要的朋友可以參考下2016-10-10