odoo14--odoo前端框架owl【odoo web library】
原文链接:https://www.alanhou.org/odoo-14-owl-todolist/
1、组件树
Root
const { Component, useState } = owl;
const { xml } = owl.tags;
class Counter extends Component {
static template = xml`
<button t-on-click="state.value++">
Click Me! [<t t-esc="state.value"/>]
</button>`;
state = useState({ value: 0 });
}
class App extends Component {
static template = xml`
<div>
<span>Hello Owl</span>
<Counter />
</div>`;
static components = { Counter };
}
const app = new App();
app.mount(document.body);
owl_todoapp
(function () {
const {Component, Store} = owl; //
const {xml} = owl.tags; //用来插入xml代码片段的
const {whenReady} = owl.utils; //工具类
const {useRef, useDispatch, useState, useStore} = owl.hooks; //钩子
// -------------------------------------------------------------------------
// Store
// -------------------------------------------------------------------------
const actions = {
addTask({state}, title) {
title = title.trim();
if (title) {
const task = {
id: state.nextId++,
title: title,
isCompleted: false,
};
state.tasks.push(task);
}
},
toggleTask({state}, id) {
const task = state.tasks.find((t) => t.id === id);
task.isCompleted = !task.isCompleted;
},
deleteTask({state}, id) {
const index = state.tasks.findIndex((t) => t.id === id);
state.tasks.splice(index, 1);
},
};
const initialState = {
nextId: 1,
tasks: [],
};
// -------------------------------------------------------------------------
// Task Component 可点击任务标题来切换复选框状态:
// -------------------------------------------------------------------------
const TASK_TEMPLATE = xml/* xml */`
<div class="task" t-att-class="props.task.isCompleted ? 'done' : ''">
<input type="checkbox" t-att-checked="props.task.isCompleted"
t-att-id="props.task.id"
t-on-click="dispatch('toggleTask', props.task.id)"/>
<label t-att-for="props.task.id"><t t-esc="props.task.title"/></label>
<span class="delete" t-on-click="dispatch('deleteTask', props.task.id)"></span>
</div>`; class Task extends Component {
static template = TASK_TEMPLATE;
static props = ["task"];
dispatch = useDispatch();
} // -------------------------------------------------------------------------
// App Component
// -------------------------------------------------------------------------
const APP_TEMPLATE = xml/* xml */`
<div class="todo-app">
<input placeholder="Enter a new task" t-on-keyup="addTask" t-ref="add-input"/>
<div class="task-list">
<Task t-foreach="displayedTasks" t-as="task" t-key="task.id" task="task"/>
</div>
<div class="task-panel" t-if="tasks.length">
<div class="task-counter">
<t t-esc="displayedTasks.length"/>
<t t-if="displayedTasks.length lt tasks.length">
/ <t t-esc="tasks.length"/>
</t>
task(s)
</div>
<div>
<span t-foreach="['all', 'active', 'completed']"
t-as="f" t-key="f"
t-att-class="{active: filter.value===f}"
t-on-click="setFilter(f)"
t-esc="f"/>
</div>
</div>
</div>`; class App extends Component {
static template = APP_TEMPLATE;
static components = {Task}; inputRef = useRef("add-input");
tasks = useStore((state) => state.tasks);
filter = useState({value: "all"});
dispatch = useDispatch(); mounted() {
this.inputRef.el.focus();
} addTask(ev) {
// 13 is keycode for ENTER
if (ev.keyCode === 13) {
this.dispatch("addTask", ev.target.value);
ev.target.value = "";
}
} get displayedTasks() {
switch (this.filter.value) {
case "active":
return this.tasks.filter((t) => !t.isCompleted);
case "completed":
return this.tasks.filter((t) => t.isCompleted);
case "all":
return this.tasks;
}
} setFilter(filter) {
this.filter.value = filter;
}
} // -------------------------------------------------------------------------
// Setup code
// -------------------------------------------------------------------------
function makeStore() {
const localState = window.localStorage.getItem("todoapp");
const state = localState ? JSON.parse(localState) : initialState;
const store = new Store({state, actions});
store.on("update", null, () => {
localStorage.setItem("todoapp", JSON.stringify(store.state));
});
return store;
} function setup() {
owl.config.mode = "dev";
App.env.store = makeStore();
const app = new App();
app.mount(document.body);
} whenReady(setup);
})();
.todo-app {
width: 300px;
margin: 50px auto;
background: aliceblue;
padding: 10px;
}
.todo-app > input {
display: block;
margin: auto;
}
.task-list {
margin-top: 8px;
}
.task {
font-size: 18px;
color: #111111;
display: grid;
grid-template-columns: 30px auto 30px;
}
//在用户鼠标悬浮到任务上方时添加视觉反馈:
.task:hover {
background-color: #def0ff;
}
.task > input {
margin: auto;
}
.delete {
opacity: 0;
cursor: pointer;
text-align: center;
}
.task:hover .delete {
opacity: 1;
}
.task.done {
opacity: 0.7;
}
//对已完成任务的标题添加中划线
.task.done label {
text-decoration: line-through;
}
.task-panel {
color: #0088ff;
margin-top: 8px;
font-size: 14px;
display: flex;
}
.task-panel .task-counter {
flex-grow: 1;
}
.task-panel span {
padding: 5px;
cursor: pointer;
}
.task-panel span.active {
font-weight: bold;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>OWL Todo App</title>
<link rel="stylesheet" href="app.css" />
<script src="owl.js"></script>
<script src="app.js"></script>
</head>
<body></body>
</html>
owl.js 在 https://github.com/odoo/owl
odoo14--odoo前端框架owl【odoo web library】的更多相关文章
- 前端框架对于未来web移动端的影响
现在前端框架市场比较乱,各种各样的框架参差不齐,这给我带来了很多困惑,同样是很多朋友的困惑吧!因为前端框架有很多种,对于程序员来说选择学习是非常困难的,不可能有几十上百种都要学习吧,不过最好的办法就是 ...
- 前端框架framework和库library的一点区别和记录
本篇纯文字,无关代码,只是一点概念的记录 关于所谓前端 首先学的是HTML5.CSS3.JavaScript这三个 之后接触了一下UI框架,如layui和bootstrap 目前是打算去学VUE和an ...
- Web前端框架汇总
在做web开发的时候难免遇到一个问题,那就是,选择什么样的框架.下面把前端的框架简单的列一下. 1.flex Apache基金会今天发布了Flex 4.8版本,这是Adobe将Flex捐献给Apach ...
- 国内5款优秀的WEB前端框架
1. JX(腾讯) 官网地址:http://alloyteam.github.io/JX/#home JX 是一个类似 Google Closure Library 的 Web 前端开发框架,服务于 ...
- Web前端,HTML5开发,前端资源,前端网址,前端博客,前端框架整理 - 转改
Web前端/H5开发,前端资源,前端网址,前端博客,前端框架整理 综合类 前端知识体系 前端知识结构 Web前端开发大系概览 Web前端开发大系概览-中文版 Web Front-end Stack v ...
- python开发学习-day15(前端部分知识、web框架、Django创建项目)
s12-20160430-day15 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...
- odoo前端
bootstrap: http://www.runoob.com/bootstrap/bootstrap-tutorial.html javascript: http://www.runoob.com ...
- Web前端框架与类库的思考
说起前端框架,我也是醉了.现在去面试或者和同行聊天,动不动就这个框架碉堡了,那个框架好犀利. 当然不是贬低框架,只是有一种杀鸡焉用牛刀的感觉.网站技术是为业务而存在的,除此毫无意义,框架也是一样.在技 ...
- React 还是 Vue: 你应该选择哪一个Web前端框架?
学还是要学的,用的多了,也就有更多的认识了,开发中遇到选择的时候也就简单起来了. 本文作者也做了总结: 如果你喜欢用(或希望能够用)模板搭建应用,请使用Vue 如果你喜欢简单和“能用就行”的东西 ...
随机推荐
- jQuery基础-选择器,样式操作
入口函数:ready() 当 DOM(文档对象模型) 已经加载,并且页面(包括图像)已经完全呈现时,会发生 ready 事件. 由于该事件在文档就绪后发生,因此把所有其他的 jQuery 事件和函数置 ...
- Mysql 面试题(一网打尽,收藏版)
文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...
- JAVA微服务应用(1)--SpringBoot中的REST API调用(学习笔记)
好长时间没有写学习小结了,最近宁正好看了小马哥的微服务系列之<Spring Boot>系列,颇有收获,并且公司也布置一个课题就是关于Spring中的REST API调用.于是乎回归本行,再 ...
- ES7扩展
前一段时间小编一直在更新javascript es6版本的部分新语法和新特性,鉴于现在js一直在更新,接下来小编将和大家一起进步,一块探究js的新特性.今天小编就和大家一起来看看es7更新的语法和新特 ...
- JavaScript的核心语法
1.JavaScript同其他程序设计语言一样,有着独特的语法结构,主要包含:变量.数据类型.运算符号.控制语句和注释等. 2.变量是存储数据的基本单位,JavaScript通常利用变量来参与j各种运 ...
- gRPC入门—golang实现
1.RPC 1.1 什么是RPC RPC(Remote Procedure Call),即远程过程调用,过程就是方法,简单来说,它就是一种能够像调用本地方法一样调用远程计算机进程中的方法的技术,在这种 ...
- 如何优雅的实现Mysql 增删改查,看完你就会了
接着上期说,上期没写一条sql就把数据查询出来了,那如果要保存或者更新数据怎么办呢?能不能自己写sql呢? 保存数据 @GetMapping("save")//保存数据 publi ...
- Golang修改操作系统时间
Golang修改操作系统时间 需求 程序有时需要和服务器对时,发现延迟过高修改本地时间,这段代码网上抄的,实测可用,windows环境需要以管理员身份启动命令提示符调试 实现Demo package ...
- spring boot @Async异步注解上下文透传
上一篇文章说到,之前使用了@Async注解,子线程无法获取到上下文信息,导致流量无法打到灰度,然后改成 线程池的方式,每次调用异步调用的时候都手动透传 上下文(硬编码)解决了问题. 后面查阅了资料,找 ...
- eclipse语言怎么设置为中文
2021-05-30 方法:1.查找语言包下载网址,并复制:2.打开eclipse,点击"help"-"Install New Software"-" ...