parent
fc585abcdf
commit
dde82e9860
|
@ -1,12 +1,9 @@
|
||||||
*.min.js
|
*.min.js
|
||||||
.httpserver
|
.httpserver
|
||||||
index.html
|
|
||||||
test.js
|
|
||||||
.vscode
|
.vscode
|
||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
dist/
|
||||||
*.sublime-project
|
|
||||||
*.sublime-workspace
|
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
test/
|
|
@ -1,5 +1,5 @@
|
||||||
## Wkit
|
## Wkit
|
||||||
> A library for building fast, lightweight web components.
|
> 一个简单易用、功能完善的用于开发`web components`的轻量级开发库。模板解析基于`lit-html`二次开发
|
||||||
|
|
||||||
![downloads](https://img.shields.io/npm/dt/wkit.svg)
|
![downloads](https://img.shields.io/npm/dt/wkit.svg)
|
||||||
![version](https://img.shields.io/npm/v/wkit.svg)
|
![version](https://img.shields.io/npm/v/wkit.svg)
|
||||||
|
@ -15,6 +15,7 @@
|
||||||
- `:xxx=yyy`, 属性绑定, 类似`vue`,在属性前加上`:`, 该属性不再使用`setAttribute()`, 而是直接赋值, 可满足你需要传递复杂数据结构的需求。
|
- `:xxx=yyy`, 属性绑定, 类似`vue`,在属性前加上`:`, 该属性不再使用`setAttribute()`, 而是直接赋值, 可满足你需要传递复杂数据结构的需求。
|
||||||
- `#animation={type}`, 开箱即用的动画配置, 内置6种动画`fade(默认), scale, bounce, micro-bounce, rotate, slide`
|
- `#animation={type}`, 开箱即用的动画配置, 内置6种动画`fade(默认), scale, bounce, micro-bounce, rotate, slide`
|
||||||
- `ref=xxx`, 类似`vue`的节点标识, 可方便的在`mounted()`之后通过 `this.$refs.xxx` 来访问该节点
|
- `ref=xxx`, 类似`vue`的节点标识, 可方便的在`mounted()`之后通过 `this.$refs.xxx` 来访问该节点
|
||||||
|
- 内置特色的双向绑定方法`live()`
|
||||||
- 用内置的`bind()`方法来给当前组件绑定事件时, 组件移除时事件也会自动销毁,无需手动销毁。
|
- 用内置的`bind()`方法来给当前组件绑定事件时, 组件移除时事件也会自动销毁,无需手动销毁。
|
||||||
- 灵活的`props`定义
|
- 灵活的`props`定义
|
||||||
|
|
||||||
|
@ -84,3 +85,7 @@ Hello.reg('hello')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 开源协议
|
||||||
|
|
||||||
|
- BSD 3-Clause License (Lit框架的html模板解析的源码)
|
||||||
|
- MIT (除Lit代码之外的所有代码)
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "wkit",
|
"name": "wkit",
|
||||||
"version": "1.11.6",
|
"version": "1.12.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "A library for building fast, lightweight web components.",
|
"description": "A library for building fast, lightweight web components.",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
|
|
@ -529,6 +529,10 @@ class AttributePart {
|
||||||
let strings = this.strings
|
let strings = this.strings
|
||||||
let changed = false
|
let changed = false
|
||||||
|
|
||||||
|
if (typeof value === 'function') {
|
||||||
|
value = value(this.element)
|
||||||
|
}
|
||||||
|
|
||||||
if (strings === void 0) {
|
if (strings === void 0) {
|
||||||
changed = !isPrimitive(value) || value !== this.#value
|
changed = !isPrimitive(value) || value !== this.#value
|
||||||
if (changed) {
|
if (changed) {
|
||||||
|
|
21
src/index.js
21
src/index.js
|
@ -74,6 +74,27 @@ export function which(target, list = [], defaultCase = '') {
|
||||||
return defaultCase
|
return defaultCase
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 双向绑定
|
||||||
|
* @param key<String> 绑定的字段
|
||||||
|
* @param el 当前对象, 无需传递, 由框架内部处理
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export function live(key, el) {
|
||||||
|
let callback = ev => {
|
||||||
|
Function('o', 'v', `o.${key} = v`)(this, ev.target.value)
|
||||||
|
this.$requestUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (el && !el.__live__) {
|
||||||
|
bind(el, 'input', callback)
|
||||||
|
this.$events.input ??= []
|
||||||
|
this.$events.input.push({ el, listener: callback, options: false })
|
||||||
|
el.__live__ = true
|
||||||
|
}
|
||||||
|
return Function('o', `return o.${key}`)(this)
|
||||||
|
}
|
||||||
|
|
||||||
export class Component extends HTMLElement {
|
export class Component extends HTMLElement {
|
||||||
/**
|
/**
|
||||||
* 声明可监听变化的属性列表
|
* 声明可监听变化的属性列表
|
||||||
|
|
22
src/utils.js
22
src/utils.js
|
@ -108,7 +108,7 @@ export function offset(node) {
|
||||||
/**
|
/**
|
||||||
* 事件绑定
|
* 事件绑定
|
||||||
*/
|
*/
|
||||||
export function bind(dom, type = '', selector, fn, phase = true) {
|
export function bind(dom, type = '', selector, fn, phase = false) {
|
||||||
let events = type.split(',')
|
let events = type.split(',')
|
||||||
let callback
|
let callback
|
||||||
let isWc = dom && dom.host === dom
|
let isWc = dom && dom.host === dom
|
||||||
|
@ -121,7 +121,7 @@ export function bind(dom, type = '', selector, fn, phase = true) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof selector === 'function') {
|
if (typeof selector === 'function') {
|
||||||
phase = fn
|
phase = fn || false
|
||||||
fn = selector
|
fn = selector
|
||||||
selector = null
|
selector = null
|
||||||
} else {
|
} else {
|
||||||
|
@ -168,11 +168,21 @@ export function bind(dom, type = '', selector, fn, phase = true) {
|
||||||
events.forEach(function (t) {
|
events.forEach(function (t) {
|
||||||
t = t.trim()
|
t = t.trim()
|
||||||
if (isWc) {
|
if (isWc) {
|
||||||
if (host.$events[t]) {
|
host.$events[t] ??= []
|
||||||
host.$events[t].push({ el: dom, listener: callback, options: phase })
|
|
||||||
} else {
|
let _list = host.$events[t]
|
||||||
host.$events[t] = [{ el: dom, listener: callback, options: phase }]
|
if (_list.length) {
|
||||||
|
let idx = _list.findIndex(
|
||||||
|
it =>
|
||||||
|
it.el === dom && it.listener === callback && it.options === phase
|
||||||
|
)
|
||||||
|
if (idx > -1) {
|
||||||
|
let item = _list[idx]
|
||||||
|
_list.splice(idx, 1)
|
||||||
|
dom.removeEventListener(t, item.listener, item.options)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
_list.push({ el: dom, listener: callback, options: phase })
|
||||||
}
|
}
|
||||||
dom.addEventListener(t, callback, phase)
|
dom.addEventListener(t, callback, phase)
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
|
||||||
|
<title>wkit test page</title>
|
||||||
|
<style>
|
||||||
|
body {line-height: 1.5;font-size:14px;background:var(--page-color);color:var(--text-color);}
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
border-radius: 10px;
|
||||||
|
background: var(--summary-bg-color);
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 3px;
|
||||||
|
background: var(--border-color-dark);
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--summary-color);
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 480px) {
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script type="importmap">
|
||||||
|
{
|
||||||
|
"imports":{
|
||||||
|
"es.shim":"//jscdn.ink/es.shim/latest/index.js",
|
||||||
|
"wkit":"//127.0.0.1:9999/src/index.js",
|
||||||
|
"wkitd":"//jscdn.ink/wkitd/1.3.10/index.js",
|
||||||
|
"fetch":"//jscdn.ink/@bytedo/fetch/latest/next.js",
|
||||||
|
"@bd/ui/":"//jscdn.ink/@bd/ui/0.1.16/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module" src="./test.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<wc-app></wc-app>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { html, Component, live } from 'wkit'
|
||||||
|
|
||||||
|
class App extends Component {
|
||||||
|
foo = ''
|
||||||
|
|
||||||
|
bar = { a: 333 }
|
||||||
|
|
||||||
|
created() {
|
||||||
|
// live = live.bind(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
this.foo = ''
|
||||||
|
this.bar.a = '666'
|
||||||
|
this.$requestUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<p>${this.foo}</p>
|
||||||
|
<p>${this.bar.a}</p>
|
||||||
|
<input value=${live.bind(this, 'bar.a')} />
|
||||||
|
<input value=${this.foo} />
|
||||||
|
<input value=${live.bind(this, 'foo')} />
|
||||||
|
|
||||||
|
<button @click=${this.reset}>666</button>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
App.reg('app')
|
Loading…
Reference in New Issue