组件封装:如果一块内容在项目中出现了两次就要考虑是否应进行封装。
一个组件、一个函数、一个css 只要是需要多次使用的都可以考虑封装。
项目中有个需求。因为这种需求在其他页面也用到很多,于是写成组件。
具体思路:我们在父组件引用子组件,确认好变量,再通过父传子传给组件。子组件通过props接收父组件的值。
在封装组件时,遇到几个问题:
1、组件应该做到适应大部分页面应用场景,那么如何把组件的某些内容如何灵活处理呢?
2、子组件通过props接收父组件的值,那如果父组件传的是对象,子组件该如何接收父组件传的对象呢?
3、不推荐子组件修改父组件传过来的值,但是有时候不得不修改,那子组件该如何修改父组件的值呢?
具体代码:
html部分
<Modal
v-model="isShowModal"
footer-hide
:title="title"
>
<!--弹框内容-->
<p>是否确认删除。。。</p>
<!--组件具体职责-->
</Modal>
问题1:弹框组件的内容不一定相同,有的是删除有的是编辑内容有的甚至是表格,那如何做到适应所有页面呢?
解决办法:插槽很好的解决了这个问题,只需将上述代码弹框内容<p></p>改成<slot></slot>即可,如下图:
改成插槽之后,在父组件中引用,就可以自定义插槽内容啦,示例如下:
<secondary-modal :isShowModal.sync="isShowModal" @onSave="onSave()" :title="modalTitle" :okText="okText">
// 具体内容
</secondary-modal>
问题2:子组件按如下方法接收父组件对象,遇到如下问题:
// 错误写法
props: {
formData: {
type: Object,
default: {},
},
完整报错信息:Invalide default value for prop “xxx”:Props with type Object/Array must use a factory function to return
其实看错误信息也就知道了,就是Props在传值类型为Object/Array时,如果需要配置default值(如果没有配置default值,则不会有这个报错),那必须使用函数来return这个default值,而不能像基本数据类型那样直接写default:xxx
解决方法:
// 正确写法
formData: {
type: Object,
default: () => {
return {};
},
},
问题3:在修改父组件传过来的值时,遇到如下问题
// 错误写法
cancel() {
// 直接修改父组件传过来的值
this.isShowModal = false
},
完整错误信息 :Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "xxx"
意思是子组件直接修改了来源于父组件的 isShowModal属性, 这是不合法的
解决办法:
父组件中:传值时使用.sync(双向绑定)
子组件:
cancel() {
// this.$emit("update:需要修改的字段", 修改的值);
this.$emit("update:isShowModal", false);
},
有问题欢迎指出~