扫码阅读
手机扫码阅读

手把手带你学会Odoo OWL组件开发(4):OWL组件

102 2024-03-14

本期摘要

上一章中我们讲解了OwL的核心内容部分,即挂载,数据状态,数据监听,生命周期,组件传值及hook方法:

手把手带你学会Odoo OWL组件开发(3):核心内容指南

我们在前文了解OWL的生命周期,事件hook,等就是为了能够开发组件,组件和组件之间又是如何展示传值的呢,我们在这章会了解到相关的知识

作者

沈童 | 前端开发工程师

默默无闻,走向人生巅峰,激流勇进,退居幕后黑手

01

API

// template (string)

组件所关联的xml部分,t-name=“xxx”的值,或者jsx写法,在owl的js中书写


示例:


class OwlConfirm extends Component{ static template= "owl_confirm";
    static template = static template = xml`
            
class="bg-info text-center p-2"> <b t-esc="start.title"> b> "data.Name">t> class="fa fa-close p-1 float-right" style="cursor: pointer;" t-on-click="onRemove"> i> </div>` }


// components (Object,optional)


object:组件下有哪些子组件 optional:自定义属性


示例:


                        class OwlConfirm extends Component{ static template= "owl_confirm"; static components = { OwlRadios };
}


// Props(Object,optional)


组件传值,的参数,拥有一个对象,和是否校验这个传值类型是否正确


type: 类型
element: 设定Object中每一项的类型

optional: 是否校验 blooer


示例:


                      class ComponentA extends owl.Component { static props = ['id', 'url'];
 
    ...
} class ComponentB extends owl.Component { static props = {
    count: {type: Number},
    messages: { type: Array,
      element: {type: Object, shape: {id: Boolean, text: String }
    },
   date: Date,
   combinedVal: [Number, Boolean],
   optionalProp: { type: Number, optional: true }
  };
 
  ...
}



02

Owl组件传值


// Prop


父组件传值给子组件

                    class Child extends Component { static template = xml`
"props.a"/>"props.b"/>
`; } class Parent extends Component { static template = xml`
"state.a" b="'string'"/>
`; static components = { Child };   state = useState({ a: "fromparent" }); }


// EventBus


事件传值 owl的eventBus主要用法:


  • on 传值 (eventType, owner, callback) 事件名,传值内容,回调


  • off 销毁事件传值


      const { EventBus } = owl.core; const bus = new EventBus(); //传值 let model = {
a:1,b:'string' }
bus.on("event",model,()=>console.log('传值')); //取值 const b = bus.subscriptions['event'][0].owner; console.log(b);
bus.off("event")//销毁


// 子传父


想要获取子组件数据,就可以通过下列方式


    this.__owl__.parent.getChildrenMsg(this.data.msg),



03

Owl插槽t-slot


子组件内部内容由父组件提供,就是插槽


//匿名插槽


匿名插槽,就是一般默认插槽方式,在子组件中只有一个插槽时使用较多,默认值是 t-slot=“default ”, 这个时候在父组件中的子组件写入的标签,和内容等都会直接插入到子组件中展示


//具名插槽


具名插槽,顾名思义,就是,子组件的内如插槽,是有名字的,只有渲染对应名字的插槽内容。如下的t-slot=“header”和t-slot=“foot”都是具名插槽, 在父组件中,设置插槽名有两种


  • t-set-slot=“header” 一种是设置


  • slots=“foot” 一种是直接选定


XML部分


子组件
     <div calss="owl-radios"> 
         
         
         
     div> 
 
 
父组件
    <div> <div class="owl-popup-mask">div> <div class="owl-confirm-xl" id="owlConfirm"> <div class="owl-confirm-title"> 上面的子组件 <OwlRadios > <p>sssssp> <div slots="foot" url="sss"> <h2>车船税h2> div> <div t-set-slot="header"> <h2>22222sssh2> div> OwlRadios> div> <div class="owl-confirm-btn"> <div t-on-click="confimrBtn" class="btn btn-primary">确定div> <div t-on-click="closeConfim" class="btn btn-white ml20">取消div> div> div> div> 

JS部分


注意:子组件的class必须在父组件之前,不然会报错


odoo.define('owl_components', function (require) {  "use strict"; const { Component, useState ,hooks} = owl; const { xml } = owl.tags; const { useRef,useSubEnv, onMounted, onWillStart} = hooks; const {ComponentWrapper} = require("web.OwlCompatibility"); class OwlRadios extends Component{ static template= "owl_radios";
 
        mounted(){ console.log(this.props)
        }
    } class OwlConfirm extends Component{ static template= "owl_confirm"; static components = { OwlRadios };
        setup() { this.state = useState({ title: "測試", row:this.__owl__.parent.parentWidget.recordData, name:'' }); this.state.title = 'xxxxxxxx内容部分' this.inputRef = useRef("someDiv"); const model = { a:1, b:'ssss' };
            useSubEnv(model);
        }
 
        someMethod() { console.log(this.inputRef)
         }
        changeVal(){ console.log(this.state.name)
        }
        confimrBtn(url){ console.log(this.state.row,'确定'); let self = this; console.log(this.env,'ssss')
 
        } //关闭 closeConfim(){ this.destroy();
        }
    } return {
        OwlConfirm,
    }
});


04

Owl 动态组件 t-component


// 组件插槽


可以动态根据条件渲染子组件。


class A extends Component { static template = xml`
child a
`; } class B extends Component { static template = xml`child b`; } class Parent extends Component { static template = xml``;     state = useState({ child: "a" });     get myComponent() { return this.state.child === "a" ? A : B;   } }



今天的内容就到这里,我们下期再见!

原文链接: http://mp.weixin.qq.com/s?__biz=Mzg5MzUyOTgwMQ==&mid=2247526710&idx=1&sn=f25dbddde2666ceb843db329016110a5&chksm=c02f5290f758db8683d8f14d348131ff769f1b925e491146f7c6f73a4580782bb5268bccf748#rd