完整目录请见Odoo 14全新前端框架 OWL(Odoo Web Library)官方文档中文版
🦉 快速总览 🦉
应用中的Owl组件用于定义一个(动态)组件树。
1 2 3 4 5 |
Root / \ A B / \ C D |
状态(state):各组件可管理其自身的本地状态。这是一个简单的ES6类,没有特殊规则:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Counter extends Component { static template = xml` <button t-on-click="increment"> Click Me! [<t t-esc="state.value"/>] </button>`; state = { value: 0 }; increment() { this.state.value++; this.render(); } } |
以上示例展示了一个具有本地状态的组件。注意state
对象并没有什么超能力,因此在其更新时我们需要手动地调用render
函数。这很容易让人觉得麻烦(多次进行时会显得低效)。有一种更好的方式:使用useState
钩子,它将对象转化为其自身的响应式(reactive)版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
const { useState } = owl.hooks; class Counter extends Component { static template = xml` <button t-on-click="increment"> Click Me! [<t t-esc="state.value"/>] </button>`; state = useState({ value: 0 }); increment() { this.state.value++; } } |
注意还可以使用行内语句来替换掉t-on-click
这一handler:
1 |
<button t-on-click="state.value++"> |
属性(props):子组件经常需要从父组件获取一些信息。这可通过向模板添加所需信息来实现。然后通过props
对象中的子组件进行获取。注意有一条重要规则:props
对象中包含的信息不由子组件持有,不应进行修改。
1 2 3 4 5 6 7 8 9 10 11 12 |
class Child extends Component { static template = xml`<div>Hello <t t-esc="props.name"/></div>`; } class Parent extends Component { static template = xml` <div> <Child name="'Owl'" /> <Child name="'Framework'" /> </div>`; static components = { Child }; } |
通信:有很多种方式在组件间进行信息通讯。但最重要的两种方式如下:
- 使用
props
从父组件向子组件通信, - 通过触发事件从子组件向父组件通信
以下的示例描述了这两种机制:
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 |
class OrderLine extends Component { static template = xml` <div t-on-click="add"> <div><t t-esc="props.line.name"/></div> <div>Quantity: <t t-esc="props.line.quantity"/></div> </div>`; add() { this.trigger("add-to-order", { line: props.line }); } } class Parent extends Component { static template = xml` <div t-on-add-to-order="addToOrder"> <OrderLine t-foreach="orders" t-as="line" line="line" /> </div>`; static components = { OrderLine }; orders = useState([ { id: 1, name: "Coffee", quantity: 0 }, { id: 2, name: "Tea", quantity: 0 }, ]); addToOrder(event) { const line = event.detail.line; line.quantity++; } } |
本例中,OrderLine
组件触发了一个add-to-order
事件。这会生成一个与DOM树一起冒泡的DOM事件。然后由父组件拦截,接着(从detail
键)获取该行并增加其数量。参见事件处理一页获取事件运行的更多详情。
注意在OrderLine
组件直接修改line
对象时也会有效。但这不是一种好的做法:它有效是因为从子组件所接收到的props
是响应式的,因此子组件会与父组件的实现之间进行配对。