This repository has been archived on 2023-08-30. You can view files and clone it, but cannot push or open issues/pull-requests.
bytedo
/
wcui
Archived
1
0
Fork 0

完成对组件的重构

old
宇天 2017-12-21 22:39:45 +08:00
parent ef7fa7cee7
commit b7617b01c3
7 changed files with 1327 additions and 266 deletions

View File

@ -6,6 +6,7 @@ const babel = require('babel-core')
const scss = require('node-sass')
const chokidar = require('chokidar')
const log = console.log
const chalk = require('chalk')
const sourceDir = path.resolve(__dirname, 'src')
const buildDir = path.resolve(__dirname, 'dist')
@ -28,24 +29,44 @@ const compileJs = (entry, output) => {
fs.cp(entry, output)
}, 100)
} else {
try {
const { code } = babel.transformFileSync(entry, jsOpt)
fs.echo(code, output)
} catch (err) {
return log(err)
}
log('编译JS: %s, 耗时 %d ms', entry, Date.now() - t1)
}
log(
'编译JS: %s, 耗时 %s ms',
chalk.green(entry),
chalk.yellow(Date.now() - t1)
)
}
const compileCss = (entry, output) => {
try {
let t1 = Date.now()
const { css } = scss.renderSync({ ...cssOpt, file: entry })
log('编译scss: %s, 耗时 %d ms', entry, Date.now() - t1)
log(
'编译scss: %s, 耗时 %s ms',
chalk.green(entry),
chalk.yellow(Date.now() - t1)
)
fs.echo(css, output)
} catch (err) {
log(err)
}
}
const compileHtm = (entry, output) => {
let t1 = Date.now()
let htm = fs.cat(entry).toString('utf8')
htm = htm.replace(/[\r\n\t]+/g, ' ').replace(/\s{2,}/g, ' ')
log('压缩HTML: %s, 耗时 %d ms', entry, Date.now() - t1)
log(
'压缩HTML: %s, 耗时 %s ms',
chalk.green(entry),
chalk.yellow(Date.now() - t1)
)
fs.echo(htm, output)
}
@ -102,5 +123,5 @@ chokidar
}
})
.on('ready', () => {
log('预处理完成,监听文件变化中,请勿关闭本窗口...')
log(chalk.red('预处理完成,监听文件变化中,请勿关闭本窗口...'))
})

View File

@ -5,6 +5,7 @@ const path = require('path')
const babel = require('babel-core')
const scss = require('node-sass')
const log = console.log
const chalk = require('chalk')
const sourceDir = path.resolve(__dirname, 'src')
const buildDir = path.resolve(__dirname, 'dist')
@ -27,14 +28,22 @@ const compileJs = (entry, output) => {
tmpOpt = Object.assign({}, jsOpt, { plugins: [] })
}
const { code } = babel.transformFileSync(entry, tmpOpt)
log('编译JS: %s, 耗时 %d ms', entry, Date.now() - t1)
log(
'编译JS: %s, 耗时 %s ms',
chalk.green(entry),
chalk.yellow(Date.now() - t1)
)
fs.echo(code, output)
}
const compileCss = (entry, output) => {
let t1 = Date.now()
const { css } = scss.renderSync({ ...cssOpt, file: entry })
log('编译scss: %s, 耗时 %d ms', entry, Date.now() - t1)
log(
'编译scss: %s, 耗时 %s ms',
chalk.green(entry),
chalk.yellow(Date.now() - t1)
)
fs.echo(css, output)
}
@ -42,7 +51,11 @@ const compileHtm = (entry, output) => {
let t1 = Date.now()
let htm = fs.cat(entry).toString('utf8')
htm = htm.replace(/[\r\n\t]+/g, ' ').replace(/\s{2,}/g, ' ')
log('压缩HTML: %s, 耗时 %d ms', entry, Date.now() - t1)
log(
'压缩HTML: %s, 耗时 %s ms',
chalk.green(entry),
chalk.yellow(Date.now() - t1)
)
fs.echo(htm, output)
}
@ -56,7 +69,7 @@ const cssFiles = fs.ls('./src/css/', true)
if (fs.isdir(buildDir)) {
fs.rm(buildDir, true)
log('清除旧目录 dist/')
log(chalk.cyan('清除旧目录 dist/'))
}
// 字体文件直接复制

1041
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,10 @@
"type": "git",
"url": "git+https://github.com/yutent/doui.git"
},
"keywords": ["doui", "yua"],
"keywords": [
"doui",
"yua"
],
"author": "yutent",
"license": "MIT",
"devDependencies": {
@ -19,6 +22,7 @@
"babel-plugin-transform-es2015-modules-umd": "^6.24.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-minify": "^0.2.0",
"chalk": "^2.3.0",
"chokidar": "^1.7.0",
"iofs": "^1.0.2",
"node-sass": "^4.7.2"

View File

@ -24,7 +24,11 @@
/*********************************************************************
* 全局变量及方法 *
**********************************************************************/
var bindingID = 1024
var IEVersion = 0
if (window.VBArray) {
IEVersion = document.documentMode || (window.XMLHttpRequest ? 7 : 6)
}
var expose = generateID()
//http://stackoverflow.com/questions/7290086/javascript-use-strict-and-nicks-find-global-function
var DOC = window.document
@ -83,11 +87,6 @@
'[object Generator]': 'generator',
'[object GeneratorFunction]': 'generatorfunction'
}
var bindingID = 1024
var IEVersion = 0
if (window.VBArray) {
IEVersion = document.documentMode || (window.XMLHttpRequest ? 7 : 6)
}
function noop() {}
function scpCompile(array) {
@ -190,6 +189,26 @@
return new this('string')
}
Anot.PropsTypes.isNumber = function() {
return new this('number')
}
Anot.PropsTypes.isFunction = function() {
return new this('function')
}
Anot.PropsTypes.isArray = function() {
return new this('array')
}
Anot.PropsTypes.isObject = function() {
return new this('object')
}
Anot.PropsTypes.isBoolean = function() {
return new this('boolean')
}
/*判定是否是一个朴素的javascript对象Object不是DOM对象不是BOM对象不是自定义类的实例*/
Anot.isPlainObject = function(obj) {
// 简单的 typeof obj === "object"检测会致使用isPlainObject(window)在opera下通不过
@ -3394,15 +3413,14 @@
var componentQueue = []
var widgetList = []
var componentHooks = {
$construct: function() {
return Anot.mix.apply(null, arguments)
construct: function(props, next) {
next(props)
},
$ready: noop,
$init: noop,
$dispose: noop,
$container: null,
$childReady: noop,
$$template: function(str) {
componentWillMount: noop,
componentDidMount: noop,
childComponentDidMount: noop,
componentWillUnmount: noop,
render: function(str) {
return str
}
}
@ -3416,6 +3434,7 @@
if (name === obj.name) {
componentQueue.splice(i, 1)
i--
// (obj, Anot.components[name], obj.element, obj.name)
;(function(host, hooks, elem, widget) {
//如果elem已从Document里移除,直接返回
if (!Anot.contains(DOC, elem) || elem.msResolved) {
@ -3424,74 +3443,59 @@
}
var dependencies = 1
var global = componentHooks
var globalHooks = componentHooks
//===========收集各种配置=======
if (elem.getAttribute(':attr-identifier')) {
if (elem.getAttribute(':attr-uuid')) {
//如果还没有解析完,就延迟一下 #1155
return
}
var elemOpts = getOptionsFromTag(elem, host.vmodels)
var vmOpts = getOptionsFromVM(
host.vmodels,
elemOpts.config || host.name
)
var $id = elemOpts.$id || elemOpts.identifier || generateID(widget)
delete elemOpts.config
delete elemOpts.$id
delete elemOpts.identifier
var componentDefinition = {
$up: host.vmodels[0],
$ups: host.vmodels
}
var props = getOptionsFromTag(elem, host.vmodels)
var vmOpts = getOptionsFromVM(host.vmodels, props.config)
var $id = props.uuid || generateID(widget)
var componentDefinition = {}
Anot.mix(true, componentDefinition, hooks)
componentDefinition = Anot.components[name].$construct.call(
elem,
componentDefinition,
vmOpts,
elemOpts
)
props = Object.assign({}, vmOpts, props)
vmOpts = void 0
delete props.config
delete props.uuid
hooks.construct.call(elem, props, function next(val) {
Object.assign(hooks.props, val)
Object.assign(componentDefinition, hooks)
})
componentDefinition.$refs = {}
componentDefinition.$id = $id
//==========构建VM=========
var keepContainer = componentDefinition.$container
var keepTemplate = componentDefinition.$template
delete componentDefinition.$up
delete componentDefinition.$ups
delete componentDefinition.$slot
delete componentDefinition.$replace
delete componentDefinition.$container
delete componentDefinition.$construct
var {
componentWillMount,
componentDidMount,
childComponentDidMount,
componentWillUnmount,
render
} = componentDefinition
delete componentDefinition.construct
delete componentDefinition.componentWillMount
delete componentDefinition.componentDidMount
delete componentDefinition.childComponentDidMount
delete componentDefinition.componentWillUnmount
var vmodel = Anot(componentDefinition)
var vmodel = Anot(componentDefinition) || {}
vmodel.$ups = host.vmodels
vmodel.$up = host.vmodels[0]
elem.msResolved = 1 //防止二进扫描此元素
vmodel.$init(vmodel, elem)
global.$init(vmodel, elem)
var nodes = elem.childNodes
if (vmodel.$$template) {
componentWillMount.call(vmodel)
globalHooks.componentWillMount.call(null, vmodel)
if (!elem.content.firstElementChild) {
Anot.clearHTML(elem)
elem.innerHTML = vmodel.$$template(keepTemplate)
elem.innerHTML = render()
}
// 组件所使用的标签是temlate,所以必须要要用子元素替换掉
var child = elem.content.firstChild
if (!child || serialize.call(child) === '[object Text]') {
var tmpDom = document.createElement('div')
if (child) {
tmpDom.appendChild(child)
}
child = tmpDom
tmpDom = null
}
var child = elem.content.firstElementChild
elem.parentNode.replaceChild(child, elem)
child.msResolved = 1
@ -3503,40 +3507,39 @@
if (className) {
Anot(elem).addClass(className)
}
//指定了组件的容器的话,则把组件节点转过去
if (keepContainer) {
keepContainer.appendChild(elem)
}
hideProperty(vmodel, '$elem', elem)
Anot.fireDom(elem, 'datasetchanged', {
vm: vmodel,
childReady: 1
})
var children = 0
var removeFn = Anot.bind(elem, 'datasetchanged', function(e) {
if (e.childReady) {
dependencies += e.childReady
if (vmodel !== e.vm) {
vmodel.$refs[e.vm.$id] = e.vm
if (e.childReady === -1) {
var removeFn = Anot.bind(elem, 'datasetchanged', function(ev) {
if (ev.childReady) {
dependencies += ev.childReady
if (vmodel !== ev.vm) {
vmodel.$refs[ev.vm.$id] = ev.vm
if (ev.childReady === -1) {
children++
vmodel.$childReady(vmodel, elem, e)
childComponentDidMount.call(vmodel, elem, ev)
}
e.stopPropagation()
ev.stopPropagation()
}
}
if (dependencies === 0) {
var id1 = setTimeout(function() {
clearTimeout(id1)
vmodel.$ready(vmodel, elem, host.vmodels)
global.$ready(vmodel, elem, host.vmodels)
var timer = setTimeout(function() {
clearTimeout(timer)
componentDidMount.call(vmodel)
globalHooks.componentDidMount(null, vmodel)
}, children ? Math.max(children * 17, 100) : 17)
Anot.unbind(elem, 'datasetchanged', removeFn)
//==================
host.rollback = function() {
try {
vmodel.$dispose(vmodel, elem)
global.$dispose(vmodel, elem)
componentWillUnmount.call(vmodel)
globalHooks.componentWillUnmount.call(null, vmodel)
} catch (e) {}
delete Anot.vmodels[vmodel.$id]
}
@ -3548,7 +3551,7 @@
}
}
})
scanTag(elem, [vmodel].concat(host.vmodels))
scanTag(elem, [vmodel])
Anot.vmodels[vmodel.$id] = vmodel
if (!elem.childNodes.length) {
Anot.fireDom(elem, 'datasetchanged', {
@ -6457,9 +6460,6 @@
Anot.config({
loader: true
})
Anot.ready(function() {
scanTag(DOC.body, [])
})
if (typeof define === 'function' && define.amd) {
define('Anot', [], function() {

View File

@ -1,32 +1,32 @@
<div class="do-pages do-fn-noselect" :class="{{theme}}">
<div class="do-pages do-fn-noselect" :class="{{props.theme}}">
<a class="normal"
:if="curr > 1 && !simpleMode"
:if="currPage > 1 && !simpleMode"
:attr="{href: $setUrl(1)}"
:text="btns.home"
:text="props.btns.home"
:click="$jump($event, 1)"></a>
<a class="normal"
:if="curr > 1"
:attr="{href: $setUrl(curr - 1)}"
:text="btns.prev"
:click="$jump($event, curr - 1)"></a>
<a :if-loop="!simpleMode || curr === el"
:if="currPage > 1"
:attr="{href: $setUrl(currPage - 1)}"
:text="props.btns.prev"
:click="$jump($event, currPage - 1)"></a>
<a :if-loop="!simpleMode || currPage === el"
:repeat="pageList"
:attr="{href: $setUrl(el)}"
:class="{normal: curr !== el && '...' !== el, disabled: '...' === el, curr: curr === el}"
:class="{normal: currPage !== el && '...' !== el, disabled: '...' === el, curr: currPage === el}"
:text="el"
:click="$jump($event, el)"></a>
<a class="normal"
:if="curr < total"
:attr="{href: $setUrl(curr + 1)}"
:click="$jump($event, curr + 1)">{{btns.next}}</a>
:if="currPage < totalPages"
:attr="{href: $setUrl(currPage + 1)}"
:click="$jump($event, currPage + 1)">{{props.btns.next}}</a>
<a class="normal"
:if="curr < total && !simpleMode"
:attr="{href: $setUrl(total)}"
:click="$jump($event, total)">{{btns.end}}</a>
:if="currPage < totalPages && !simpleMode"
:attr="{href: $setUrl(totalPages)}"
:click="$jump($event, totalPages)">{{props.btns.end}}</a>
<div class="input-box" :if="inputJump && !simpleMode">
<span>共{{total}}页,跳转到第</span>
<input type="text" :duplex-number="input" :keyup="$jump($event)">
<span>共{{totalPages}}页 {{totalItems}}条,跳转到第</span>
<input type="text" :duplex-number="inputPage" :keyup="$jump($event)">
<span></span>
<a class="normal" :attr="{href: $setUrl(input)}" :click="$jump($event, input)">确定</a>
</div>

View File

@ -1,30 +1,35 @@
"use strict";
define(["yua","text!./main.htm", "css!./main"], function(yua, tpl) {
'use strict'
import 'Anot'
import tpl from 'text!./main.htm'
import 'css!./main.css'
yua.ui.pages = '1.0.0'
Anot.ui.pages = '1.0.0'
var colors = { plain: 1, green: 1, blue: 1, red: 1, orange: 1, grey: 1 },
themes = ['skin-1 ', 'skin-2 '];
themes = ['skin-1 ', 'skin-2 ']
//计算页码列表
function calculate(vm){
if (vm.total < 2)
return vm.pageList.clear();
function calculate({ currPage, maxPageShow, totalPages }) {
let arr = []
let midPage =
currPage < maxPageShow / 2
? maxPageShow - currPage
: Math.floor(maxPageShow / 2)
var arr = [],
mid = vm.curr < vm.max / 2 ? vm.max - vm.curr : Math.floor(vm.max / 2);
if(vm.curr - mid > 1){
if (currPage - midPage > 1) {
arr.push('...')
}
for (var i = vm.curr - mid; i < vm.curr + mid + 1 && i <= vm.total; i++){
for (
var i = currPage - midPage;
i < currPage + midPage + 1 && i <= totalPages;
i++
) {
if (i > 0) {
arr.push(i)
}
}
if(vm.curr + mid < vm.total){
if (currPage + midPage < totalPages) {
arr.push('...')
}
vm.pageList.clear()
vm.pageList.pushArray(arr)
return arr
}
function update(pid, vm) {
@ -40,44 +45,85 @@ define(["yua","text!./main.htm", "css!./main"], function(yua, tpl) {
}
}
return yua.component('pages', {
$template: tpl,
$construct: function(a, b, c){
yua.mix(a, b, c)
a.theme = themes[a.theme>>0]
if(!a.theme){
a.theme = themes[0]
}
if(a.color && colors[a.color]){
a.theme += a.color
}else{
a.theme += 'plain'
}
delete a.color
return a
export default Anot.component('pages', {
construct: function(props, next) {
// console.log(props, this)
next(props)
},
$init: function(vm) {
render: function() {
return tpl
},
componentWillMount: function(vm) {
if (this.totalPages < 2) {
return
}
const { currPage, totalPages, props } = this
this.pageList.clear()
this.pageList.pushArray(
calculate({ currPage, totalPages, maxPageShow: props.maxPageShow })
)
},
componentDidMount: function() {
this.props.onSuccess(this)
},
state: {
currPage: 1,
totalItems: 100,
perPage: 20,
inputJump: !1,
simpleMode: !1,
inputPage: 1,
pageList: []
},
computed: {
totalPages: function() {
return Math.ceil(this.totalItems / this.perPage)
}
},
props: {
url: 'javascript:;',
btns: {
prev: '<<',
next: '>>',
home: '首页',
end: '末页'
},
maxPageShow: 5,
theme: 'skin-2 red',
onPageChange: Anot.noop,
onSuccess: Anot.noop
},
watch: {
curr: function(val, old) {
val = val >>> 0 || 1
old = old >>> 0
if (val !== old) {
calculate(vm)
vm.$setUrl = function(val) {
if(!vm.url
|| '...' === val
|| vm.curr === val
|| val > vm.total
|| 1 > val) {
}
},
total: function(val, old) {
val = val >>> 0 || 1
old = old >>> 0
if (val !== old) {
calculate(vm)
}
}
},
methods: {
$setUrl: function(val) {
if (
!this.props.url ||
'...' === val ||
this.curr === val ||
val > this.total ||
1 > val
) {
return 'javascript:;'
} else {
return vm.url.replace('{id}', val)
return this.props.url.replace('{id}', val)
}
}
vm.$forceReset = function(){
vm.curr = 1
calculate(vm)
}
vm.$jump = function(ev, val) {
},
$jump: function(ev, val) {
if ('...' !== val) {
var link = this.getAttribute('href') || this.getAttribute('xlink:href')
@ -85,55 +131,21 @@ define(["yua","text!./main.htm", "css!./main"], function(yua, tpl) {
if ('javascript:;' !== link) {
location.href = link
}
var pid = val >> 0;
update(pid, vm)
var pid = val >> 0
update(pid, this)
} else {
vm.input = vm.input >>> 0 || 1;
this.input = this.input >>> 0 || 1
if (13 == ev.keyCode) {
update(vm.input, vm)
update(this.input, this)
}
}
}
},
$onJump: Anot.noop,
$onSuccess: Anot.noop,
$forceReset: function() {
this.curr = 1
calculate(this)
}
vm.$watch('curr', function(val, old) {
val = (val >>> 0) || 1
old = old >>> 0
if(val !== old){
calculate(vm)
}
})
vm.$watch('total', function(val, old) {
val = (val >>> 0) || 1
old = old >>> 0
if(val !== old){
calculate(vm)
}
})
},
$ready: function(vm){
vm.$onSuccess(vm)
},
curr: 1,
total: 1,
max: 5,
url: "javascript:;",
inputJump: !1,
simpleMode: !1,
input: 1,
pageList: [],
btns: {
prev: "<<",
next: ">>",
home: "首页",
end: "末页"
},
theme: '',
$skipArray: ['max', 'btns', 'url', 'theme'],
$setUrl: yua.noop,
$jump: yua.noop,
$onJump: yua.noop,
$onSuccess: yua.noop,
$forceReset: yua.noop,
})
});