Package Exports
- vir.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (vir.js) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
此处为vir.js的新版本(1.0.*)
这次我将核心的功能抽离出来了, 核心的内容比旧版的少了许多, 也更灵活了.
旧版的可以看看这里: https://github.com/Eoyo/express/tree/master/public/Vir
vir.js 的核心: js Dom 树的解析
一. 用法
1. 安装:
npm install vir.js
使用typescript编写的, 自带类型声明的
2. 导入 (typescript/ ES6)
import { Vir } from 'vir.js'
注意啦: 要使用{} , 我是export { Vir } 导出的
3. 其他使用: 例如
- 浏览器导入(不推荐的了, 未来的目标要在node.js上跑的...),
- node.js 的 require, 也可以(可我还是喜欢ES6的模块语法)
const Vir = require('vir.js').Vir
二. 简单的使用例子:
1. 显示四个盒子(className = "box"
), 每个盒子一个big apple:
写法1:
Vir({
'4* .box': {
'.apple': 'Big Apple'
}
})
写法2: 使用vir.js'原生的'数组自适应, 让你可以控制单个的内容
Vir({
'.box' : [
{ '.apple': 'Big Apple' },
{ '.apple': 'Big Apple' },
{ '.apple': 'Big Apple' },
{ '.apple': 'Big Apple' }
]
})
写法3: 搭配ramda 等类似的库, 让你有望使用函数式开发.
import R = require('ramda')
Vir({
'.box' : R.map(
(e)=>({ '.apple': e }),
R.repeat(4, 'Big Apple')
)
})
2. 模块开发, 一个模块说我是'model one', 另一个说我是: 'model two'
核心是利用 函数节点
// use typescript
// modelOne
import { Vir } from 'vir.js';
import * as $ from 'jquery';
function One (ele : HTMLElement) {
const sayWords = 'I\'am model one'
Vir(ele, {
'.say': sayWords
, on: { // 绑定个事件也可以
click() {
alert(sayWords)
}
}
})
}
//model two
function Two (ele : HTMLElement) {
const sayWords = 'I\'am model two'
Vir(ele, {
'.say': sayWords
})
// 想用jquery就用, 自由如此
$(ele).on('click',()=> {
alert(sayWords)
})
}
// usage 1:
Vir({
'.model': One
, '2; .model': Two
})
// usage 1 等价于如下: usage 2
Vir({
'.model': [
One, Two
]
})
// 说白了就是有个函数节点, 看看如下, 详细见语法篇
Vir({
'.model'(ele) {
ele.innerHTML = 'abc'
}
})
三. vir.js 的优势
- 定位清晰: 就是用js创建dom的.
- 无其他依赖: 目前发布的vir.js 才800来行, 源码都可以一口气看完..
- 有潜力: 这是一个极简先驱版本, 我还开发了许多vir.js的工具, vir.js不久将会上升到framework的高度
- 完全用js 开发的: 实现在前后端同时跑也是可以的;
- 使用方便: 有强大的数组使用方法;
四. vir.js 的语法
1.基本的 id 与class 解析 : "#id .class .classtwo"
#
后紧跟id名, .
后跟class名,class是按顺序的,可以多个;id 与和class 不分顺序,class之间有顺序的;
标签名默认为div;
2.属性解析:[key = 'value']
和html 中写属性值一样;
3.子元素解析:".parent > .son"
在js中:
".parent > .son":{
$:"son"
///绑定在最后生成的元素上;即为.son上;
}
创建的是:
<div class = "parent">
<div class = "son">son</div>
</div>
4.多个元素 : "3* div"
数字和*黏在一起;不可以!!!!:"3 *div"
。
但是可以:"3*div"
。最好是放在开头,其他地方也可以,但容易出错;
5.定义变量 : "div ::oneDiv"
创建的div存在oneDiv里。可以多次出现::oneDiv在不同的标签属性里,结果是oneDiv变成了数组,按创建次序记录各个element;还可以与point 4中的乘法搭用,生成数组(不是“反常坑”的HTMLcollection)。
6.混搭 :"div ::parentDiv > 3*div ::threeChild"
js代码:
var test = Vir({
"div ::parentDiv > 3*div ::threeChild":{
$:"son"
///绑定在最后生成的元素上;即为.son上;
}
})
生成html如下:
<div>
<div>son</div>
<div>son</div>
<div>son</div>
</div>
使用变量threeChild;
// 使用变量threeChild;
test.args.threeChild.forEach((v)=>{
v.innerHTML = "use";
})
改动效果如下html:
<div>
<div>use</div>
<div>use</div>
<div>use</div>
</div>
7. 特殊的属性: $, on, style, args, data
其实上面有许多的例子使用了特殊的属性了, 特殊属性主要是为了方便操作dom的. 其他的都很简单的, 就$牛逼点: $ 是innerHTML, 但也可以是数组.
- on 绑定事件的地方. on为函数时自定义把绑定,
'div .test':{ on(ele){ /* do what you want */ } }
, ele 为HTMLELement; - style 绑定样式的地方
- args 绑定生成的HTMLELement的属性如className, 或自定义: 如key; (index 被Vir.js用了!)
- data 绑定到dataSet上, 原生dom的安全数据接口, 优点是css里可以访问到(绝对黑科技!),
- $ 显式的绑定innerHTML 或者使用数组, 就这两种情况
8. 分述、复述和自适应数组
数组的自动解析是本框架的一大特色, 很多框架都是要用类似于for于语句去声明. 但是我这里不需要的. 为了使用时使得结果符合预期, 请大家注意一下几点:
8.1 数组中合法的类型:
Vir({
'.array > .item' : [
'string'
, true
, 123 //primitive转字符串显示
, { // object 当做新的vir节点解析
'#obj' : 'object'
}
, (ele) => { // 调用函数处理, 唯一入口是框架生成的HTMLElememt
ele.innerHTML = 'function'
}
, null // 结果不显示
, undefined // 显示出undefined
]
})
注意:
- 不支持Symbol类型用在数组里
- null 和 undefined: null不显示, undefined会被渲染成字符串'undefined';
- 尾部的
.item
没有声明数量和声明的数量为1, 则.item
的数量为其后数组的长度. 若是声明的数量大于1, 则溢出的会忽略, 不足的为'undefined'
8.2 分述、复述
js代码为:
// 分述
Vir({
".parent > 3* .son":["son1","son2","son3"]
})
// 复述
Vir({
".parent > 3* .son": "son"
})
分述在节点值为数组时触发;否则为复述
生成html为:
<!-- 分述 -->
<div>
<div title = "son">son1</div>
<div title = "son">son2</div>
<div title = "son">son3</div>
</div>
<!-- 复述 -->
<div>
<div title = "son">son</div>
<div title = "son">son</div>
<div title = "son">son</div>
</div>
ps: 复述, 我觉的就生成个棋盘啥的有用了...
8.3 在特殊的属性$中使用数组
其实和直接写在节点尾部是一样的, 只是使用$写, 可以写额外的style, on 等等
实现点击blue弹出blue, 点击red弹出red
Vir ({
'span .color': {
$: ['red', 'blue']
, on: {
click() {
alert(this.innerHTML)
}
}
}
})