mirror of
https://github.com/Tencent/Hippy.git
synced 2026-10-29 06:06:52 +08:00
refactor(demo): perf react&vue demo
This commit is contained in:
@@ -468,4 +468,4 @@ AsyncStorage 是一个简单的、异步的、持久化的 Key-Value 存储系
|
||||
|
||||
`(ref, callback: Function) => Promise`
|
||||
|
||||
> - callback: ({ x, y, width, height } | string | -1) => void - 回调函数, 参数可以获取到引用组件在 App 窗口范围内的坐标值和宽高,如果出错或者 [节点被优化(仅在Android)](hippy-react/components?id=样式内特殊属性)可能返回 -1 或者 `this view is null` 字符串
|
||||
> - callback: ({ x, y, width, height } | string | -1) => void - 回调函数, 参数可以获取到引用组件在 App 窗口范围内的坐标值和宽高,如果出错或者 [节点被优化(仅在Android)](style/layout?id=collapsable)可能返回 -1 或者 `this view is null` 字符串
|
||||
|
||||
@@ -40,9 +40,7 @@ app.$start((instance, initialProps) => {
|
||||
|
||||
# 样式
|
||||
|
||||
标准 Hippy 中长度单位是不允许带有单位的,不过为了和浏览器保持兼容,hippy-vue 采取了 1px = 1pt 的方案进行换算,把 CSS 单位中的 px 直接去掉变成了 Hippy 中不带单位的数字。
|
||||
|
||||
不过依然存在一些问题,类似 rem、vh 这样的相对单位如果写进 Hippy 业务里了,及时发现避免更重要大的风险可能更重要一些,所以现在只转换 px 单位,别的单位任由终端层报错。
|
||||
标准 Hippy 中长度单位是不允许带有单位,不过为了和浏览器保持兼容,hippy-vue 采取了 1px = 1pt 的方案进行换算,把 CSS 单位中的 px 直接去掉变成了 Hippy 中不带单位的数字。
|
||||
|
||||
HippyVue 提供了 `beforeLoadStyle` 的 Vue options 勾子函数,供开发者做定制化修改 CSS 样式,如
|
||||
|
||||
|
||||
@@ -288,7 +288,7 @@ console.log(Vue.Native.getElemCss(this.demon1Point)) // => { height: 80, left: 0
|
||||
|
||||
---
|
||||
|
||||
# ImageLoaderModule
|
||||
# ImageLoader
|
||||
|
||||
通过该模块可以对远程图片进行相应操作
|
||||
|
||||
@@ -296,13 +296,13 @@ console.log(Vue.Native.getElemCss(this.demon1Point)) // => { height: 80, left: 0
|
||||
|
||||
## 方法
|
||||
|
||||
### ImageLoaderModule.getSize
|
||||
### ImageLoader.getSize
|
||||
|
||||
`(url: string) => Promise<{width, height}>` 获取图片大小(会同时预加载图片)。
|
||||
|
||||
> * url - 图片地址
|
||||
|
||||
### ImageLoaderModule.prefetch
|
||||
### ImageLoader.prefetch
|
||||
|
||||
`(url: string) => void` 用于预加载图片。
|
||||
|
||||
@@ -318,7 +318,7 @@ console.log(Vue.Native.getElemCss(this.demon1Point)) // => { height: 80, left: 0
|
||||
|
||||
`(ref) => Promise<{top: number, left: number, right: number, bottom: number, width: number, height: number}>`
|
||||
|
||||
> * Promise resolve 的参数可以获取到引用组件在 App 窗口范围内的坐标值和宽高,如果出错或 [节点被优化(仅在Android)](hippy-vue/components?id=样式内特殊属性) 会返回 { top: -1, left: -1, right: -1, bottom: -1, width: -1, height: -1 }
|
||||
> * Promise resolve 的参数可以获取到引用组件在 App 窗口范围内的坐标值和宽高,如果出错或 [节点被优化(仅在Android)](style/layout?id=collapsable) 会返回 { top: -1, left: -1, right: -1, bottom: -1, width: -1, height: -1 }
|
||||
|
||||
---
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -45,7 +45,7 @@
|
||||
"@babel/polyfill": "^7.12.0",
|
||||
"@babel/preset-env": "^7.12.0",
|
||||
"@babel/preset-react": "^7.9.4",
|
||||
"@hippy/debug-server-next": "^0.3.0",
|
||||
"@hippy/debug-server-next": "^0.3.4",
|
||||
"@hippy/hippy-dynamic-import-plugin": "^2.0.0",
|
||||
"@hippy/hippy-hmr-plugin": "^0.1.0",
|
||||
"@hippy/hippy-react-refresh-webpack-plugin": "^0.5.5",
|
||||
|
||||
+37
-19
@@ -10,7 +10,6 @@ import Style1 from '../../shared/UIStyles/Style1';
|
||||
import Style2 from '../../shared/UIStyles/Style2';
|
||||
import Style5 from '../../shared/UIStyles/Style5';
|
||||
|
||||
const STYLE_LOADING = 100;
|
||||
const MAX_FETCH_TIMES = 50;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
@@ -32,16 +31,23 @@ const styles = StyleSheet.create({
|
||||
alignSelf: 'center',
|
||||
},
|
||||
pullContainer: {
|
||||
height: 60,
|
||||
backgroundColor: 'green',
|
||||
|
||||
flex: 1,
|
||||
height: 50,
|
||||
backgroundColor: '#4c9afa',
|
||||
},
|
||||
pullContent: {
|
||||
lineHeight: 60,
|
||||
lineHeight: 50,
|
||||
color: 'white',
|
||||
height: 60,
|
||||
height: 50,
|
||||
textAlign: 'center',
|
||||
},
|
||||
pullFooter: {
|
||||
height: 40,
|
||||
flex: 1,
|
||||
backgroundColor: '#4c9afa',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -52,7 +58,7 @@ const styles = StyleSheet.create({
|
||||
*
|
||||
* 目前主要用于替换掉 RefreshWrapper 实现更好的下拉功能。
|
||||
*/
|
||||
export default class PullHeaderExample extends React.Component {
|
||||
export default class PullHeaderFooterExample extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@@ -66,6 +72,7 @@ export default class PullHeaderExample extends React.Component {
|
||||
this.getRowType = this.getRowType.bind(this);
|
||||
this.getRowKey = this.getRowKey.bind(this);
|
||||
this.renderPullHeader = this.renderPullHeader.bind(this);
|
||||
this.renderPullFooter = this.renderPullFooter.bind(this);
|
||||
this.onEndReached = this.onEndReached.bind(this);
|
||||
this.onHeaderReleased = this.onHeaderReleased.bind(this);
|
||||
this.onHeaderPulling = this.onHeaderPulling.bind(this);
|
||||
@@ -93,19 +100,21 @@ export default class PullHeaderExample extends React.Component {
|
||||
}
|
||||
this.loadMoreDataFlag = true;
|
||||
this.setState({
|
||||
dataSource: dataSource.concat([{ style: STYLE_LOADING }]),
|
||||
loadingState: '加载更多...',
|
||||
});
|
||||
let newData = [];
|
||||
try {
|
||||
newData = await this.mockFetchData();
|
||||
} catch (err) {}
|
||||
const lastLineItem = dataSource[dataSource.length - 1];
|
||||
if (lastLineItem && lastLineItem.style === STYLE_LOADING) {
|
||||
dataSource.pop();
|
||||
if (newData.length === 0) {
|
||||
this.setState({
|
||||
loadingState: '没有更多数据',
|
||||
});
|
||||
}
|
||||
const newDataSource = dataSource.concat(newData);
|
||||
this.loadMoreDataFlag = false;
|
||||
const newDataSource = [...dataSource, ...newData];
|
||||
this.setState({ dataSource: newDataSource });
|
||||
this.loadMoreDataFlag = false;
|
||||
this.listView.collapsePullFooter();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,7 +214,7 @@ export default class PullHeaderExample extends React.Component {
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 pullHeader 组件,只保留内容即可
|
||||
* 渲染 pullHeader 组件
|
||||
*/
|
||||
renderPullHeader() {
|
||||
const { pullingText } = this.state;
|
||||
@@ -216,13 +225,24 @@ export default class PullHeaderExample extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 pullFooter 组件
|
||||
*/
|
||||
renderPullFooter() {
|
||||
return (<View style={styles.pullFooter} >
|
||||
<Text style={{
|
||||
color: 'white',
|
||||
}}>{this.state.loadingState}</Text>
|
||||
</View>);
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染单个列表行
|
||||
*
|
||||
* @param {number} index - 行索引号
|
||||
*/
|
||||
renderRow(index) {
|
||||
const { dataSource, loadingState } = this.state;
|
||||
const { dataSource } = this.state;
|
||||
let styleUI = null;
|
||||
const rowData = dataSource[index];
|
||||
const isLastItem = dataSource.length === index + 1;
|
||||
@@ -236,9 +256,6 @@ export default class PullHeaderExample extends React.Component {
|
||||
case 5:
|
||||
styleUI = <Style5 itemBean={rowData.itemBean} onClick={event => this.onClickItem(index, event)} />;
|
||||
break;
|
||||
case STYLE_LOADING:
|
||||
styleUI = <Text style={styles.loading}>{loadingState}</Text>;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
return (
|
||||
@@ -272,9 +289,10 @@ export default class PullHeaderExample extends React.Component {
|
||||
getRowKey={this.getRowKey}
|
||||
renderRow={this.renderRow}
|
||||
renderPullHeader={this.renderPullHeader}
|
||||
onEndReached={this.onEndReached}
|
||||
renderPullFooter={this.renderPullFooter}
|
||||
onHeaderReleased={this.onHeaderReleased}
|
||||
onHeaderPulling={this.onHeaderPulling}
|
||||
onFooterReleased={this.onEndReached}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -33,14 +33,13 @@ const styles = StyleSheet.create({
|
||||
alignSelf: 'center',
|
||||
},
|
||||
pullContainer: {
|
||||
height: 60,
|
||||
backgroundColor: 'green',
|
||||
|
||||
height: 50,
|
||||
backgroundColor: '#4c9afa',
|
||||
},
|
||||
pullContent: {
|
||||
lineHeight: 60,
|
||||
lineHeight: 50,
|
||||
color: 'white',
|
||||
height: 60,
|
||||
height: 50,
|
||||
textAlign: 'center',
|
||||
},
|
||||
pullFooter: {
|
||||
@@ -73,17 +72,11 @@ export default class ListExample extends React.Component {
|
||||
this.renderPullFooter = this.renderPullFooter.bind(this);
|
||||
this.renderBanner = this.renderBanner.bind(this);
|
||||
this.getItemStyle = this.getItemStyle.bind(this);
|
||||
// TODO: PullHeader is not supported on Android yet
|
||||
// this.renderPullHeader = this.renderPullHeader.bind(this);
|
||||
// this.onHeaderReleased = this.onHeaderReleased.bind(this);
|
||||
// this.onHeaderPulling = this.onHeaderPulling.bind(this);
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const dataSource = await this.mockFetchData();
|
||||
this.setState({ dataSource });
|
||||
// 结束时需主动调用collapsePullHeader
|
||||
// this.listView.collapsePullHeader();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,62 +108,6 @@ export default class ListExample extends React.Component {
|
||||
this.loadMoreDataFlag = false;
|
||||
}
|
||||
|
||||
// TODO: PullHeader is not supported on Android yet
|
||||
// 下拉超过内容高度,松手后触发
|
||||
// async onHeaderReleased() {
|
||||
// if (this.fetchingDataFlag) {
|
||||
// return;
|
||||
// }
|
||||
// this.fetchingDataFlag = true;
|
||||
// // eslint-disable-next-line no-console
|
||||
// console.log('onHeaderReleased');
|
||||
// this.setState({
|
||||
// pullingText: '刷新数据中,请稍等,2秒后自动收起',
|
||||
// });
|
||||
// let dataSource = [];
|
||||
// try {
|
||||
// dataSource = await this.mockFetchData();
|
||||
// } catch (err) {}
|
||||
// this.fetchingDataFlag = false;
|
||||
// this.setState({ dataSource }, () => {
|
||||
// // 要主动调用collapsePullHeader关闭pullHeader,否则可能会导致onHeaderReleased事件不能再次触发
|
||||
// this.listView.collapsePullHeader();
|
||||
// });
|
||||
// }
|
||||
|
||||
// 渲染 pullHeader 组件,只保留内容即可
|
||||
// renderPullHeader() {
|
||||
// const { pullingText } = this.state;
|
||||
// return (
|
||||
// <View style={styles.pullContainer}>
|
||||
// <Text style={styles.pullContent}>{ pullingText }</Text>
|
||||
// </View>
|
||||
// );
|
||||
// }
|
||||
|
||||
/**
|
||||
* 下拉过程中触发
|
||||
* 事件会通过 contentOffset 参数返回拖拽高度,我们已经知道了内容高度,
|
||||
* 简单对比一下就可以显示不同的状态。
|
||||
* 这里简单处理,其实可以做到更复杂的动态效果。
|
||||
*/
|
||||
// onHeaderPulling(evt) {
|
||||
// if (this.fetchingDataFlag) {
|
||||
// return;
|
||||
// }
|
||||
// // eslint-disable-next-line no-console
|
||||
// console.log('onHeaderPulling', evt.contentOffset);
|
||||
// if (evt.contentOffset > styles.pullContent.height) {
|
||||
// this.setState({
|
||||
// pullingText: '松手,即可触发刷新',
|
||||
// });
|
||||
// } else {
|
||||
// this.setState({
|
||||
// pullingText: '继续下拉,触发刷新',
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
renderPullFooter() {
|
||||
if (this.state.dataSource.length === 0) return null;
|
||||
return (<View style={styles.pullFooter}>
|
||||
@@ -323,9 +260,6 @@ export default class ListExample extends React.Component {
|
||||
contentInset={contentInset}
|
||||
getItemStyle={this.getItemStyle}
|
||||
containPullFooter={true}
|
||||
// renderPullHeader={this.renderPullHeader}
|
||||
// onHeaderReleased={this.onHeaderReleased}
|
||||
// onHeaderPulling={this.onHeaderPulling}
|
||||
renderPullFooter={this.renderPullFooter}
|
||||
/>
|
||||
</RefreshWrapper>
|
||||
|
||||
@@ -5,7 +5,7 @@ export { default as Image } from './Image';
|
||||
export { default as ListView } from './ListView';
|
||||
export { default as Modal } from './Modal';
|
||||
export { default as RefreshWrapper } from './RefreshWrapper';
|
||||
export { default as PullHeader } from './PullHeader';
|
||||
export { default as PullHeaderFooter } from './PullHeaderFooter';
|
||||
export { default as ScrollView } from './ScrollView';
|
||||
export { default as Text } from './Text';
|
||||
export { default as TextInput } from './TextInput';
|
||||
|
||||
@@ -67,8 +67,8 @@ export default [
|
||||
},
|
||||
{
|
||||
path: '/PullHeader',
|
||||
name: 'PullHeader 组件',
|
||||
component: PAGE_LIST.PullHeader,
|
||||
name: 'PullHeader/Footer组件',
|
||||
component: PAGE_LIST.PullHeaderFooter,
|
||||
meta: {
|
||||
style: 1,
|
||||
},
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
"@babel/plugin-transform-runtime": "^7.11.0",
|
||||
"@babel/polyfill": "^7.12.0",
|
||||
"@babel/preset-env": "^7.12.0",
|
||||
"@hippy/debug-server-next": "^0.3.0",
|
||||
"@hippy/debug-server-next": "^0.3.4",
|
||||
"@hippy/hippy-dynamic-import-plugin": "^2.0.0",
|
||||
"@hippy/hippy-hmr-plugin": "^0.1.0",
|
||||
"@hippy/vue-css-loader": "^2.0.1",
|
||||
|
||||
@@ -251,8 +251,10 @@ export default {
|
||||
#demo-list .style-two-image {
|
||||
height: 140px;
|
||||
}
|
||||
.item-style {
|
||||
#demo-list .item-style {
|
||||
background-color: white;
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
/*width: 100px;*/ /* configure li style if horizontal ul is set*/
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -11,7 +11,7 @@ export default Vue.component('StyleOne', {
|
||||
<div class="style-one-image-container">
|
||||
<img v-for="(pic, index) in itemBean.picList" :key="index" :src="pic" class="image style-one-image" />
|
||||
</div>
|
||||
<div class="tag-line">
|
||||
<div :style="{ alignSelf: 'flex-start', marginTop: '5px' }">
|
||||
<p class="normal-text">
|
||||
{{ itemBean.subInfo.join('') }}
|
||||
</p>
|
||||
|
||||
@@ -9,7 +9,7 @@ export default Vue.component('StyleTwo', {
|
||||
<p class="article-title" :numberOfLines="2" :enableScale="true">
|
||||
{{ itemBean.title }}
|
||||
</p>
|
||||
<div class="tag-line">
|
||||
<div :style="{ alignSelf: 'flex-start', marginTop: '5px' }">
|
||||
<p class="normal-text">
|
||||
{{ itemBean.subInfo.join('') }}
|
||||
</p>
|
||||
|
||||
@@ -11,7 +11,7 @@ export default Vue.component('StyleFive', {
|
||||
<div class="style-five-image-container">
|
||||
<img :src="itemBean.picUrl" class="image" />
|
||||
</div>
|
||||
<div class="tag-line">
|
||||
<div :style="{ alignSelf: 'flex-start', marginTop: '5px' }">
|
||||
<p class="normal-text">
|
||||
{{ itemBean.subInfo.join(' ') }}
|
||||
</p>
|
||||
|
||||
@@ -28,18 +28,19 @@
|
||||
<li
|
||||
v-for="(ui, index) in dataSource"
|
||||
:key="index"
|
||||
class="item-style"
|
||||
:type="'row-' + ui.style"
|
||||
>
|
||||
<style-one
|
||||
v-if="ui.style == 1"
|
||||
v-if="ui.style === 1"
|
||||
:item-bean="ui.itemBean"
|
||||
/>
|
||||
<style-two
|
||||
v-if="ui.style == 2"
|
||||
v-if="ui.style === 2"
|
||||
:item-bean="ui.itemBean"
|
||||
/>
|
||||
<style-five
|
||||
v-if="ui.style == 5"
|
||||
v-if="ui.style === 5"
|
||||
:item-bean="ui.itemBean"
|
||||
/>
|
||||
</li>
|
||||
@@ -260,4 +261,11 @@ export default {
|
||||
#demo-pull-footer .style-two-image {
|
||||
height: 140px;
|
||||
}
|
||||
|
||||
#demo-pull-footer .item-style {
|
||||
background-color: white;
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -48,18 +48,19 @@
|
||||
<li
|
||||
v-for="(ui, index) in dataSource"
|
||||
:key="index"
|
||||
class="item-style"
|
||||
:type="'row-' + ui.style"
|
||||
>
|
||||
<style-one
|
||||
v-if="ui.style == 1"
|
||||
v-if="ui.style === 1"
|
||||
:item-bean="ui.itemBean"
|
||||
/>
|
||||
<style-two
|
||||
v-if="ui.style == 2"
|
||||
v-if="ui.style === 2"
|
||||
:item-bean="ui.itemBean"
|
||||
/>
|
||||
<style-five
|
||||
v-if="ui.style == 5"
|
||||
v-if="ui.style === 5"
|
||||
:item-bean="ui.itemBean"
|
||||
/>
|
||||
</li>
|
||||
@@ -277,4 +278,11 @@ export default {
|
||||
#demo-pull-header .style-two-image {
|
||||
height: 140px;
|
||||
}
|
||||
|
||||
#demo-pull-header .item-style {
|
||||
background-color: white;
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -45,10 +45,6 @@ interface PullFooterProps extends LayoutableProps {
|
||||
}
|
||||
|
||||
class PullFooter extends React.Component<PullFooterProps, {}> {
|
||||
private static defaultProps = {
|
||||
sticky: true,
|
||||
};
|
||||
|
||||
private instance: Element | Fiber | HTMLDivElement | null = null;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user