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

优化绑定事件中this的指向;完成分页组件的改造

old
宇天 2017-12-23 00:34:44 +08:00
parent 35defd426d
commit c1a1f9d917
4 changed files with 201 additions and 180 deletions

View File

@ -1363,7 +1363,7 @@
var oldAccessors = (old && old.$accessors) || nullObject var oldAccessors = (old && old.$accessors) || nullObject
var $vmodel = new Component() //要返回的对象, 它在IE6-8下可能被偷龙转凤 var $vmodel = new Component() //要返回的对象, 它在IE6-8下可能被偷龙转凤
var accessors = {} //监控属性 var accessors = {} //监控属性
var hasOwn = { props: !!source.$id } var hasOwn = {}
var skip = [] var skip = []
var simple = [] var simple = []
var $skipArray = {} var $skipArray = {}
@ -1463,6 +1463,7 @@
if (props) { if (props) {
hideProperty($vmodel, 'props', {}) hideProperty($vmodel, 'props', {})
hasOwn.props = !!source.$id
for (var name in props) { for (var name in props) {
$vmodel.props[name] = props[name] $vmodel.props[name] = props[name]
} }
@ -2789,20 +2790,18 @@
var ret = [], var ret = [],
prefix = ' = ' + name + '.' prefix = ' = ' + name + '.'
for (var i = vars.length, prop; (prop = vars[--i]); ) { for (var i = vars.length, prop; (prop = vars[--i]); ) {
var arr = prop.split('.'), var arr = prop.split('.')
a
var first = arr[0] var first = arr[0]
while ((a = arr.shift())) {
if (vmodel.hasOwnProperty(a)) { if (vmodel.hasOwnProperty(first)) {
ret.push(first + prefix + first) // log(first, prop, prefix, vmodel)
binding.observers.push({ ret.push(first + prefix + first)
v: vmodel, binding.observers.push({
p: prop v: vmodel,
}) p: prop,
vars.splice(i, 1) type: Anot.type(vmodel[first])
} else { })
break vars.splice(i, 1)
}
} }
} }
return ret return ret
@ -2860,6 +2859,7 @@
}) + }) +
expr + expr +
dataType dataType
// log(expr, '---------------', assigns)
var getter = evaluatorPool.get(exprId) //直接从缓存,免得重复生成 var getter = evaluatorPool.get(exprId) //直接从缓存,免得重复生成
if (getter) { if (getter) {
if (dataType === 'duplex') { if (dataType === 'duplex') {
@ -2869,6 +2869,7 @@
return (binding.getter = getter) return (binding.getter = getter)
} }
// expr的字段不可枚举时,补上一个随机变量, 避免抛出异常
if (!assigns.length) { if (!assigns.length) {
assigns.push('fix' + expose) assigns.push('fix' + expose)
} }
@ -2896,9 +2897,9 @@
if (dataType === 'on') { if (dataType === 'on') {
//事件绑定 //事件绑定
if (expr.indexOf('(') === -1) { if (expr.indexOf('(') === -1) {
expr += '.call(this, $event)' expr += '.call(' + names[names.length - 1] + ', $event)'
} else { } else {
expr = expr.replace('(', '.call(this,') expr = expr.replace('(', '.call(' + names[names.length - 1] + ', ')
} }
names.push('$event') names.push('$event')
expr = '\nreturn ' + expr + ';' //IE全家 Function("return ")出错需要Function("return ;") expr = '\nreturn ' + expr + ';' //IE全家 Function("return ")出错需要Function("return ;")
@ -2907,11 +2908,33 @@
var footer = expr.slice(lastIndex) var footer = expr.slice(lastIndex)
expr = header + '\n' + footer expr = header + '\n' + footer
} else { } else {
// 对于非事件绑定的方法, 同样绑定到vm上
binding.observers.forEach(function(it) {
if (it.type === 'function') {
// log(it, expr)
let reg = new RegExp(it.p + '\\(([^)]*)\\)', 'g')
expr = expr.replace(reg, function(s, m) {
m = m.trim()
return (
it.p +
'.call(' +
names[names.length - 1] +
(m ? ', ' + m : '') +
')'
)
})
}
})
expr = '\nreturn ' + expr + ';' //IE全家 Function("return ")出错需要Function("return ;") expr = '\nreturn ' + expr + ';' //IE全家 Function("return ")出错需要Function("return ;")
} }
/* jshint ignore:start */ /* jshint ignore:start */
getter = scpCompile( getter = scpCompile(
names.concat("'use strict';\nvar " + assigns.join(',\n') + expr) names.concat(
"'use strict';\ntry{\nvar " +
assigns.join(',\n') +
expr +
'\n}catch(e){log(e)}'
)
) )
/* jshint ignore:end */ /* jshint ignore:end */
@ -3990,18 +4013,11 @@
binding.param.replace(rw20g, function(name) { binding.param.replace(rw20g, function(name) {
if (rduplexType.test(elem.type) && rduplexParam.test(name)) { if (rduplexType.test(elem.type) && rduplexParam.test(name)) {
if (name === 'radio') log(':duplex-radio已经更名为:duplex-checked')
name = 'checked' name = 'checked'
binding.isChecked = true binding.isChecked = true
binding.xtype = 'radio' binding.xtype = 'radio'
} }
if (name === 'bool') {
name = 'boolean'
log(':duplex-bool已经更名为:duplex-boolean')
} else if (name === 'text') {
name = 'string'
log(':duplex-text已经更名为:duplex-string')
}
if (casting[name]) { if (casting[name]) {
hasCast = true hasCast = true
} }
@ -5159,8 +5175,9 @@
keyOrId = track[i] //array为随机数, object 为keyName keyOrId = track[i] //array为随机数, object 为keyName
var proxy = retain[keyOrId] var proxy = retain[keyOrId]
if (!proxy) { if (!proxy) {
// log(this)
proxy = getProxyVM(this) proxy = getProxyVM(this)
proxy.$up = null proxy.$up = this.vmodels[0]
if (xtype === 'array') { if (xtype === 'array') {
action = 'add' action = 'add'
proxy.$id = keyOrId proxy.$id = keyOrId

View File

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

View File

@ -4,56 +4,58 @@ import tpl from 'text!./main.htm'
import 'css!./main.css' import 'css!./main.css'
Anot.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 ']
//计算页码列表 //计算页码列表
function calculate({ currPage, maxPageShow, totalPages }) { function calculate({ currPage, maxPageShow, totalPages }) {
let arr = [] let arr = []
let midPage = let fixNum = 0
let halfPage =
currPage < maxPageShow / 2 currPage < maxPageShow / 2
? maxPageShow - currPage ? maxPageShow - currPage
: Math.floor(maxPageShow / 2) : Math.floor(maxPageShow / 2)
if (currPage - midPage > 1) { if (currPage - halfPage > 1) {
arr.push('...') arr.push('...')
} }
if (totalPages - currPage < halfPage) {
fixNum = halfPage - totalPages + currPage
}
for ( for (
var i = currPage - midPage; let i = currPage - halfPage - fixNum;
i < currPage + midPage + 1 && i <= totalPages; i < currPage + halfPage + 1 && i <= totalPages;
i++ i++
) { ) {
if (i > 0) { if (i > 0) {
arr.push(i) arr.push(i)
} }
} }
if (currPage + midPage < totalPages) { if (currPage + halfPage < totalPages) {
arr.push('...') arr.push('...')
} }
return arr return arr
} }
// 更新组件
function update(pid, vm) { function update(currPage, vm) {
if (pid < 1) { const { totalPages, props } = vm
pid = vm.input = 1 vm.pageList.clear()
} vm.pageList.pushArray(
if (pid > vm.total) { calculate({ currPage, totalPages, maxPageShow: props.maxPageShow })
pid = vm.input = vm.total )
} vm.currPage = vm.inputPage = currPage
if (pid !== vm.curr) { vm.props.onPageChange.call(null, currPage)
vm.curr = vm.input = pid
vm.$onJump(pid)
}
} }
export default Anot.component('pages', { export default Anot.component('pages', {
construct: function(props, next) { construct: function(props, next) {
// console.log(props, this) props.className =
'skin-' + (props.theme || 1) + ' ' + (props.color || 'plain')
delete props.theme
delete props.color
next(props) next(props)
}, },
render: function() { render: function() {
return tpl return tpl
}, },
componentWillMount: function(vm) { componentWillMount: function() {
if (this.totalPages < 2) { if (this.totalPages < 2) {
return return
} }
@ -64,24 +66,23 @@ export default Anot.component('pages', {
) )
}, },
componentDidMount: function() { componentDidMount: function() {
this.props.onSuccess(this) this.props.onSuccess.call(null, this)
}, },
state: { state: {
currPage: 1, currPage: 1,
totalItems: 100, totalItems: 1000,
perPage: 20, pageSize: 20,
inputJump: !1,
simpleMode: !1,
inputPage: 1, inputPage: 1,
pageList: [] pageList: []
}, },
computed: { computed: {
totalPages: function() { totalPages: function() {
return Math.ceil(this.totalItems / this.perPage) return Math.ceil(this.totalItems / this.pageSize)
} }
}, },
props: { props: {
url: 'javascript:;', url: null,
btns: { btns: {
prev: '<<', prev: '<<',
next: '>>', next: '>>',
@ -89,63 +90,58 @@ export default Anot.component('pages', {
end: '末页' end: '末页'
}, },
maxPageShow: 5, maxPageShow: 5,
theme: 'skin-2 red', className: '',
simpleMode: !1,
onPageChange: Anot.noop, onPageChange: Anot.noop,
onSuccess: Anot.noop onSuccess: Anot.noop
}, },
watch: {
curr: function(val, old) {
val = val >>> 0 || 1
old = old >>> 0
if (val !== old) {
calculate(vm)
}
},
total: function(val, old) {
val = val >>> 0 || 1
old = old >>> 0
if (val !== old) {
calculate(vm)
}
}
},
methods: { methods: {
$setUrl: function(val) { // 格式化页码的URL
if ( parseUrl: function(val) {
!this.props.url || val = val >>> 0
'...' === val || if (val < 1 || !this.props.url || this.currPage === val) {
this.curr === val ||
val > this.total ||
1 > val
) {
return 'javascript:;' return 'javascript:;'
} else {
return this.props.url.replace('{id}', val)
} }
return this.props.url.replace('{id}', val)
}, },
$jump: function(ev, val) { // 设置页码
if ('...' !== val) { setPage: function(val, ev) {
var link = this.getAttribute('href') || this.getAttribute('xlink:href') if (this.currPage === val) {
return
}
let elem = (ev && ev.target) || null
if (val && elem) {
if (val && val !== '...') {
let link =
(elem && elem.getAttribute('href')) ||
elem.getAttribute('xlink:href')
if (val !== void 0) {
if ('javascript:;' !== link) { if ('javascript:;' !== link) {
location.href = link location.href = link
} else {
val = val >> 0
update(val, this)
}
}
} else {
if (val === null) {
this.inputPage = this.inputPage >>> 0 || 1
if (ev && ev.keyCode === 13) {
update(this.inputPage, this)
} }
var pid = val >> 0
update(pid, this)
} else { } else {
this.input = this.input >>> 0 || 1 val = val >>> 0
if (13 == ev.keyCode) { update(val, this)
update(this.input, this)
}
} }
} }
}, },
$onJump: Anot.noop, setPageSize: function(num) {
$onSuccess: Anot.noop, this.pageSize = +num
$forceReset: function() { update(1, this)
this.curr = 1 },
calculate(this) setTotalItems: function(num) {
this.totalItems = +num
update(1, this)
} }
} }
}) })

View File

@ -9,78 +9,87 @@
@import "../../../css/var.scss"; @import "../../../css/var.scss";
.do-pages {height:auto;text-align:center;font-size:13px; .do-pages {height:auto;text-align:center;font-size:13px;color: nth($cgr, 1);
a {display:inline-block;width:auto;min-width:40px;height:40px;line-height:40px;color: nth($cgr, 1);text-decoration:none;cursor:pointer;} a {display:inline-block;width:auto;min-width:40px;height:40px;line-height:40px;color: nth($cgr, 1);text-decoration:none;cursor:pointer;}
a.curr, a.disabled {cursor:default;} a.curr, a.disabled {cursor:default;}
&.skin-1 {width:100%; &.skin-1 {width:100%;
a.normal, a.normal,
a.disabled, a.disabled,
a.curr {padding:0 10px;margin:0 3px;} a.curr {padding:0 10px;margin:0 3px;}
a.curr {font-weight:bold;font-size:15px;} a.curr {font-weight:bold;font-size:15px;}
a.disabled {min-width:0;padding:0} a.disabled {min-width:0;padding:0;background:none;color:nth($cgr, 1);
&:hover,&:active {background:none;}
.input-box,
.input-box span,
.input-box input {display:inline-block}
.input-box input {width:25px;height:20px;padding:0 3px;background:#fff;border:1px solid #ddd}
.input-box a.normal{height:30px;line-height:30px;}
} }
.input-box,
.input-box span,
.input-box input {display:inline-block;}
.input-box input {width:30px;height:30px;padding:0 3px;background:#fff;border:1px solid #ddd;text-align:center;}
}
&.skin-2 {float:right;width:auto; &.skin-2 {float:right;width:auto;
a.normal, a.normal,
a.disabled, a.disabled,
a.curr {float:left;margin:0;padding:0 5px;color:#fff;} a.curr {float:left;margin:0;padding:0 5px;color:#fff;}
a.disabled {display:none;} a.disabled {display:none;}
.input-box {display:none;} .input-box {display:none;}
}
&.plain a.normal {background:nth($cp, 1);color:nth($cgr, 1);}
&.plain a.normal:hover {background:nth($cp, 2)}
&.skin-2.plain a.curr,
&.plain a.normal:active {background:nth($cp, 3)}
&.grey a.normal {background:nth($cgr, 1);color: #fff;}
&.grey a.normal:hover {background:nth($cgr, 2)}
&.skin-2.grey a.curr,
&.grey a.normal:active {background:nth($cgr, 3)}
&.red a.normal {background:nth($cr, 1);color: #fff;}
&.red a.normal:hover {background:nth($cr, 2)}
&.skin-2.red a.curr,
&.red a.normal:active {background:nth($cr, 3)}
&.orange a.normal {background:nth($co, 1);color: #fff;}
&.orange a.normal:hover {background:nth($co, 2)}
&.skin-2.orange a.curr,
&.orange a.normal:active {background:nth($co, 3)}
&.green a.normal {background:nth($cg, 1);color: #fff;}
&.green a.normal:hover {background:nth($cg, 2)}
&.skin-2.green a.curr,
&.green a.normal:active {background:nth($cg, 3)}
&.teal a.normal {background:nth($ct, 1);color: #fff;}
&.teal a.normal:hover {background:nth($ct, 2)}
&.skin-2.teal a.curr,
&.teal a.normal:active {background:nth($ct, 3)}
&.blue a.normal {background:nth($cb, 1);color: #fff;}
&.blue a.normal:hover {background:nth($cb, 2)}
&.skin-2.blue a.curr,
&.blue a.normal:active {background:nth($cb, 3)}
&.purple a.normal {background:nth($cpp, 1);color: #fff;}
&.purple a.normal:hover {background:nth($cpp, 2)}
&.skin-2.purple a.curr,
&.purple a.normal:active {background:nth($cpp, 3)}
&.skin-1 {
a.disabled {background:none;color:nth($cgr, 1);
&:hover,&:active {background:none;}
} }
}
&.plain a.normal {background:nth($cp, 1)}
&.plain a.normal:hover {background:nth($cp, 2)}
&.skin-2.plain a.curr,
&.plain a.normal:active {background:nth($cp, 3)}
&.grey a.normal {background:nth($cgr, 1);color: #fff;}
&.grey a.normal:hover {background:nth($cgr, 2)}
&.skin-2.grey a.curr,
&.grey a.normal:active {background:nth($cgr, 3)}
&.red a.normal {background:nth($cr, 1);color: #fff;}
&.red a.normal:hover {background:nth($cr, 2)}
&.skin-2.red a.curr,
&.red a.normal:active {background:nth($cr, 3)}
&.orange a.normal {background:nth($co, 1);color: #fff;}
&.orange a.normal:hover {background:nth($co, 2)}
&.skin-2.orange a.curr,
&.orange a.normal:active {background:nth($co, 3)}
&.green a.normal {background:nth($cg, 1);color: #fff;}
&.green a.normal:hover {background:nth($cg, 2)}
&.skin-2.green a.curr,
&.green a.normal:active {background:nth($cg, 3)}
&.teal a.normal {background:nth($ct, 1);color: #fff;}
&.teal a.normal:hover {background:nth($ct, 2)}
&.skin-2.teal a.curr,
&.teal a.normal:active {background:nth($ct, 3)}
&.blue a.normal {background:nth($cb, 1);color: #fff;}
&.blue a.normal:hover {background:nth($cb, 2)}
&.skin-2.blue a.curr,
&.blue a.normal:active {background:nth($cb, 3)}
&.purple a.normal {background:nth($cpp, 1);color: #fff;}
&.purple a.normal:hover {background:nth($cpp, 2)}
&.skin-2.purple a.curr,
&.purple a.normal:active {background:nth($cpp, 3)}
} }