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

相关推荐
Piper蛋窝5 小时前
深入 Go 语言垃圾回收:从原理到内建类型 Slice、Map 的陷阱以及为何需要 strings.Builder
后端·go
六毛的毛8 小时前
Springboot开发常见注解一览
java·spring boot·后端
AntBlack8 小时前
拖了五个月 ,不当韭菜体验版算是正式发布了
前端·后端·python
31535669138 小时前
一个简单的脚本,让pdf开启夜间模式
前端·后端
uzong8 小时前
curl案例讲解
后端
一只叫煤球的猫9 小时前
真实事故复盘:Redis分布式锁居然失效了?公司十年老程序员踩的坑
java·redis·后端
大鸡腿同学10 小时前
身弱武修法:玄之又玄,奇妙之门
后端
轻语呢喃12 小时前
JavaScript :字符串模板——优雅编程的基石
前端·javascript·后端
MikeWe12 小时前
Paddle张量操作全解析:从基础创建到高级应用
后端
岫珩12 小时前
Ubuntu系统关闭防火墙的正确方式
后端