Merge pull request #132 from TuSimple/freestyle

Freestyle
This commit is contained in:
07akioni 2020-05-19 15:25:19 +08:00 committed by GitHub Enterprise
commit 4b8e4f153a
24 changed files with 321 additions and 151 deletions

View File

@ -1,9 +1,20 @@
# CHANGELOG
## 1.1.2 (2020-05-19)
### Features
- Add content slot for `n-step`.
- Add `label` prop for `n-checkbox`.
### Performance Improvements
- All placeable components register listeners on demand.
- Use cache when finding scrollable parent node.
- Imporve performance of `n-button`'s beforeDestroy.
- Reduce the useless re-rendering of `n-checkbox` when checked status isn't changed.
- Imporve performance of text typed `n-avatar`.
## 1.1.1 (2020-05-18)
### Fixes
- Update css-render dependencies.
- Color of default typed button icon.
### Performance Imporvements
### Performance Improvements
- Reduce useless re-renders of `n-menu-item`.
- Reduce useless re-renders of doc page.
### Refactors

View File

@ -1,9 +1,20 @@
# CHANGELOG
## 1.1.2 (2020-05-19)
### Features
- 为 `n-step` 增加内容的 slot
- 为 `n-checkbox` 增加了 `label` prop
### Performance Improvements
- 所有定位组件按需注册监听器
- 在寻找可滚动节点的过程中使用缓存
- 提升了 `n-button` beforeDestroy 的性能
- 减少了 `n-checkbox` 在值未改变时的重复渲染
- 提升了文字内容的 `n-avatar` 的性能
## 1.1.1 (2020-05-18)
### Fixes
- 更新 css-render 的依赖
- 默认类型的按钮的 icon 的颜色
### Performance Imporvements
### Performance Improvements
- 减少了 `n-menu-item` 没用的重复渲染
- 减少了文档页面没用的重复渲染
### Refactors

View File

@ -1,11 +1,11 @@
# Event
```html
<n-checkbox v-model="value" @change="handleChange">Event</n-checkbox>
<n-checkbox v-model="value" @change="handleChange" label="Event" />
<n-checkbox-group v-model="cities" @change="handleChange">
<n-checkbox value="Beijing">Beijing</n-checkbox>
<n-checkbox value="Shanghai">Shanghai</n-checkbox>
<n-checkbox value="Guangzhou">Guangzhou</n-checkbox>
<n-checkbox value="Shenzen">Shenzhen</n-checkbox>
<n-checkbox value="Beijing" label="Beijing" />
<n-checkbox value="Shanghai" label="Shanghai" />
<n-checkbox value="Guangzhou" label="Guangzhou" />
<n-checkbox value="Shenzen" label="Shenzhen" />
</n-checkbox-group>
```
```js

View File

@ -4,50 +4,50 @@ Use checkbox with grid.
<n-checkbox-group v-model="value">
<n-row>
<n-col :span="12">
<n-checkbox value="Prosperity">Prosperity</n-checkbox>
<n-checkbox value="Prosperity" label="Prosperity" />
</n-col>
<n-col :span="12">
<n-checkbox value="Democracy">Democracy</n-checkbox>
<n-checkbox value="Democracy" label="Democracy" />
</n-col>
</n-row>
<n-row>
<n-col :span="12">
<n-checkbox value="Civility">Civility</n-checkbox>
<n-checkbox value="Civility" label="Civility" />
</n-col>
<n-col :span="12">
<n-checkbox value="Harmony">Harmony</n-checkbox>
<n-checkbox value="Harmony" label="Harmony" />
</n-col>
</n-row>
<n-row>
<n-col :span="12">
<n-checkbox value="Freedom">Freedom</n-checkbox>
<n-checkbox value="Freedom" label="Freedom" />
</n-col>
<n-col :span="12">
<n-checkbox value="Equality">Equality</n-checkbox>
<n-checkbox value="Equality" label="Equality" />
</n-col>
</n-row>
<n-row>
<n-col :span="12">
<n-checkbox value="Justice">Justice</n-checkbox>
<n-checkbox value="Justice" label="Justice" />
</n-col>
<n-col :span="12">
<n-checkbox value="Rule of Law">Rule of Law</n-checkbox>
<n-checkbox value="Rule of Law" label="Rule of Law" />
</n-col>
</n-row>
<n-row>
<n-col :span="12">
<n-checkbox value="Patriotism">Patriotism</n-checkbox>
<n-checkbox value="Patriotism" label="Patriotism" />
</n-col>
<n-col :span="12">
<n-checkbox value="Dedication">Dedication</n-checkbox>
<n-checkbox value="Dedication" label="Dedication" />
</n-col>
</n-row>
<n-row>
<n-col :span="12">
<n-checkbox value="Integrity">Integrity</n-checkbox>
<n-checkbox value="Integrity" label="Integrity" />
</n-col>
<n-col :span="12">
<n-checkbox value="Friendship">Friendship</n-checkbox>
<n-checkbox value="Friendship" label="Friendship" />
</n-col>
</n-row>
</n-checkbox-group>

View File

@ -1,10 +1,10 @@
# Checkbox Group
```html
<n-checkbox-group v-model="cities">
<n-checkbox value="Beijing">Beijing</n-checkbox>
<n-checkbox value="Shanghai">Shanghai</n-checkbox>
<n-checkbox value="Guangzhou">Guangzhou</n-checkbox>
<n-checkbox value="Shenzen">Shenzhen</n-checkbox>
<n-checkbox value="Beijing" label="Beijing" />
<n-checkbox value="Shanghai" label="Shanghai" />
<n-checkbox value="Guangzhou" label="Guangzhou" />
<n-checkbox value="Shenzen" label="Shenzhen" />
</n-checkbox-group>
```
```js

View File

@ -28,6 +28,7 @@ event
|value|`string \| number`|`null`||
|checked|`boolean`|`false`||
|disabled|`boolean`|`false`||
|label|`string \| function`|`null`|Could be a render function.|
### Checkbox Group Props
|Name|Type|Default|Description|
@ -38,6 +39,11 @@ event
## Slots
### Checkbox Slots
<n-alert title="Caveat" type="warning" style="margin-bottom: 16px">
Don't use the slot in a massive checkbox group. Since it will cause re-rendering of all the checkboxes everytime when the group value changes. In that case you may use <n-text code>label</n-text> prop instead.
</n-alert>
|Name|Parameters|Description|
|-|-|-|
|default|`()`||

View File

@ -1,11 +1,11 @@
# 事件
```html
<n-checkbox v-model="value" @change="handleChange">事件</n-checkbox>
<n-checkbox v-model="value" @change="handleChange" label="事件" />
<n-checkbox-group v-model="cities" @change="handleChange">
<n-checkbox value="Beijing">北京</n-checkbox>
<n-checkbox value="Shanghai">上海</n-checkbox>
<n-checkbox value="Guangzhou">广州</n-checkbox>
<n-checkbox value="Shenzen">深圳</n-checkbox>
<n-checkbox value="Beijing" label="北京" />
<n-checkbox value="Shanghai" label="上海" />
<n-checkbox value="Guangzhou" label="广州" />
<n-checkbox value="Shenzen" label="深圳" />
</n-checkbox-group>
```
```js

View File

@ -4,50 +4,50 @@
<n-checkbox-group v-model="value">
<n-row>
<n-col :span="12">
<n-checkbox value="Prosperity">富强</n-checkbox>
<n-checkbox value="Prosperity" label="富强" />
</n-col>
<n-col :span="12">
<n-checkbox value="Democracy">民主</n-checkbox>
<n-checkbox value="Democracy" label="民主" />
</n-col>
</n-row>
<n-row>
<n-col :span="12">
<n-checkbox value="Civility">文明</n-checkbox>
<n-checkbox value="Civility" label="文明" />
</n-col>
<n-col :span="12">
<n-checkbox value="Harmony">和谐</n-checkbox>
<n-checkbox value="Harmony" label="和谐" />
</n-col>
</n-row>
<n-row>
<n-col :span="12">
<n-checkbox value="Freedom">自由</n-checkbox>
<n-checkbox value="Freedom" label="自由" />
</n-col>
<n-col :span="12">
<n-checkbox value="Equality">平等</n-checkbox>
<n-checkbox value="Equality" label="平等" />
</n-col>
</n-row>
<n-row>
<n-col :span="12">
<n-checkbox value="Justice">公正</n-checkbox>
<n-checkbox value="Justice" label="公正" />
</n-col>
<n-col :span="12">
<n-checkbox value="Rule of Law">法制</n-checkbox>
<n-checkbox value="Rule of Law" label="法制" />
</n-col>
</n-row>
<n-row>
<n-col :span="12">
<n-checkbox value="Patriotism">爱国</n-checkbox>
<n-checkbox value="Patriotism" label="爱国" />
</n-col>
<n-col :span="12">
<n-checkbox value="Dedication">敬业</n-checkbox>
<n-checkbox value="Dedication" label="敬业" />
</n-col>
</n-row>
<n-row>
<n-col :span="12">
<n-checkbox value="Integrity">诚信</n-checkbox>
<n-checkbox value="Integrity" label="诚信" />
</n-col>
<n-col :span="12">
<n-checkbox value="Friendship">友善</n-checkbox>
<n-checkbox value="Friendship" label="友善" />
</n-col>
</n-row>
</n-checkbox-group>

View File

@ -1,10 +1,10 @@
# 选项组
```html
<n-checkbox-group v-model="cities">
<n-checkbox value="Beijing">北京</n-checkbox>
<n-checkbox value="Shanghai">上海</n-checkbox>
<n-checkbox value="Guangzhou">广州</n-checkbox>
<n-checkbox value="Shenzen">深圳</n-checkbox>
<n-checkbox value="Beijing" label="北京" />
<n-checkbox value="Shanghai" label="上海" />
<n-checkbox value="Guangzhou" label="广州" />
<n-checkbox value="Shenzen" label="深圳" />
</n-checkbox-group>
```
```js

View File

@ -28,6 +28,7 @@ event
|value|`string \| number`|`null`||
|checked|`boolean`|`false`||
|disabled|`boolean`|`false`||
|label|`string \| function`|`null`|可以是渲染函数|
### Checkbox Group Props
|名称|类型|默认值|说明|
@ -38,6 +39,12 @@ event
## Slots
### Checkbox Slots
<n-alert title="Caveat" type="warning" style="margin-bottom: 16px">
不要在一个巨量的选项组中使用 Checkbox 的 slot因为它会导致每次选项组值变更的时候对每个 Checkbox 做一次重新渲染。在这种情况下你可以使用 <n-text code>label</n-text> 属性来替代。
</n-alert>
|名称|参数|说明|
|-|-|-|
|default|`()`||

View File

@ -1,4 +1,4 @@
# Custom
# Use Slot in Step
```html
<n-steps
:current="current"
@ -7,25 +7,49 @@
<n-step title="I Me Mine">
<div class="n-step-description">
<p>Al through the day, I me mine I me mine, I me mine</p>
<n-button :type="current === 1 ? currentStatus : null" size="small" @click="handleButton1Click">click me</n-button>
<n-button
v-if="current === 1"
:type="buttonType"
size="small"
@click="handleButtonClick">
Next
</n-button>
</div>
</n-step>
<n-step title="Let It Be">
<div class="n-step-description">
<p>When I find myself in times of trouble Mother Mary comes to me</p>
<n-button :type="current === 2 ? currentStatus : null" size="small" @click="handleButton2Click">click me</n-button>
<n-button
v-if="current === 2"
:type="buttonType"
size="small"
@click="handleButtonClick">
Next
</n-button>
</div>
</n-step>
<n-step title="Come Together">
<div class="n-step-description">
<p>Here come old flat top He come grooving up slowly</p>
<n-button :type="current === 3 ? currentStatus : null" size="small" @click="handleButton3Click">click me</n-button>
<n-button
v-if="current === 3"
:type="buttonType"
size="small"
@click="handleButtonClick">
Next
</n-button>
</div>
</n-step>
<n-step title="Something">
<div class="n-step-description">
<p>Something in the way she moves Attracts me like no other lover</p>
<n-button :type="current === 4 ? currentStatus : null" size="small" @click="handleButton4Click">click me</n-button>
<n-button
v-if="current === 4"
:type="buttonType"
size="small"
@click="handleButtonClick">
Next
</n-button>
</div>
</n-step>
</n-steps>
@ -34,13 +58,13 @@
<n-radio-button value="error">
Error
</n-radio-button>
<n-radio-button value="success">
<n-radio-button value="process">
Process
</n-radio-button>
<n-radio-button value="warning">
<n-radio-button value="wait">
Wait
</n-radio-button>
<n-radio-button value="primary">
<n-radio-button value="finish">
Finish
</n-radio-button>
</n-radio-group>
@ -61,30 +85,21 @@ export default {
currentStatus: 'error'
}
},
computed: {
buttonType () {
switch (this.currentStatus) {
case 'error':
return 'error'
case 'finish':
return 'success'
default:
return 'default'
}
}
},
methods: {
handleButton1Click() {
if(this.current === 1) {
console.log('click 1, do something')
this.current++
}
},
handleButton2Click() {
if(this.current === 2) {
console.log('click 2, do something')
this.current++
}
},
handleButton3Click() {
if(this.current === 3) {
console.log('click 3, do something')
this.current++
}
},
handleButton4Click() {
if(this.current === 4) {
console.log('click 4, do something')
this.current = 1
}
handleButtonClick() {
this.current = (this.current % 4) + 1
}
}
}

View File

@ -1,4 +1,4 @@
# 自定义内容
# 使用 Step 的 Slot
```html
<n-steps
:current="current"
@ -7,25 +7,49 @@
<n-step title="I Me Mine">
<div class="n-step-description">
<p>Al through the day, I me mine I me mine, I me mine</p>
<n-button :type="current === 1 ? currentStatus : null" size="small" @click="handleButton1Click">click me</n-button>
<n-button
v-if="current === 1"
:type="buttonType"
size="small"
@click="handleButtonClick">
Next
</n-button>
</div>
</n-step>
<n-step title="Let It Be">
<div class="n-step-description">
<p>When I find myself in times of trouble Mother Mary comes to me</p>
<n-button :type="current === 2 ? currentStatus : null" size="small" @click="handleButton2Click">click me</n-button>
<n-button
v-if="current === 2"
:type="buttonType"
size="small"
@click="handleButtonClick">
Next
</n-button>
</div>
</n-step>
<n-step title="Come Together">
<div class="n-step-description">
<p>Here come old flat top He come grooving up slowly</p>
<n-button :type="current === 3 ? currentStatus : null" size="small" @click="handleButton3Click">click me</n-button>
<n-button
v-if="current === 3"
:type="buttonType"
size="small"
@click="handleButtonClick">
Next
</n-button>
</div>
</n-step>
<n-step title="Something">
<div class="n-step-description">
<p>Something in the way she moves Attracts me like no other lover</p>
<n-button :type="current === 4 ? currentStatus : null" size="small" @click="handleButton4Click">click me</n-button>
<n-button
v-if="current === 4"
:type="buttonType"
size="small"
@click="handleButtonClick">
Next
</n-button>
</div>
</n-step>
</n-steps>
@ -34,13 +58,13 @@
<n-radio-button value="error">
Error
</n-radio-button>
<n-radio-button value="success">
<n-radio-button value="process">
Process
</n-radio-button>
<n-radio-button value="warning">
<n-radio-button value="wait">
Wait
</n-radio-button>
<n-radio-button value="primary">
<n-radio-button value="finish">
Finish
</n-radio-button>
</n-radio-group>
@ -61,30 +85,21 @@ export default {
currentStatus: 'error'
}
},
computed: {
buttonType () {
switch (this.currentStatus) {
case 'error':
return 'error'
case 'finish':
return 'success'
default:
return 'default'
}
}
},
methods: {
handleButton1Click() {
if(this.current === 1) {
console.log('click 1, do something')
this.current++
}
},
handleButton2Click() {
if(this.current === 2) {
console.log('click 2, do something')
this.current++
}
},
handleButton3Click() {
if(this.current === 3) {
console.log('click 3, do something')
this.current++
}
},
handleButton4Click() {
if(this.current === 4) {
console.log('click 4, do something')
this.current = 1
}
handleButtonClick() {
this.current = (this.current % 4) + 1
}
}
}

View File

@ -24,14 +24,14 @@ import DocHeader from './header.vue'
import menuOptions from './menuOptions'
import { i18n } from './init'
import { state } from './store'
import staputed from '../src/_mixins/staputed'
import simulatedComputed from '../src/_mixins/simulatedComputed'
export default {
components: {
DocHeader
},
mixins: [
staputed({
simulatedComputed({
menuGenerationOptions: {
get () {
return {

View File

@ -1,6 +1,6 @@
{
"name": "naive-ui",
"version": "1.1.0",
"version": "1.1.2",
"description": "A Vue UI Framework. Caring About Styles, Themed, Batteries Included, Not Rather Slow.",
"main": "lib/index.js",
"module": "es/index.js",
@ -40,7 +40,6 @@
"@babel/cli": "^7.8.4",
"@babel/core": "^7.8.4",
"@babel/preset-env": "^7.8.4",
"@css-render/plugin-bem": "^0.7.5",
"@kazupon/vue-i18n-loader": "^0.4.1",
"@rollup/plugin-node-resolve": "^6.1.0",
"@rollup/plugin-strip": "^1.3.2",
@ -63,7 +62,6 @@
"cors": "^2.8.5",
"cross-env": "^5.2.1",
"css-loader": "^2.1.1",
"css-render": "^0.7.5",
"cssnano": "^4.1.10",
"emoji-regex": "^8.0.0",
"emoji-unicode": "^1.1.0",
@ -122,7 +120,9 @@
"webpack-dev-server": "^3.10.3"
},
"dependencies": {
"@css-render/plugin-bem": "^0.8.0",
"async-validator": "^1.11.5",
"css-render": "^0.8.0",
"date-fns": "^2.9.0",
"highlight.js": "^9.18.1",
"lodash-es": "^4.17.15",

View File

@ -143,8 +143,8 @@ export default {
slotEl.style.top = `${offsetTop}px`
slotEl.style.height = `${offsetHeight}px`
slotEl.style.maxWidth = `${offsetWidth + offsetLeft}px`
barEl.getBoundingClientRect()
slotEl.getBoundingClientRect()
void barEl.offsetHeight
void slotEl.offsetHeight
if (!transition) {
barEl.style.transition = null

View File

@ -19,6 +19,7 @@
<script>
import collectable from '../../_mixins/collectable'
import simlulatedComputed from '../../_mixins/simulatedComputed'
export default {
name: 'NAnchorLink',
@ -27,7 +28,19 @@ export default {
default: null
}
},
mixins: [collectable('NAnchor', 'collectedLinkHrefs', 'href')],
mixins: [
simlulatedComputed({
active: {
get () {
const href = this.href
return href && (this.activeHref === href)
},
deps: ['activeHref', 'href'],
default: false
}
}),
collectable('NAnchor', 'collectedLinkHrefs', 'href')
],
props: {
title: {
type: String,
@ -39,12 +52,12 @@ export default {
}
},
computed: {
active () {
return this.href && this.NAnchor.activeHref === this.href
activeHref () {
return this.NAnchor.activeHref
}
},
watch: {
active: function (value) {
active (value) {
if (value) this.NAnchor.updateBarPosition(this.$refs.title)
}
},

View File

@ -60,7 +60,8 @@ export default {
},
data () {
return {
ratio: 1
ratio: 1,
memorizedTextHTML: null
}
},
computed: {
@ -90,14 +91,20 @@ export default {
},
methods: {
adjustText () {
if (this.$refs.text) {
const elWidth = this.$el.offsetWidth
const textWidth = this.$refs.text.offsetWidth
const elHeight = this.$el.offsetHeight
const textHeight = this.$refs.text.offsetHeight
const radix = (this.circle || this.round) ? 0.75 : 0.85
const ratio = Math.min(elWidth / textWidth * radix, elHeight / textHeight * radix)
this.ratio = Math.min(1, ratio)
const textEl = this.$refs.text
if (textEl) {
const memorizedTextHTML = this.memorizedTextHTML
if (memorizedTextHTML === null || memorizedTextHTML !== textEl.innerHTML) {
this.memorizedTextHTML = textEl.innerHTML
const selfEl = this.$el
const elWidth = selfEl.offsetWidth
const textWidth = textEl.offsetWidth
const elHeight = selfEl.offsetHeight
const textHeight = textEl.offsetHeight
const radix = (this.circle || this.round) ? 0.75 : 0.85
const ratio = Math.min(elWidth / textWidth * radix, elHeight / textHeight * radix)
this.ratio = Math.min(1, ratio)
}
}
}
}

View File

@ -301,7 +301,10 @@ export default {
if (colorHash) {
unmountColorStyle(colorHash)
}
window.clearTimeout(this.rippleTimer)
const rippleTimer = this.rippleTimer
if (rippleTimer !== null) {
window.clearTimeout(rippleTimer)
}
},
methods: {
handleMouseDown (e) {

View File

@ -2,7 +2,7 @@
<div
class="n-checkbox"
:class="{
'n-checkbox--checked': syntheticChecked,
'n-checkbox--checked': renderSafeChecked,
'n-checkbox--disabled': syntheticDisabled,
'n-checkbox--indeterminate': indeterminate,
'n-checkbox--table-header': tableHeader,
@ -22,10 +22,12 @@
<line-mark class="n-checkbox-box__line-mark" />
</div>
<span
v-if="$scopedSlots.default"
v-if="label !== null || $scopedSlots.default"
class="n-checkbox__label"
>
<slot />
<slot>
<render :render="label" />
</slot>
</span>
</div>
</template>
@ -34,9 +36,11 @@
import withapp from '../../_mixins/withapp'
import themeable from '../../_mixins/themeable'
import asformitem from '../../_mixins/asformitem'
import collectable from '../../_mixins/collectable'
import simulatedComputed from '../../_mixins/simulatedComputed'
import render from '../../_utils/vue/render'
import CheckMark from './CheckMark'
import LineMark from './LineMark'
import collectable from '../../_mixins/collectable'
export default {
name: 'NCheckbox',
@ -47,7 +51,8 @@ export default {
},
components: {
CheckMark,
LineMark
LineMark,
render
},
mixins: [
withapp,
@ -73,7 +78,18 @@ export default {
return 'medium'
}
),
collectable('NCheckboxGroup', 'collectedCheckboxValues')
collectable('NCheckboxGroup', 'collectedCheckboxValues'),
simulatedComputed({
renderSafeChecked: {
default: false,
get () {
return this.syntheticChecked
},
deps: [
'syntheticChecked'
]
}
})
],
model: {
prop: 'checked',
@ -105,6 +121,10 @@ export default {
tableHeader: {
type: Boolean,
default: false
},
label: {
type: [String, Function],
default: null
}
},
computed: {

View File

@ -57,7 +57,7 @@
import collectable from '../../_mixins/collectable'
import withapp from '../../_mixins/withapp'
import themeable from '../../_mixins/themeable'
import staputed from '../../_mixins/staputed'
import simulatedComputed from '../../_mixins/simulatedComputed'
import NMenuItemContent from './MenuItemContent'
import NTooltip from '../../Tooltip'
import menuContentMixin from './menuContentMixin'
@ -76,7 +76,7 @@ export default {
return true
}
}),
staputed({
simulatedComputed({
selected: {
get () {
if (this.rootMenuValue === this.name) {

View File

@ -1,6 +1,5 @@
import scrollDelegate from '../_utils/delegate/scrollDelegate'
import resizeDelegate from '../_utils/delegate/resizeDelegate'
import getParentNode from '../_utils/dom/getParentNode'
import getScrollParent from '../_utils/dom/getScrollParent'
import {
getAdjustedPlacementOfTrackingElement,
@ -169,6 +168,11 @@ export default {
watch: {
active (value) {
if (value) {
if (!this.listenersRegistered) {
this.registerScrollListeners()
this.registerResizeListener()
this.listenersRegistered = true
}
this.$nextTick().then(this.updatePosition)
}
},
@ -184,17 +188,23 @@ export default {
trackingElement: null,
trackedElement: null,
scrollListeners: [],
adjustedPlacement: this.placement
adjustedPlacement: this.placement,
listenersRegistered: false
}
},
mounted () {
this.registerScrollListeners()
this.registerResizeListener()
if (this.active) {
this.registerScrollListeners()
this.registerResizeListener()
this.listenersRegistered = true
}
this.updatePosition()
},
beforeDestroy () {
this.unregisterScrollListeners()
this.unregisterResizeListener()
if (this.listenersRegistered) {
this.unregisterScrollListeners()
this.unregisterResizeListener()
}
},
methods: {
_getTrackingElement () {
@ -296,12 +306,11 @@ export default {
resizeDelegate.registerHandler(this.updatePosition)
},
registerScrollListeners () {
let currentElement = getParentNode(this._getTrackedElement())
let currentElement = this._getTrackedElement()
while (true) {
currentElement = getScrollParent(currentElement)
if (currentElement === null) break
this.scrollListeners.push([currentElement, this.updatePosition])
currentElement = getParentNode(currentElement)
}
for (const [el, handler] of this.scrollListeners) {
scrollDelegate.registerHandler(el, handler)

View File

@ -1,6 +1,6 @@
/**
* staputed means static computed, it behaves like a data property. If it's
* same after calculation, it won't cause re-render.
* simulatedComputed means it behaves like a computed property except the if it's
* same after re-calculation, it won't cause re-rendering.
*/
export default function (options) {
const keys = Object.keys(options)
@ -14,17 +14,20 @@ export default function (options) {
})
},
data () {
return data
return Object.assign({}, data)
}
}
keys.forEach(key => {
const computedData = options[key]
data[key] = computedData.default
for (const dep of computedData.deps) {
computedData.deps.forEach(dep => {
watch[dep] = function () {
this[key] = computedData.get.call(this)
const result = computedData.get.call(this)
if (result !== this[key]) {
this[key] = result
}
}
}
})
})
return mixin
}

View File

@ -1,6 +1,31 @@
import getStyleComputedProperty from './getStyleComputedProperty'
import getParentNode from './getParentNode'
const NOT_FOUND = 'NOT_FOUND'
const CACHE_DURATION = 60000
const scrollNodeCache = {
cache: new Map(),
read (node) {
if (this.cache.has(node)) {
return this.cache.get(node)
} else {
return NOT_FOUND
}
},
remove (node) {
this.cache.delete(node)
},
write (node, scrollParentNode) {
if (!this.cache.has(node)) {
this.cache.set(node, scrollParentNode)
window.setTimeout(() => {
this.remove(node)
}, CACHE_DURATION)
}
}
}
/**
* Returns the scrolling parent of the given element
* @method
@ -8,6 +33,16 @@ import getParentNode from './getParentNode'
* @returns {Element|null} scroll parent
*/
export default function getScrollParent (element) {
const startElement = getParentNode(element)
return getScrollElementFrom(startElement)
}
function getScrollElementFrom (element) {
const cachedNode = scrollNodeCache.read(element)
if (cachedNode !== NOT_FOUND) {
return cachedNode
}
// Return body, `getScroll` will take care to get the correct `scrollTop` from it
if (!element) {
return null
@ -24,8 +59,11 @@ export default function getScrollParent (element) {
// Firefox want us to check `-x` and `-y` variations as well
const { overflow, overflowX, overflowY } = getStyleComputedProperty(element)
if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {
scrollNodeCache.write(element, element)
return element
}
return getScrollParent(getParentNode(element))
const scrollElement = getScrollElementFrom(getParentNode(element))
scrollNodeCache.write(element, scrollElement)
return scrollElement
}

View File

@ -155,6 +155,12 @@ h('NLayout', {
```
一个是computed导致重复渲染还有一个是 getScrollParent 缓存的问题
## 2020.5.19
我在想要不要帮用户检查值,比如说一些不存在的值...现在这个问题就出现在 checkbox 里面,这是个哲学问题
## 2020.5.19
得看懂 vue 究竟是怎么更新组件的...
## TODO 排序不分先后
1. <del>Focus Detector on Time Selector</del>
2. <del>Menu Root Indent = 0 可能造成问题</del>
@ -246,7 +252,13 @@ h('NLayout', {
88. <del>CSS Font 选择</del> 对英文应该没有那么麻烦走系统字体就好了然而对中文又没什么好的解决方案so 先这个样子,之后再琢磨琢磨
89. <del>把所有用 $slots 判断的地方都改成 $scopedSlots[原因](https://vuejs.org/v2/api/#vm-scopedSlots)<del> done
90. 调整默认状态下 button 的 icon 的颜色
91. 优化 button 的样式,现在太冗余了,关键是怎么同步按钮的主题变量呢...
91. <del>优化 button 的样式,现在太冗余了,关键是怎么同步按钮的主题变量呢...</del>
92. <del>placeable 按需注册</del>
93. steps 列表优化
94. tabs 列表优化
95. tree 列表优化
96. cascader 列表优化
```
Done