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 $vmodel = new Component() //要返回的对象, 它在IE6-8下可能被偷龙转凤
var accessors = {} //监控属性
var hasOwn = { props: !!source.$id }
var hasOwn = {}
var skip = []
var simple = []
var $skipArray = {}
@ -1463,6 +1463,7 @@
if (props) {
hideProperty($vmodel, 'props', {})
hasOwn.props = !!source.$id
for (var name in props) {
$vmodel.props[name] = props[name]
}
@ -2789,20 +2790,18 @@
var ret = [],
prefix = ' = ' + name + '.'
for (var i = vars.length, prop; (prop = vars[--i]); ) {
var arr = prop.split('.'),
a
var arr = prop.split('.')
var first = arr[0]
while ((a = arr.shift())) {
if (vmodel.hasOwnProperty(a)) {
ret.push(first + prefix + first)
binding.observers.push({
v: vmodel,
p: prop
})
vars.splice(i, 1)
} else {
break
}
if (vmodel.hasOwnProperty(first)) {
// log(first, prop, prefix, vmodel)
ret.push(first + prefix + first)
binding.observers.push({
v: vmodel,
p: prop,
type: Anot.type(vmodel[first])
})
vars.splice(i, 1)
}
}
return ret
@ -2860,6 +2859,7 @@
}) +
expr +
dataType
// log(expr, '---------------', assigns)
var getter = evaluatorPool.get(exprId) //直接从缓存,免得重复生成
if (getter) {
if (dataType === 'duplex') {
@ -2869,6 +2869,7 @@
return (binding.getter = getter)
}
// expr的字段不可枚举时,补上一个随机变量, 避免抛出异常
if (!assigns.length) {
assigns.push('fix' + expose)
}
@ -2896,9 +2897,9 @@
if (dataType === 'on') {
//事件绑定
if (expr.indexOf('(') === -1) {
expr += '.call(this, $event)'
expr += '.call(' + names[names.length - 1] + ', $event)'
} else {
expr = expr.replace('(', '.call(this,')
expr = expr.replace('(', '.call(' + names[names.length - 1] + ', ')
}
names.push('$event')
expr = '\nreturn ' + expr + ';' //IE全家 Function("return ")出错需要Function("return ;")
@ -2907,11 +2908,33 @@
var footer = expr.slice(lastIndex)
expr = header + '\n' + footer
} 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 ;")
}
/* jshint ignore:start */
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 */
@ -3990,18 +4013,11 @@
binding.param.replace(rw20g, function(name) {
if (rduplexType.test(elem.type) && rduplexParam.test(name)) {
if (name === 'radio') log(':duplex-radio已经更名为:duplex-checked')
name = 'checked'
binding.isChecked = true
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]) {
hasCast = true
}
@ -5159,8 +5175,9 @@
keyOrId = track[i] //array为随机数, object 为keyName
var proxy = retain[keyOrId]
if (!proxy) {
// log(this)
proxy = getProxyVM(this)
proxy.$up = null
proxy.$up = this.vmodels[0]
if (xtype === 'array') {
action = 'add'
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"
:if="currPage > 1 && !simpleMode"
:attr="{href: $setUrl(1)}"
:if="currPage > 1 && !props.simpleMode"
:attr="{href: parseUrl(1)}"
:text="props.btns.home"
:click="$jump($event, 1)"></a>
:click="setPage(1, $event)"></a>
<a class="normal"
:if="currPage > 1"
:attr="{href: $setUrl(currPage - 1)}"
:attr="{href: parseUrl(currPage - 1)}"
:text="props.btns.prev"
:click="$jump($event, currPage - 1)"></a>
<a :if-loop="!simpleMode || currPage === el"
:click="setPage(currPage - 1, $event)"></a>
<a :if-loop="!props.simpleMode || currPage === el"
:repeat="pageList"
:attr="{href: $setUrl(el)}"
:class="{normal: currPage !== el && '...' !== el, disabled: '...' === el, curr: currPage === el}"
:attr="{href: parseUrl(el)}"
:class="{normal: currPage !== el, disabled: '...' === el, curr: currPage === el}"
:text="el"
:click="$jump($event, el)"></a>
:click="setPage(el, $event)"></a>
<a class="normal"
:if="currPage < totalPages"
:attr="{href: $setUrl(currPage + 1)}"
:click="$jump($event, currPage + 1)">{{props.btns.next}}</a>
:attr="{href: parseUrl(currPage + 1)}"
:click="setPage(currPage + 1, $event)">{{props.btns.next}}</a>
<a class="normal"
:if="currPage < totalPages && !simpleMode"
:attr="{href: $setUrl(totalPages)}"
:click="$jump($event, totalPages)">{{props.btns.end}}</a>
:if="currPage < totalPages && !props.simpleMode"
:attr="{href: parseUrl(totalPages)}"
:click="setPage(totalPages, $event)">{{props.btns.end}}</a>
<div class="input-box" :if="inputJump && !simpleMode">
<span>{{totalPages}}页 {{totalItems}}条,跳转到第</span>
<input type="text" :duplex-number="inputPage" :keyup="$jump($event)">
<div class="input-box" :if="!props.simpleMode">
<span> {{totalPages}} 页 {{totalItems}} 条,前往</span>
<input type="text" :duplex="inputPage" :keyup="setPage(null, $event)">
<span></span>
<a class="normal" :attr="{href: $setUrl(input)}" :click="$jump($event, input)">确定</a>
</div>
</div>

View File

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

View File

@ -9,78 +9,87 @@
@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.curr, a.disabled {cursor:default;}
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;}
&.skin-1 {width:100%;
a.normal,
a.disabled,
a.curr {padding:0 10px;margin:0 3px;}
&.skin-1 {width:100%;
a.normal,
a.disabled,
a.curr {padding:0 10px;margin:0 3px;}
a.curr {font-weight:bold;font-size:15px;}
a.disabled {min-width:0;padding:0}
.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;}
a.curr {font-weight:bold;font-size:15px;}
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:30px;height:30px;padding:0 3px;background:#fff;border:1px solid #ddd;text-align:center;}
}
&.skin-2 {float:right;width:auto;
a.normal,
a.disabled,
a.curr {float:left;margin:0;padding:0 5px;color:#fff;}
&.skin-2 {float:right;width:auto;
a.normal,
a.disabled,
a.curr {float:left;margin:0;padding:0 5px;color:#fff;}
a.disabled {display:none;}
.input-box {display:none;}
a.disabled {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)}
}
}