手把手带你学会Odoo OWL组件开发(4):OWL组件
本期摘要
上一章中我们讲解了OwL的核心内容部分,即挂载,数据状态,数据监听,生命周期,组件传值及hook方法:
手把手带你学会Odoo OWL组件开发(3):核心内容指南
我们在前文了解OWL的生命周期,事件hook,等就是为了能够开发组件,组件和组件之间又是如何展示传值的呢,我们在这章会了解到相关的知识
作者
沈童 | 前端开发工程师
默默无闻,走向人生巅峰,激流勇进,退居幕后黑手
01
API
// template (string)
组件所关联的xml部分,t-name=“xxx”的值,或者jsx写法,在owl的js中书写
示例:
class OwlConfirm extends Component{ static template= "owl_confirm";
static template = static template = xml`
class="bg-info text-center p-2"> <b t-esc="start.title"> b> "data.Name">t>
class="fa fa-close p-1 float-right" style="cursor: pointer;" t-on-click="onRemove"> i> </div>`
}
// components (Object,optional)
object:组件下有哪些子组件 optional:自定义属性
示例:
class OwlConfirm extends Component{ static template= "owl_confirm"; static components = { OwlRadios };
}
// Props(Object,optional)
组件传值,的参数,拥有一个对象,和是否校验这个传值类型是否正确
type: 类型
element: 设定Object中每一项的类型
optional: 是否校验 blooer
示例:
class ComponentA extends owl.Component { static props = ['id', 'url'];
...
} class ComponentB extends owl.Component { static props = {
count: {type: Number},
messages: { type: Array,
element: {type: Object, shape: {id: Boolean, text: String }
},
date: Date,
combinedVal: [Number, Boolean],
optionalProp: { type: Number, optional: true }
};
...
}
02
Owl组件传值
// Prop
父组件传值给子组件
class Child extends Component { static template = xml`
"props.a"/>"props.b"/>
`;
} class Parent extends Component { static template = xml`
"state.a" b="'string'"/>
`; static components = { Child };
state = useState({ a: "fromparent" });
}
// EventBus
事件传值 owl的eventBus主要用法:
-
on 传值 (eventType, owner, callback) 事件名,传值内容,回调
-
off 销毁事件传值
const { EventBus } = owl.core; const bus = new EventBus(); //传值 let model = {
a:1,b:'string' }
bus.on("event",model,()=>console.log('传值')); //取值 const b = bus.subscriptions['event'][0].owner; console.log(b);
bus.off("event")//销毁
// 子传父
想要获取子组件数据,就可以通过下列方式
this.__owl__.parent.getChildrenMsg(this.data.msg),
03
Owl插槽t-slot
子组件内部内容由父组件提供,就是插槽
//匿名插槽
匿名插槽,就是一般默认插槽方式,在子组件中只有一个插槽时使用较多,默认值是 t-slot=“default ”, 这个时候在父组件中的子组件写入的标签,和内容等都会直接插入到子组件中展示
//具名插槽
具名插槽,顾名思义,就是,子组件的内如插槽,是有名字的,只有渲染对应名字的插槽内容。如下的t-slot=“header”和t-slot=“foot”都是具名插槽, 在父组件中,设置插槽名有两种
-
t-set-slot=“header” 一种是设置
-
slots=“foot” 一种是直接选定
XML部分
子组件
<div calss="owl-radios">
div>
父组件
<div> <div class="owl-popup-mask">div> <div class="owl-confirm-xl" id="owlConfirm"> <div class="owl-confirm-title"> 上面的子组件 <OwlRadios > <p>sssssp> <div slots="foot" url="sss"> <h2>车船税h2> div> <div t-set-slot="header"> <h2>22222sssh2> div> OwlRadios> div> <div class="owl-confirm-btn"> <div t-on-click="confimrBtn" class="btn btn-primary">确定div> <div t-on-click="closeConfim" class="btn btn-white ml20">取消div> div> div> div>
JS部分
注意:子组件的class必须在父组件之前,不然会报错
odoo.define('owl_components', function (require) { "use strict"; const { Component, useState ,hooks} = owl; const { xml } = owl.tags; const { useRef,useSubEnv, onMounted, onWillStart} = hooks; const {ComponentWrapper} = require("web.OwlCompatibility"); class OwlRadios extends Component{ static template= "owl_radios";
mounted(){ console.log(this.props)
}
} class OwlConfirm extends Component{ static template= "owl_confirm"; static components = { OwlRadios };
setup() { this.state = useState({ title: "測試", row:this.__owl__.parent.parentWidget.recordData, name:'' }); this.state.title = 'xxxxxxxx内容部分' this.inputRef = useRef("someDiv"); const model = { a:1, b:'ssss' };
useSubEnv(model);
}
someMethod() { console.log(this.inputRef)
}
changeVal(){ console.log(this.state.name)
}
confimrBtn(url){ console.log(this.state.row,'确定'); let self = this; console.log(this.env,'ssss')
} //关闭 closeConfim(){ this.destroy();
}
} return {
OwlConfirm,
}
});
04
Owl 动态组件 t-component
// 组件插槽
可以动态根据条件渲染子组件。
class A extends Component { static template = xml`
child a
`;
} class B extends Component { static template = xml`child b`;
} class Parent extends Component { static template = xml``;
state = useState({ child: "a" });
get myComponent() { return this.state.child === "a" ? A : B;
}
}
今天的内容就到这里,我们下期再见!