自由设计师网站,医药网站开发,凤蝶直播,永修中铁三局招聘文章目录 一、$attrs的概念和使用场景概念使用场景 二、代码解释Father.vueChild.vueGrandChild.vue 三、另一个$attrs使用的例子 一、$attrs的概念和使用场景
概念
在Vue 3.0中#xff0c;$attrs是一个组件实例属性#xff0c;它包含了父组件传递给子组件的所有非props属性… 文章目录 一、$attrs的概念和使用场景概念使用场景 二、代码解释Father.vueChild.vueGrandChild.vue 三、另一个$attrs使用的例子 一、$attrs的概念和使用场景
概念
在Vue 3.0中$attrs是一个组件实例属性它包含了父组件传递给子组件的所有非props属性。这里的非props属性是指那些父组件传递过来但子组件没有通过props显式定义来接收的属性。当父组件向子组件传递数据时$attrs就像是一个“属性收集器”自动收集这些未被props接收的属性以便在组件内部或继续向下传递给更深层的子组件时使用。
使用场景
多层组件嵌套中的属性透传在多层嵌套的组件结构中经常会遇到父组件的某些属性需要传递给更深层的子组件但中间的一些组件并不需要使用这些属性的情况。此时就可以利用$attrs来实现属性的“穿透式”传递无需在每个中间组件都去定义props来接收和再次传递这些属性大大简化了多层组件间数据传递的流程。动态属性传递当需要动态地向子组件传递一些属性且这些属性的具体内容可能会根据不同的业务场景或用户操作而变化时使用$attrs会很方便。因为不需要提前在子组件中为每一个可能传递的属性都定义好props只需要在父组件传递时将相关属性附上子组件通过$attrs就能获取到这些动态传递的属性。
二、代码解释
代码
Father.vue
templatediv classfatherh3父组件/h3h4a{{ a }}/h4h4b{{ b }}/h4h4c{{ c }}/h4h4d{{ d }}/h4!-- 下面这行中的v-bind可以传对象比如下面传递了一个{x:100,y:200}那就相当于给子组件传递了两个props属性一个是x一个是y 然后下面子组件中去接收就行 --Child:aa:bb:cc:dd v-bind{x:100,y:200}:updateAupdateA//div
/templatescript setup langts nameFather
import Child from ./Child.vue
import { ref } from vuelet a ref(1)
let b ref(2)
let c ref(3)
let d ref(4)function updateA(value: number) {a.value value
}
//测试一下在自己的组件中只定义的变量是否会被放在$attrs中
const productId ref(123);
const productName ref(Awesome Product);
const productImage ref(product-image.jpg);
/scriptstyle scoped
.father {background-color: rgb(165, 164, 164);padding: 20px;border-radius: 10px;
}
/style
在Father.vue组件的模板部分通过属性绑定的方式向Child组件传递了多个属性包括a、b、c、d以及一个通过v-bind绑定的对象{x:100,y:200}还有updateA函数。在脚本部分定义了a、b、c、d这几个ref类型的响应式数据并初始化了相应的值同时定义了updateA函数用于更新a的值。
Child.vue
templatediv classchildh3子组件/h3h4a:{{a}}/h4h4b:{{b}}/h4h4其他{{$attrs}}/h4!-- 下面这行相当于传递了很多props给子组件 --GrandChild v-bind$attrs //div
/templatescript setup langts nameChild
import GrandChild from ./GrandChild.vue
// defineProps([a,b]) //我现在对于父传过来的属性一个也不想使用所以传过来的这些都在$attrs中直接将这些传递给这个组件的子组件也就是孙子组件
/scriptstyle scoped
.child {margin-top: 20px;background-color: skyblue;padding: 20px;border-radius: 10px;box-shadow: 0 0 10px black;
}
/style在Child.vue的模板部分展示了a和b的值这里假设是为了示意可以获取到这些值虽然在实际代码逻辑中作者提到不想使用这些属性并通过v-bind$attrs将$attrs中的所有属性传递给了GrandChild组件。在脚本部分虽然定义了defineProps([a,b])但作者表示本意是不想使用父组件传递过来的这些属性所以实际上这些属性还是会被放到$attrs中继续向下传递。
GrandChild.vue
templatediv classgrand-childh3孙组件/h3h4a{{ a }}/h4h4b{{ b }}/h4h4c{{ c }}/h4h4d{{ d }}/h4h4x{{ x }}/h4h4y{{ y }}/h4button clickupdateA(6)点我将爷爷那的a更新/button button clickmybutton点我试一试/button/div
/templatescript setup langts nameGrandChild
import {ref} from vue
const {c} defineProps([a, b, c, d,x,y,updateA])function mybutton(){console.log(,c);}
/scriptstyle scoped
.grand-child {margin-top: 20px;background-color: orange;padding: 20px;border-radius: 10px;box-shadow: 0 0 10px black;
}
/style在GrandChild.vue的模板部分展示了从父组件通过$attrs传递过来的a、b、c、d、x、y等属性的值并且有一个按钮点击该按钮会调用updateA(6)函数这个函数是从父组件传递过来的用于更新Father.vue组件中a的值。在脚本部分通过defineProps([a, b, c, d,x,y,updateA])正确地接收了从父组件传递过来的这些属性使得在模板中能够正常使用它们。
三、另一个$attrs使用的例子
假设我们有一个电商应用场景有一个ProductPage组件产品页面组件它包含一个ProductDetails组件产品详情组件和一个ProductReviews组件产品评论组件。ProductPage组件会接收到一些关于产品的通用属性如productId、productName等这些属性需要传递给ProductReviews组件但ProductDetails组件并不需要使用这些属性。
ProductPage.vue组件
templatediv classproduct-pageProductDetails :productImageproductImage /ProductReviews v-bind{productId:productId,productName:productName,productImage:productImage} //div/templatescript setup langts nameProductPageimport ProductDetails from ./ProductDetails.vue;import ProductReviews from ./ProductReviews.vue;import { ref } from vue;const productId ref(123);const productName ref(Awesome Product);const productImage https://images.dog.ceo//breeds//pembroke//n02113023_11091.jpg/scriptstyle scoped.product-page {padding: 20px;}/styleProductDetails.vue组件
templatediv classproduct-detailsimg :srcproductImage altProduct Imageh2Product Details/h2h4{{productImage}}/h4/div/templatescript setup langts nameProductDetailsimport { ref } from vue;import { defineProps } from vue;// const productImage ref();defineProps([productImage])/scriptstyle scoped.product-details {background-color: lightgray;padding: 10px;}/styleProductReviews.vue组件
templatediv classproduct-reviewsh2Product Reviews/h2!-- h4{{$attrs}}/h4 --pProduct ID: {{ productId }}/ppProduct Name: {{ productName }}/pbutton clickfetchReviewsFetch Reviews/button/div/templatescript setup langts nameProductReviewsimport { onMounted, ref, toRefs,defineProps } from vue;
const {productId,productName} defineProps([productId,productName])// onMounted(() {
// const attrs $attrs;
// ({ productId, productName } toRefs(attrs));
// });
// // const { productId, productName } toRefs($attrs);const fetchReviews () {// 这里可以根据productId去获取对应的产品评论数据等操作console.log(Fetching reviews for product,productId);};/scriptstyle scoped.product-reviews {background-color: lightyellow;padding: 10px;}/style在这个例子中ProductPage组件将productId和productName等属性通过$attrs传递给了ProductReviews组件而ProductDetails组件不需要处理这些属性实现了在电商应用场景下组件间属性的合理传递。