前端UI组件封装,要考虑传递属性事件、插槽,必要的话传ref出来
举例封装一个Vuetify组件 v-data-table
传递参数
在mounted
钩子打印this.$attrs
就是组件传递的的属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <!-- 子组件 --> <template> <div> <p>props a: {{ a }}</p> <p>$attrs: {{ $attrs }}</p> </div> </template>
<script> export default { props: { a: { type: String, default: () => (''), }, }, mounted() { console.log(this.$attrs); }, } </script>
|
在父组件传参a b c this.$attrs 打印 b c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <!-- 父组件 --> <template> <div class="pa-4"> <h1>测试组件封装 传参 a="1"b="2"c="3"</h1> <Son a="1" b="2" c="3" /> </div> </template> <script> import Son from './Son.vue';
export default { components: { Son, }, } </script>
|
默认把需要传递的参数,给子组件的UI框架组件添加上 v-bind="$attrs"
传递事件
子组件添加v-on="$listeners"
传递插槽
子组件循环$scopedSlots
ref传递
把UI组件上定义的的ref传给父组件(vue不支持ref传递,会有可能打破单项数据流,写出💩⛰️
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| mounted() {
},
|
mounted钩子ref注册全局方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <template> <v-app> <ios-header :loginDialog="$refs.loginDialog"/> <v-main> <info-alert ref="infoAlert" /> <pepper-snackbar /> <pepper-comfirm ref="confirm" /> <login-dialog ref="loginDialog" /> <pepper-loading /> <router-view /> </v-main> </v-app> </template>
<script> import PepperComfirm from '@pepper/pepperComponents/core/PepperConfirm.vue';
export default { name: 'App', components: { PepperComfirm, }, async mounted() { this.$root.$confirm = this.$refs.confirm; },
|
demo
DataTable.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| <template> <v-data-table v-bind="$attrs" v-on="$listeners" > <template v-for="(_, name) in $scopedSlots" #[name]="data" > <slot :name="name" v-bind="data" /> </template> </v-data-table> </template>
<script>
export default { name: 'DataTable', props: { }, data() { return { }; }, computed: { }, methods: { }, }; </script> <style lang="scss" scoped> ::v-deep .v-data-table-header { background-color: #3B3D4D !important; tr { border-radius: 5px; } // background: green !important; } .v-data-table { background-color: transparent !important; }
::v-deep .v-data-table__selected { background: linear-gradient(45deg, var(--v-primary-base) -200px, rgba(255, 255, 255, 0)) !important; }
::v-deep tr:hover:not(.v-data-table__expanded__content):not(.v-data-table__empty-wrapper) { background: linear-gradient(45deg, var(--v-primary-base) -200px, rgba(255, 255, 255, 0)) !important; } </style>
|