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

相关推荐
大侠归来2 小时前
Spring Boot 2.1 → 3.5 迁移推演:从实战出发的完整路线图
java·spring boot·后端
海马2 小时前
Spring Boot 开发知识整理
java·spring boot·后端
谢亮_vipxieliang2 小时前
Spring Boot 3.x 从零开始——环境搭建与第一个 REST 项目
java·spring boot·后端
念何架构之路2 小时前
go-grpc核心抽象接口
开发语言·后端·golang
FYKJ_20102 小时前
django个性化新闻推荐35173-计算机课程设计、毕业设计
java·spring boot·后端·python·架构·django·课程设计
夜之眷属3 小时前
服务启动即崩:InetAddress.getLocalHost() 抛 UnknownHostException 排查记
java·运维·后端·docker
金銀銅鐵3 小时前
[Java] 用GUI展示class文件顶层的 access_flags
后端·python·ai编程
IT_陈寒4 小时前
Vue的数组更新把我坑惨了
前端·人工智能·后端
高晶4 小时前
Android 智能语音开发新手入门实战
后端·程序员