?🌈個人主頁:前端青山
🔥系列專欄:Vue篇
🔖人終將被年少不可得之物困其一生
依舊青山,本期給大家帶來vue篇專欄內容:vue3-組件傳參及計算屬性
目錄
vue3中的組件傳參
1、父傳子
2、子傳父
toRef 與 toRefs
vue3中的計算屬性
vue3 中的 watch監聽器
vue3中的組件傳參
組件關系:
父子 props、$panrent
子父 emit自定義事件 $children $refs
兄弟 eventbus中央事件總線 vue3如果需要實現eventbus 安裝第三方庫mitt
跨層級 provider inject
組件狀態共享工具: vuex pinia
1、父傳子
-
在父組件中給子組件設置自定義屬性 tit,將要傳遞的參數賦值給tit屬性
<!--父組件 -->
<template><p></p><Testvue3 :tit="schoolName"><span>123</span></Testvue3>
</template>
?
<script>
import Testvue3 from "@/components/Testvue3";
export default {name: "App",components: { Testvue3 },setup() {let schoolName = "千鋒"; // 定義要傳給子組件的數據 ?return {schoolName, // 要使用的變量拋出去,這樣就可以在頁面模板中使用該變量};},
};
</script>
-
在子組件中接收傳過來的屬性通過props ,這個和vue2 一樣沒有變化。
<!-- 子組件 -->
<template><p>{{ tit }}</p><button>點擊事件,子傳父</button>
</template>
?
<script>
export default {data() {return {};},props: ["tit"],setup(props) { // 參數props即為父組件傳過來的參數console.log(props)return {//setup函數返回值為一個對象};},
};
</script>
2、子傳父
-
給子組件綁定自定義事件,然后在setup中定義該事件對應的方法,因為setup中沒有this ,this為undefined,所以vue的開發者為了解決該問題,在setup中提供了2個形參,prop和context
-
props 為父傳子的參數
-
context 上下文對象,里面有emit 方法,可以實現子傳父
-
-
子組件中多了 emits選項,該選項類似于props,接收父組件給子組件綁定的自定義方法,如果不加該選項,vue3 會提示警告。但不影響功能
<!-- 子組件 -->
<template><p>{{ tit }}</p><button @click="emit">點擊事件,子傳父</button>
</template>
<script>
import { reactive } from "vue";
export default {data() {return {};},emits: ["transfer"], // 在子組件中使用emits配置項,接收父組件給我綁定的自定義事件,用法類似于props, // 不加該配置項,控制臺會提示警告setup(props, context) {console.log(11, props);console.log(22, context);// 定義方法function emit() {// 子傳父 此處不用this,使用context上下文對象context.emit("transfer", 666);}return {//setup函數返回值為一個對象emit,};},
};
</script>
-
在父組件接收自定義事件,該事件對應的執行函數的形參就是傳過來的數據,這個就和vue2一樣啦。
<!--父組件 --> <template><p></p><Testvue3 @transfer="showdata"><span>123</span></Testvue3> </template> <script> import Testvue3 from "@/components/Testvue3"; export default {name: "App",components: { Testvue3 },setup() {function showdata(value) {console.log(value);}return {showdata,};}, }; </script>
toRef 與 toRefs
定義:toRef 創建一個ref 響應數據
語法:let name = toRef(person,'name') 將響應對象person中的name屬性單獨拿出來變成響應屬性。
應用:一般用于將響應對象中的某個屬性單獨提供給外部使用
-
如下是使用toRef 前的代碼: 插值表達式模板中的 person 有點繁瑣
-
<!-- 子組件 -->
<template><div><p>{{ person.name }} -- {{ person.age }} -- {{ person.job.type }} --{{ person.job.salary }}</p></div> </template> ? <script> import { reactive } from "vue"; export default {setup() {let person = reactive({name: "張三",age: 20,job: {type: "web前端開發",salary: 30,},});return {person,};}, }; </script>
-
如下是使用toRef 后 的代碼,
-
<!-- 子組件 -->
<template><div><p><!-- 在模板中直接使用name,age,type,salary -->{{ name }} -- {{ age }} -- {{ type }} --{{ salary }}</p><p><button @click="name += '-'">修改name</button><button @click="salary++">修改薪水</button></p></div> </template> ? <script> import { reactive, toRef } from "vue"; export default {setup() {let person = reactive({name: "張三",age: 20,job: {type: "web前端開發",salary: 30,},});// 將person 中的name 屬性轉換成ref 響應式數據,這樣就可以直接在模板中使用了,以此類推let name = toRef(person, "name"); let age = toRef(person, "age");let type = toRef(person.job, "type");let salary = toRef(person.job, "salary");return {name,age,type,salary,};}, }; </script> <style scoped> /* @import url(); 引入css類 */ </style>
-
使用toRefs 可以將對象中的多個屬性轉換成響應數據,代碼如下:
-
<!-- 子組件 -->
<template><div><p>{{ name }} -- {{ age }} -- {{ job.type }} --{{ job.salary }}</p><p><button @click="name += '-'">修改name</button><button @click="job.salary++">修改薪水</button></p></div> </template> ? <script> import { reactive, toRefs } from "vue"; export default {setup() {let person = reactive({name: "張三",age: 20,job: {type: "web前端開發",salary: 30,},});//toRefs返回一個響應對象,該對象中每個屬性都變成了響應屬性了。這樣就可以直接拿來在模板插值表達式中使用了let person1 = toRefs(person);// console.log(person1);return {...person1, // 使用后擴展運算符展開對象};}, }; </script> <style scoped> /* @import url(); 引入css類 */ </style>
關于數據響應式設置的問題:
1、如何設置一個響應式數據? ref reactive
2、如何將非響應式數據轉為響應式數據? toRef toRefs
3、如何將數據設置為只讀數據?不能夠修改 readOnly
vue3中的計算屬性
同vue2不同,使用計算屬性需要引入computed 方法
<template><p>姓:<input type="text" v-model="data.firstname" /></p><p>名:<input type="text" v-model="data.lastname" /></p><p>姓名:<input type="text" v-model="data.fullname" /></p>
</template>
?
<script>
// 引入對應的計算屬性方法
import { reactive, computed } from "vue";
export default {name: "App",setup() {let data = reactive({firstname: "",lastname: "",fullname: "",});// 計算屬性--簡寫// data.fullname = computed(() => {// ? return data.firstname + data.lastname;// });// 計算屬性--完整寫法data.fullname = computed({get() {return data.firstname + data.lastname;},set(value) {console.log(value);data.firstname = value.substr(0, 1);data.lastname = value.substr(1);},});return {data,};},
};
</script>
vue3 中的 watch監聽器
vue3 中的watch 也是 組合式api中的一個方法,所以使用時,需要引入
<template><p>{{ sum }} <button @click="sum++">sum++</button></p><p>{{ fullname }} <button @click="fullname += '-'">修改姓名</button></p><p>{{ userinfo.name }}--{{ userinfo.age }}--{{ userinfo.job.type }}--{{userinfo.job.salary}}K<button @click="userinfo.age++">修改年齡</button><button @click="userinfo.job.salary++">修改薪水</button></p>
</template>
<script>
// 引入對應的計算屬性方法
import { ref, watch, reactive } from "vue";
export default {name: "App",setup() {let sum = ref(0);let fullname = ref("張三");let userinfo = reactive({name: "李四",age: 20,job: {type: "web開發",salary: 20,},});//1、監聽ref定義的響應式數據 immediate初始化就執行watchwatch(sum, (newvalue, oldvalue) => {console.log(newvalue, oldvalue);},{immediate:true});//2、 監聽ref定義的多個響應式數據,immediate初始化就執行watchwatch([sum, fullname], (newvalue, oldvalue) => {console.log(newvalue, oldvalue);}, { immediate: true });
?//3、 監聽reactive 定義的響應式數據// 注意:此處oldvalue 無效(新值與舊值一樣),默認是深度監聽,immediate初始化就執行watchwatch(userinfo,(newvalue, oldvalue) => {console.log(newvalue, oldvalue);},{ immediate: true });return {sum,fullname,userinfo,};},
};
</script>
watch
和watchEffect
都能響應式地執行有副作用的回調。它們之間的主要區別是追蹤響應式依賴的方式:
watch
只追蹤明確偵聽的數據源。它不會追蹤任何在回調中訪問到的東西。另外,僅在數據源確實改變時才會觸發回調。watch
會避免在發生副作用時追蹤依賴,因此,我們能更加精確地控制回調函數的觸發時機。
watchEffect
,則會在副作用發生期間追蹤依賴。它會在同步執行過程中,自動追蹤所有能訪問到的響應式屬性。這更方便,而且代碼往往更簡潔,但有時其響應性依賴關系會不那么明確。