OWL模板的指令解析

.bind指令

父组件将回调函数作为prop传递到子组件是一种很常见的操作。由于OWL组件是类组件,回调函数在运行时通常需要绑定父组件的运行环境,使用.bind指令可以方便的实现该操作。

  • 类组件:类组件内部有this保存组件的状态,回调函数如果不绑定父组件的this,会通过子组件的this调用回调函数
  • 函数式组件:基于函数式编程的思想,组件在两次外部输入相同的情况下,必定有一致的输出效果。函数式组件内部没有this指向模糊性的问题。OWL不支持函数式组件。React框架主推函数式组件。

不使用.bind指令的写法,回调函数绑定父组件this后,再进行传递

js 复制代码
class SomeComponent extends Component {
  static template = xml`
    <div>
      <Child callback="doSomething"/>
    </div>`;

  setup() {
    this.doSomething = this.doSomething.bind(this);
  }

  doSomething() {
    // ...
  }
}

使用OWL提供的.bind指令,就可以直接在模板中完成绑定,简化了代码

js 复制代码
class SomeComponent extends Component {
  static template = xml`
    <div>
      <Child callback.bind="doSomething"/>
    </div>`;

  doSomething() {
    // ...
  }
}

t-slot指令

OWL可以定义一些通用组件,这些通用组件可以减少组件的重复定义,例如导航栏是一个通用组件,开发人员只需要根据需要向导航栏插入特定内容即可,而不需要定义一个完整的导航栏组件。在通用组件中使用t-slot指令设置内容插入位置,使用t-set-slot向通用组件中插入特定内容。

t-set-slot指令的参数

有些情况下使用t-set-slot向通用组件插入内容时,需要附加一些额外的信息,可以通过下列方式实现:

xml 复制代码
<div class="info-box" t-name="InfoBox">
  <div class="info-box-title">
    <t t-slot="title"/>
    <span class="info-box-close-button" t-on-click="close">X</span>
  </div>
</div>

<!-- 使用通用组件,插入特定内容,同时传递额外信息 -->
<InfoBox>
  <t t-set-slot="title" subtitle="subtitle">
    Specific Title. It could be html also.
  </t>
</InfoBox>

在通用组件中使用this.props.slots['title'].subtitle就可以获取传递的参数。slot参数与props的使用方式类似,可以使用.bind指令对回调函数进行绑定。

t-slot-scope指令

插入内容需要依靠通用组件内部的信息来完成渲染,此时可以使用t-slot-scope定义一个变量,来访问通用组件内部的信息。比如下面的例子,对话框是一个通用组件,用户可以在对话框的底部插入特定内容,但是底部关闭按钮的功能依赖于对话框内部的实现

xml 复制代码
<t t-name="web.Dialog" owl="1">
    <footer t-if="props.footer">
        <!-- 定义close -->
        <t t-slot="footer" close="data.close">
            <button class="btn btn-primary o-default-button" t-on-click="data.close">
                <t>Ok</t>
            </button>
        </t>
    </footer>
</t>

<Dialog>
   ...
    <t t-set-slot="footer" t-slot-scope="dialog">
            <!-- 使用变量dialog访问close -->
        <button class="btn btn-secondary" t-on-click="dialog.close">
            Discard
        </button>
    </t>
</Dialog>

当向默认插槽插入内容时,可以不使用t-set-slot指令,此时如果需要使用t-slot-scope指令,可以这样:

xml 复制代码
    <Transition visible="state.show" name="'o-fade'" t-slot-scope="transition" >
        <span class="o_loading_indicator" t-att-class="transition.className">
            Loading 
        </span>
    </Transition>

插入内容的渲染context

xml 复制代码
<Parent>
    <Child>
        <t t-set-slot="title">xxx</t>
    </Child>
</Parent>

插入内容的渲染context来自Parent组件

相关推荐
苍何6 小时前
让 WorkBuddy 操控浏览器,干活有点猛啊1
后端
IT_陈寒6 小时前
当Java的hashCode遇上Lombok,我的缓存被全清了
前端·人工智能·后端
XW6 小时前
常用提示词(Prompt)框架总结
后端
ServBay6 小时前
DeepSeek 再次崩了,DeepSeek V5正在路上?
后端·deepseek
IT规划师7 小时前
编程术语中的同步与异步:从"等不等"到工程取舍
后端·面试
孟陬8 小时前
Foobar 技术周刊#159:当看不懂代码时,如何高效排障调试。脏页陷阱:一条只读查询,写入数 TB 数据。推测解码:大模型加速利器
前端·人工智能·后端
GoGeekBaird8 小时前
别再给每个 AI 做自我介绍了:我做了一个「个人上下文」管理系统
后端·github·agent
码事漫谈8 小时前
腾讯混元 Hy4 正式版发布了
后端
Mikko78 小时前
Redis 连接数满了服务端有错误信息吗?连接数不增加却命令超时?6.2 实测连接池、超时与大 key 怎么判定
java·spring boot·redis·后端
苍何10 小时前
DeepSeek的Super-agent 设计,和我们的工程实践
后端