欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue2的16種傳參通信方式總結(jié)和示例講解

 更新時間:2024年08月24日 09:53:23   作者:Monstar_0°-蒙  
Vue2中路由傳參數(shù):props(父傳子),$emit與v-on(子傳父),EventBus(兄弟傳參),.sync與update:(父子雙向),v-model(父子雙向),ref?$children與$parent,$attrs與$listeners(爺孫雙向),provide與inject(多層傳參),Vuex,Vue.prototype,路由,瀏覽器緩存,window,$root,slot(父傳子)

前言

先直入主題列出有哪些傳參方式,下面再通過事例一一講解。

props(父傳子)
$emitv-on (子傳父)
EventBus (兄弟傳參)
.syncupdate: (父子雙向)
v-model (父子雙向)
ref$children$parent
$attrs$listeners (爺孫雙向)
provideinject (多層傳參)
Vuex (全局)
Vue.prototype (全局)
路由
瀏覽器緩存 (全局)
window (全局)
$root (頂層)
slot(父傳子)

一、props(父傳子)

思路簡述:父組件直接用冒號:綁定變量,然后子組件通過props接收父組件傳過來的內(nèi)容。

父組件代碼:核心代碼在第3行,直接用:message="message"傳參。

<template>
  <div>
    <child  :message="message" />
  </div>
</template>

<script>
import child  from './child .vue';
export default {
  components: {
    child 
  },
  data() {
    return {
      message: '這是父組件傳過去的'
    };
  }
};
</script>

子組件代碼: 用props接收消息后可以直接使用,如下第3行和第16行中直接使用

注意: props有兩種接收方法,如下第9行注釋的就是簡寫用法,此用法不能設(shè)置默認(rèn)值。

<template>
  <div>
    <p>接收到的消息: {{ message }}</p>
  </div>
</template>

<script>
  export default {
    //props:['message'],
    props: {
      message: {
        type: String,
        default: '', // 這里能設(shè)置默認(rèn)值,如果父組件沒有傳參,默認(rèn)值會生效
      },
    },
    mounted() {
      console.log(this.message);
    },
  };
</script>

注意: 此傳參方式是單向的,即子組件接收到父組件的數(shù)據(jù)后,是不能直接修改props接收的數(shù)據(jù),否則會直接報錯。

二、$emitv-on (子傳父)

思路簡述: 子組件通過$emit觸發(fā)父組件的指定方法并且在此方法中攜帶任意參數(shù),父組件通過在被觸發(fā)的方法中拿到攜帶的參數(shù)完成子傳父。

語法:$emit(方法名,參數(shù))

子組件代碼:核心代碼在第11行,觸發(fā)方法并且攜帶參數(shù)。

<template>
  <div>
    <button @click="sendParent">點(diǎn)擊發(fā)送數(shù)據(jù)給父組件</button>
  </div>
</template>

<script>
  export default {
    methods: {
      sendParent() {
        this.$emit('my-event', '這是傳遞的參數(shù)');
      },
    },
  };
</script>

父組件代碼:核心代碼在第3行觸發(fā)事件,獲取到子組件的傳參。

<template>
  <div>
    <child v-on:my-event="childEvent" />
    // 或者用@簡寫代替v-on
    <child @my-event="childEvent" />
  </div>
</template>

<script>
  import child from './child.vue';
  export default {
    components: {
      child,
    },
    methods: {
      childEvent(item) {
        console.log('接收到子組件的傳參:', item);
      },
    },
  };
</script>

三、EventBus (兄弟傳參)

思路簡述: 先創(chuàng)建一個全局的事件總線Bus(可以隨意命名),并掛載在Vue.prototype上。

然后兄弟組件A通過$emit發(fā)送參數(shù),兄弟組件B通過$on接收參數(shù)。

  • 有兩種使用方法,下面分別講解。

方法一:直接掛載全局事件總線,全局直接使用不需要額外引入。

先在項(xiàng)目的入口文件中(main.jsmain.ts)創(chuàng)建全局事件Bus并且掛載在Vue.prototype*

import Vue from 'vue';

const Bus = new Vue();

Vue.prototype.$Bus = Bus;

兄弟組件A代碼:通過this.$Bus.$emit(方法名,參數(shù))發(fā)送參數(shù)。

<template>
  <div>
    <button @click="sendSibling">點(diǎn)擊發(fā)送內(nèi)容給兄弟組件</button>
  </div>
</template>

<script>
  export default {
    methods: {
      sendSibling() {
        this.$Bus.$emit('my-event', '參數(shù)');
      },
    },
  };
</script>

兄弟組件B代碼:通過this.$Bus.$on(對應(yīng)$emit的方法,本地方法)觸發(fā)本地的方法,從而接收參數(shù)。

<template>
  <div> 我是兄弟組件B </div>
</template>

<script>
  export default {
    created() {
      this.$Bus.$on('my-event', this.handleMessage);
    },
    beforeDestroy() {
      this.$Bus.$off('my-event', this.handleMessage);
    },
    methods: {
      handleMessage(message) {
        console.log('來自兄弟的參數(shù):', message);
      },
    },
  };
</script>

注意: 如上第10-12行所示,在組件銷毀前要在 beforeDestroy 生命周期中使用$off移除移除$on的事件監(jiān)聽器,防止避免內(nèi)存泄漏影響性能。如下所示

方法二: 不創(chuàng)建全局事件總線,單獨(dú)開一個文件,哪里需要就哪里引用。

創(chuàng)建一個單獨(dú)文件命名為Bus.js(可以自由命名)

import Vue from "vue"

export default new Vue()

兄弟組件A代碼: 先引入Bus.js文件,然后通過Bus.$emit(方法名,參數(shù))發(fā)送參數(shù)。

<template>
  <div>
    <button @click="sendSibling">點(diǎn)擊發(fā)送內(nèi)容給兄弟組件</button>
  </div>
</template>

<script>
  import Bus from './Bus.js';
  export default {
    methods: {
      sendSibling() {
        Bus.$emit('my-event', '參數(shù)');
      },
    },
  };
</script>

兄弟組件B代碼:先引入Bus.js文件,然后通過Bus.$on(對應(yīng)$emit的方法,本地方法)觸發(fā)本地的方法,從而接收參數(shù)。同樣也需要使用$off銷毀事件監(jiān)聽。

<template>
  <div> 我是兄弟組件B </div>
</template>

<script>
  import Bus from './Bus.js';
  export default {
    created() {
      Bus.$on('my-event', this.handleMessage);
    },
    beforeDestroy() {
      Bus.$off('my-event', this.handleMessage);
    },
    methods: {
      handleMessage(message) {
        console.log('來自兄弟的參數(shù):', message);
      },
    },
  };
</script>

四、.syncupdate: (父子雙向)

思路簡述:.sync其實(shí)是一個語法糖, 配合子組件用this.$emit('update:綁定的屬性名', 方法)修改父組件屬性, 能解決props只能單向傳遞的問題。

父組件代碼:核心代碼在第3行,比普通的父傳子多使用了.sync修飾符。

<template>
  <div>
    <chile :myprop.sync="myData" />
  </div>
</template>

<script>
import chile from './chile.vue';

export default {
  components: {
    chile
  },
  data() {
    return {
      myData: '父組件數(shù)據(jù)'
    };
  }
};
</script>

子組件代碼:核心代碼是第14行,通過this.$emit同步修改父組件內(nèi)容。

<template>
  <div>
    <button @click="updateData">點(diǎn)擊子修改父傳過來的數(shù)據(jù)</button>
  </div>
</template>

<script>
  export default {
    props: {
      myprop: String,
    },
    methods: {
      updateData() {
        this.$emit('update:myprop', 新內(nèi)容);
      },
    },
  };
</script>

注意:使用.sync修飾符時,this.$emit里面總是以update:開頭,后面接要修改的屬性名稱。

五、v-model (父子雙向)

思路簡述:v-model最常用于表單,它其實(shí)是一個語法糖,并且和上面.sync有點(diǎn)類似。v-model本質(zhì)上是v-bind:value@input組件效果。通過v-bind:value綁定數(shù)據(jù)父傳子,通過@input觸發(fā)對應(yīng)事件子傳父從而實(shí)現(xiàn)雙向綁定。

父組件代碼:直接用v-model綁定要傳給子組件的參數(shù),當(dāng)子組件觸發(fā)input事件時父組件myData會同步更新。

<template>
  <div>
    <child v-model="myData" />
  </div>
</template>

<script>
import child from './child.vue';

export default {
  components: {
    child
  },
  data() {
    return {
      myData: '天天鴨'
    };
  }
};
</script>

子組件代碼:當(dāng)input輸入框的內(nèi)容發(fā)生變化時,就會觸發(fā)@input事件,然后this.$emit同步修改父組件的值

<template>
  <div>
    <input :value="childData" @input="handleChange" />
  </div>
</template>

<script>
export default {
  model: {
    prop: 'myProp',
    event: 'input'
  },
  props: {
    myProp: String
  },
  data() {
    return {
      childData: this.myProp
    };
  },
  methods: {
    handleChange(event) {
      this.childData = event.target.value;
      this.$emit('input', this.childData);
    }
  }
};
</script>

注意:在子組件當(dāng)中,必須要定義model來指定props和事件名稱(名稱默認(rèn)為input)。

六、ref

思路講解: ref主要用來訪問子組件的方法和屬性,是直接操縱DOM的方式。主要用法是在子組件上綁定一個ref,然后父組件用this.$refs直接訪問子組件的方法

父組件代碼:子組件上用ref="refChild"綁定一個ref,然后用this.$refs.refChild獲取到子組件實(shí)例,能獲取到子組件屬性和操縱子組件方法。

<template>
  <div>
    <child ref="refChild" />
  </div>
</template>

<script>
  import child from './child.vue';
  export default {
    components: {
      child,
    },
    mounted() {
      let childObj = this.$refs.refChild;
      console.log(childObj.name); // 直接獲取到子組件的屬性內(nèi)容 打印出來:天天鴨
      childObj.childMethod('參數(shù)'); // 觸發(fā)子組件的方法
    },
  };
</script>

子組件代碼:

<template>
  <div></div>
</template>

<script>
  export default {
    data() {
      return {
        name: '天天鴨',
      };
    },
    methods: {
      childMethod(val) {
        console.log(val);
      },
    },
  };
</script>

七、$children$parent

簡述: $children 和 $parent 是Vue用于訪問子組件實(shí)例和父組件實(shí)例的特殊屬性。其中$children能獲取所有子組件實(shí)例但不能獲取孫子的,而$parent獲取當(dāng)前組件的父組件實(shí)例。

父組件代碼: 直接使用this.$children即可獲取。

注意: 獲取到的實(shí)例可能為空,因此需要判空。并且如果有多個子組件時返回的是一個數(shù)組,所以需要通過下標(biāo)確認(rèn)對應(yīng)的子組件數(shù)據(jù)。

<template>
  <div>
    <child />
    <button @click="getChildMethod">調(diào)用子組件方法</button>
  </div>
</template>

<script>
  import child from './child.vue';
  export default {
    components: {
      child,
    },
    methods: {
      getChildMethod() {
       // 判空,然后用下標(biāo)獲取
        if (this.$children.length > 0) {
          this.$children[0].childMethod();  // 使用子組件方法
          this.$children[0].name;    // 使用子組件屬性
        }
      },
    },
  };
</script>

子組件代碼: 類似地,父組件也是同樣用法,但區(qū)別是返回的不是數(shù)組而且一個對象,能直接使用。

<template>
  <div></div>
</template>

<script>
  export default {
    mounted(){
        this.$parent.parMethod()
        this.$parent.name
    }
  };
</script>

八、$attrs$listeners (爺孫雙向)

簡述: $attrs和 $listeners相當(dāng)于是使用在父親組件上的一個中轉(zhuǎn)站。 $attrs用于將props外的數(shù)據(jù)從爺組件傳遞給孫組件的,而$listeners用于從孫組件中觸發(fā)爺組件中事件達(dá)到傳參效果。

下面把$attrs$listeners分開講解更易于理解。

$attrs使用流程代碼:

(1)爺組件代碼: 類似父傳子,正常用冒號綁定屬性傳參。

<GrandParent :name=name></GrandParent>

(2)父組件代碼$attrs作用在父組件,意思是把props之外屬性全部傳遞給到孫子。

注意:如果這里父組件用props接收了name屬性,那么用$attrs無法傳遞到孫子組件,因?yàn)橹荒軅鬟fprops之外屬性。

<Parent v-bind="$attrs"></Parent>

(3)孫組件代碼:類似父傳子,正常用popos接收爺組件傳過來的參數(shù)。

<template>
  <div> 爺組件傳來的:{{ name }} </div>
</template>
<script>
  export default {
    props: {
      name: {
        default: String,
      },
    },
  };
</script>

$listeners使用流程代碼:

(1)孫組件代碼 直接this.$emit類似子傳父

<template>
  <div>
    <el-button @click="update">點(diǎn)擊孫傳爺</el-button>
  </div>
</template>

<script>
  export default {
    methods: {
      update() {
        this.$emit('my-event', '孫傳給爺?shù)臄?shù)據(jù)');
      },
    },
  };
</script>

(2)父組件代碼:$listeners作用在父組件。

<Parent v-bind="$listeners"></Parent>

(3)爺組件代碼: 類似子傳父中的父組件,觸發(fā)對應(yīng)孫子組件this.$emit中的my-event事件接收到參數(shù)。

<template>
  <div>
    <Parent @my-event="getMyEvent" />
  </div>
</template>

<script>
  import Parent from './Parent.vue';
  export default {
    components: {
      Parent,
    },
    methods: {
      getMyEvent(val) {
        console.log('爺組件接收到的數(shù)據(jù):', val);
      },
    },
  };
</script>

這里感覺算兩種(爺傳孫與孫傳爺)傳參方式了,但由于都是類似中轉(zhuǎn)站效果,所以放一起說比較好理解。

九、provideinject (多層傳參)

簡述: provideinject無論多少層組件都能傳參。頂層組件通過provide傳參,下面所有組件都能用inject接收,而且子組件也能通過方法給頂層組件傳參。

頂層組件代碼: 核心代碼在第8行的provide()中,可以傳遞常量、變量和方法。

<template>
  <div> </div>
</template>

<script>
  export default {
    provide() {
      return {
        name: '天天鴨',
        age: this.age,
        myMethod: this.myMethod,
      };
    },
    data() {
      return {
        age: '18',
      };
    },
    methods: {
      myMethod(data) {
        console.log('收到來自某個孫子的數(shù)據(jù):', data);
      },
    },
  };
</script>

子孫組件代碼:核心代碼在第10行接收參數(shù), 除了能接收頂層參數(shù)外,還能通過參考第13行的用法,通過頂層給到的方法傳參給頂層組件。

<template>
  <div>
    <el-button @click="myMethod('我是孫子組件')">我是孫子組件</el-button>
    這是頂層傳下來的參數(shù): {{ name }}
  </div>
</template>

<script>
  export default {
    inject: ['name', 'age', 'myMethod'],
    methods: {
      myMethod(data) {
        this.myMethod(data); // 傳參給頂層祖先組件
      },
    },
  };
</script>

十、Vuex (全局)

有針對性寫過對應(yīng)的文章,可以直接跳轉(zhuǎn)細(xì)看:對比學(xué)習(xí)vuex和pinia用法

十一、Vue.prototype (全局)

簡述:能用Vue.prototype把任何屬性和方法掛載在Vue實(shí)例了,讓所有Vue實(shí)例共用。

(1)掛載屬性 直接往Vue.prototype掛載即可

Vue.prototype.$testName = '天天鴨';

(2)掛載方法直接往Vue.prototype掛載即可

Vue.prototype.$testMethod = function(val) {
  console.log(val);
};

調(diào)用:直接在任何頁面用this調(diào)用

this.$appName;

this.$testMethod('參數(shù)');

十二、瀏覽器緩存

簡述: localStorage 和sessionStorage:主要是瀏覽器用來持久化存儲的,這算是用的不多,但也是必用的一種通信方式。兩者區(qū)別如下

sessionStorage(臨時存儲):最大空間5M,為每一個數(shù)據(jù)源維持一個存儲區(qū)域,但只在瀏覽器打開期間存在,關(guān)閉后數(shù)據(jù)會不會消失,包括頁面重新加載。
localStorage(長期存儲):最大空間5M,與 sessionStorage 一樣,但是哪怕瀏覽器關(guān)閉后,數(shù)據(jù)依然會一直存在,除非手動刪除。

具體用法如下所示:

// 存儲
sessionStorage.setItem('key', 'value');
localStorage.setItem('key', 'value');

// 獲取
let valueFromSessionStorage = sessionStorage.getItem('key');
let valueFromLocalStorage = localStorage.getItem('key');

// 刪除
sessionStorage.removeItem('key');
localStorage.removeItem('key');

// 清空所有
sessionStorage.clear();
localStorage.clear();

注意:存儲的數(shù)據(jù)只能是字符串形式,因此如果要存儲對象或者數(shù)組,則需要使用JSON.stringify來轉(zhuǎn)換后再存儲,讀取后用JSON.parse還原。

十三、window (全局)

簡述: 直接用語法 window.age = '18' 定義然后全局通用即可。(此方式是存放在內(nèi)存刷新會清空)

注意:在 Vue 應(yīng)用中,雖然可以直接將屬性掛載到 window 對象上實(shí)現(xiàn)全局通用,但并推薦,因?yàn)?code>這可能會出現(xiàn)命名沖突、導(dǎo)致代碼難以維護(hù)。

添加屬性和方法:直接定義,可以是屬性也可以是對象

window.Obj = { test: '掛載對象' }
window.name = '天天鴨'

使用:

console.log( window.Obj); 
console.log( window.name);

十四、路由

簡述: Vue在路由跳轉(zhuǎn)時攜帶參數(shù)其實(shí)也很常用的方式,下面匯總一下三種路由傳參。

(1)通過 params 傳參 跳轉(zhuǎn)頁面用法:

this.$router.push({name:"index", params:{id}})

目標(biāo)頁面接收參數(shù):

this.$route.params.id

(2)通過 query 傳參

跳轉(zhuǎn)頁面用法:有幾種方式

this.$router.push({ name:"index", query:{id}})

this.$router.push({ path:"/index", query:{id}}) 

this.$router.push('/index?name='+obj.name+'&age='+obj.age)

目標(biāo)頁面接收參數(shù):

this.$route.query.id

(3)通過動態(tài)路由傳參

注意: 如果用動態(tài)路由傳參需要對路由進(jìn)行配置;并且參數(shù)會在 url 中顯示。 如下所示,在path后面要配置:name/:age.

{ 
  path: '/about/:name/:age' ,  
  name: 'About', 
  component() => import('@/views/About.vue') 
}

跳轉(zhuǎn)頁面用法:

this.$router.push('/about/'+obj.name+'/'+obj.age)

目標(biāo)頁面接收參數(shù):

this.$route.params

十五、$root (頂層)

簡述: 可以通過 $root 訪問到整個 Vue 樹的根實(shí)例,也就是可以使用 $root 來訪問全局的屬性或者修改全局的屬性。

示例:在main.js文件中定義一個globalName屬性,可以全局使用。

import App from './App.vue';
import Vue from 'vue';

new Vue({
  el: '#app',
  render: h => h(App),
  data: {
    globalName: '天天鴨'
  }
});

在下層任意組件使用或者修改內(nèi)容

<template>
  <div>
    {{ globalName }}
  </div>
</template>

<script>
export default {
  mounted() {
    this.$root.globalName = '修改數(shù)據(jù)';
  },
};
</script>

十六、slot(父傳子)

簡述: 通過插槽也是可以傳遞參數(shù),這也是很多人忽略的一種方式。父組件可以通過插槽向子組件傳遞參數(shù),然后子組件拿到參數(shù)進(jìn)行渲染。

下面主要講解具名插槽和默認(rèn)插槽兩種使用方式。

(1)具名插槽用法

子組件代碼: 用slot定義一個名叫header的插槽。

<template>
  <div>
    <slot name="header"></slot>
  </div>
</template>

<script>
export default {
};
</script>

父組件代碼:v-slot:header向子組件的header插槽傳遞內(nèi)容。這邊傳遞什么那邊就會在對應(yīng)區(qū)域顯示什么。

<template>
  <div>
    <child>
        <template v-slot:header>
          <h1>這是插槽的內(nèi)容</h1>
        </template>
    </child>
  </div>
</template>

<script>
import child from './child.vue';

export default {
  components: {
    child
  }
};
</script>

(2)無參數(shù)傳遞的默認(rèn)插槽

子組件代碼: 用slot定義插槽時不需要指定name名稱。

<template>
  <div>
    <slot></slot>
  </div>
</template>

<script>
export default {
};
</script>

父組件代碼:不需要指定插槽名稱,只要在組件中間填寫內(nèi)容就會渲染在默認(rèn)插槽中。

<template>
  <div>
    <child>
      <p>默認(rèn)插槽中的內(nèi)容。</p>
    </child>
  </div>
</template>

<script>
import child from './child.vue';

export default {
  components: {
    child
  }
};
</script>

總結(jié)

Vue2中路由傳參數(shù)方式:props(父傳子),$emit與v-on(子傳父),EventBus(兄弟傳參),.sync與update:(父子雙向),v-model(父子雙向),ref $children與$parent,$attrs與$listeners(爺孫雙向),provide與inject(多層傳參),Vuex,Vue.prototype,路由,瀏覽器緩存,window,$root,slot(父傳子)。

到此這篇關(guān)于Vue2的16種傳參通信方式總結(jié)和示例講解的文章就介紹到這了,更多相關(guān)Vue2的16種傳參通信方式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論