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组件

相关推荐
XUN4J11 分钟前
深入解析MySQL事务与锁:构建高并发数据系统的基石
后端·面试
徐行code16 分钟前
C++核心机制-复制消除
后端
开心猴爷32 分钟前
在 CICD 中实践 Fastlane + Appuploader 命令行,构建可复制的 iOS 自动化发布流程
后端
一 乐44 分钟前
高校评教|基于SpringBoot+vue高校学生评教系统 (源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习
疯狂的程序猴1 小时前
Web 抓包完整实践指南,从浏览器网络调试到底层数据流捕获的全流程方案
后端
喵手1 小时前
我使用openEuler构建出了一个自愈式系统监控平台
后端
调试人生的显微镜1 小时前
以 uni-app 为核心的 iOS 上架流程实践, 从构建到最终提交的完整路径
后端
喵手1 小时前
我在openEuler上从零开始构建云原生AI应用
后端
解读玫瑰2 小时前
WSL+openEuler嵌入式开发实战:交叉编译与QEMU仿真全流程
后端
Stream2 小时前
加密与签名技术之数字签名算法
后端