提交 3ffd0037 编写于 作者: DCloud-yyl's avatar DCloud-yyl

Merge branch 'dev' into alpha

......@@ -55,29 +55,29 @@
console.log(action);
switch (action) {
case 'switchTab':
uni.switchTab({
uni.webView.switchTab({
url: '/pages/tabBar/API'
});
break;
case 'reLaunch':
uni.reLaunch({
uni.webView.reLaunch({
url: '/pages/tabBar/component'
});
break;
case 'navigateBack':
uni.navigateBack({
uni.webView.navigateBack({
delta: 1
});
break;
case 'getEnv':
uni.getEnv((res) => {
uni.webView.getEnv((res) => {
uni.postMessage({
data: res
})
});
break;
default:
uni[action]({
uni.webView[action]({
url: '/pages/component/button/button'
});
break;
......@@ -86,7 +86,7 @@
})
// });
document.querySelector("#postMessage").addEventListener('click', function() {
uni.postMessage({
uni.webView.postMessage({
data: {
action: 'message'
}
......
......@@ -14,12 +14,6 @@
"navigationBarTitleText": "view"
}
},
{
"path": "pages/component/view/view-draw",
"style": {
"navigationBarTitleText": "DrawableContext"
}
},
{
"path": "pages/component/scroll-view/scroll-view",
"style": {
......@@ -199,6 +193,32 @@
"style": {
"navigationBarTitleText": "general-event"
}
},
{
"path": "pages/component/unicloud-db-contacts/list",
"style": {
"navigationBarTitleText": "联系人",
"enablePullDownRefresh": true
}
},
{
"path": "pages/component/unicloud-db-contacts/add",
"style": {
"navigationBarTitleText": "新增联系人"
}
},
{
"path": "pages/component/unicloud-db-contacts/edit",
"style": {
"navigationBarTitleText": "编辑联系人",
"navigationStyle": "custom"
}
},
{
"path": "pages/component/unicloud-db-contacts/detail",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/tabBar/API",
......@@ -844,7 +864,7 @@
{
"path": "pages/template/scroll-sticky/scroll-sticky",
"style": {
"navigationBarTitleText": "滚动吸顶"
"navigationBarTitleText": "scroll-view自定义滚动吸顶"
}
},
{
......@@ -958,7 +978,31 @@
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}
},
{
"path": "pages/component/sticky-header/sticky-header",
"style": {
"navigationBarTitleText": "sticky-header",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/API/element-takesnapshot/element-takesnapshot",
"style" :
{
"navigationBarTitleText" : "takeSnapshot",
"enablePullDownRefresh" : false
}
},
{
"path" : "pages/API/element-draw/element-draw",
"style" :
{
"navigationBarTitleText" : "getDrawableContext",
"enablePullDownRefresh" : false
}
}
],
"globalStyle": {
"pageOrientation": "portrait",
......@@ -1009,4 +1053,4 @@
"query": "" //启动参数,在页面的onLoad函数里面得到
}]
}
}
\ No newline at end of file
}
......@@ -3,14 +3,14 @@
<scroll-view style="flex: 1">
<!-- #endif -->
<view>
<view ref="draw-text-view" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view ref="draw-line-view" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view ref="draw-circle-view" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view ref="draw-dash-line" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view ref="draw-house" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view ref="draw-style" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view ref="draw-odd" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view ref="draw-arcto" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view id="draw-text-view" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view id="draw-line-view" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view id="draw-circle-view" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view id="draw-dash-line" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view id="draw-house" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view id="draw-style" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view id="draw-odd" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view id="draw-arcto" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
</view>
<!-- #ifdef APP -->
</scroll-view>
......@@ -57,68 +57,68 @@
},
methods: {
drawText() {
let element = (this.$refs['draw-text-view'] as Element)
let ctx = element.getDrawableContext()
let element = uni.getElementById('draw-text-view')
let ctx = element!.getDrawableContext()
let width = element.getBoundingClientRect().width
ctx!!.reset()
ctx!!.font = "15px"
ctx!.textAlign = "center"
ctx!.reset()
ctx.font = "15px"
ctx.textAlign = "center"
for (var i = 0; i < this.texts.length; i++) {
let value = this.texts[i]
if (i % 2 == 0) {
ctx!!.fillText(value, width / 2, (20 * (i + 1)))
ctx.fillText(value, width / 2, (20 * (i + 1)))
} else {
ctx!!.strokeText(value, width / 2, (20 * (i + 1)))
ctx.strokeText(value, width / 2, (20 * (i + 1)))
}
}
ctx!!.update()
ctx.update()
},
drawLines() {
let ctx = (this.$refs['draw-line-view'] as Element).getDrawableContext()
ctx!!.reset()
ctx!!.lineWidth = 10;
let ctx = uni.getElementById('draw-line-view')!.getDrawableContext()
ctx!.reset()
ctx.lineWidth = 10;
["round", "bevel", "miter"].forEach((join, i) => {
ctx!.lineJoin = join;
ctx!.beginPath();
ctx!.moveTo(5, 10 + i * 40);
ctx!.lineTo(50, 50 + i * 40);
ctx!.lineTo(90, 10 + i * 40);
ctx!.lineTo(130, 50 + i * 40);
ctx!.lineTo(170, 10 + i * 40);
ctx!.stroke();
ctx.lineJoin = join;
ctx.beginPath();
ctx.moveTo(5, 10 + i * 40);
ctx.lineTo(50, 50 + i * 40);
ctx.lineTo(90, 10 + i * 40);
ctx.lineTo(130, 50 + i * 40);
ctx.lineTo(170, 10 + i * 40);
ctx.stroke();
});
ctx!!.lineWidth = 1
ctx.lineWidth = 1
var space = 170
ctx!.strokeStyle = '#09f';
ctx!.beginPath();
ctx!.moveTo(10 + space, 10);
ctx!.lineTo(140 + space, 10);
ctx!.moveTo(10 + space, 140);
ctx!.lineTo(140 + space, 140);
ctx!.stroke();
ctx.strokeStyle = '#09f';
ctx.beginPath();
ctx.moveTo(10 + space, 10);
ctx.lineTo(140 + space, 10);
ctx.moveTo(10 + space, 140);
ctx.lineTo(140 + space, 140);
ctx.stroke();
// Draw lines
ctx!.strokeStyle = 'black';
ctx.strokeStyle = 'black';
['butt', 'round', 'square'].forEach((lineCap, i) => {
ctx!.lineWidth = 15;
ctx!.lineCap = lineCap;
ctx!.beginPath();
ctx!.moveTo(25 + space + i * 50, 10);
ctx!.lineTo(25 + space + i * 50, 140);
ctx!.stroke();
ctx.lineWidth = 15;
ctx.lineCap = lineCap;
ctx.beginPath();
ctx.moveTo(25 + space + i * 50, 10);
ctx.lineTo(25 + space + i * 50, 140);
ctx.stroke();
});
ctx!.lineWidth = 1;
this.drawDashedLine([], ctx!);
this.drawDashedLine([2, 2], ctx!);
this.drawDashedLine([10, 10], ctx!);
this.drawDashedLine([20, 5], ctx!);
this.drawDashedLine([15, 3, 3, 3], ctx!);
this.drawDashedLine([20, 3, 3, 3, 3, 3, 3, 3], ctx!);
ctx!.lineDashOffset = 18;
this.drawDashedLine([12, 3, 3], ctx!);
ctx!.lineDashOffset = 0
ctx!.setLineDash([0])
ctx!!.update()
ctx.lineWidth = 1;
this.drawDashedLine([], ctx);
this.drawDashedLine([2, 2], ctx);
this.drawDashedLine([10, 10], ctx);
this.drawDashedLine([20, 5], ctx);
this.drawDashedLine([15, 3, 3, 3], ctx);
this.drawDashedLine([20, 3, 3, 3, 3, 3, 3, 3], ctx);
ctx.lineDashOffset = 18;
this.drawDashedLine([12, 3, 3], ctx);
ctx.lineDashOffset = 0
ctx.setLineDash([0])
ctx.update()
},
drawDashedLine(pattern : Array<number>, ctx : DrawableContext) {
ctx.beginPath();
......@@ -129,12 +129,12 @@
y += 15;
},
drawCircles() {
let ctx = (this.$refs['draw-circle-view'] as Element).getDrawableContext()
ctx!!.reset()
let ctx = uni.getElementById('draw-circle-view')!.getDrawableContext()
ctx!.reset()
// Draw shapes
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 3; j++) {
ctx!!.beginPath();
ctx.beginPath();
var x = 25 + j * 50; // x coordinate
var y = 25 + i * 50; // y coordinate
var radius = 20; // Arc radius
......@@ -142,22 +142,22 @@
var endAngle = Math.PI + (Math.PI * j) / 2; // End point on circle
var clockwise = i % 2 == 0 ? false : true; // clockwise or anticlockwise
ctx!.arc(x, y, radius, startAngle, endAngle, clockwise);
ctx.arc(x, y, radius, startAngle, endAngle, clockwise);
if (i > 1) {
ctx!.fill();
ctx.fill();
} else {
ctx!.stroke();
ctx.stroke();
}
}
}
ctx!!.update()
ctx.update()
},
drawStar() {
let ctx = (this.$refs['draw-dash-line'] as Element).getDrawableContext()
ctx!!.reset()
ctx!!.beginPath();
let ctx = uni.getElementById('draw-dash-line')!.getDrawableContext()
ctx!.reset()
ctx.beginPath();
var horn = 5; // 画5个角
var angle = 360 / horn; // 五个角的度数
// 两个圆的半径
......@@ -169,45 +169,45 @@
for (var i = 0; i < horn; i++) {
// 角度转弧度:角度/180*Math.PI
// 外圆顶点坐标
ctx!.lineTo(Math.cos((18 + i * angle) / 180.0 * Math.PI) * R + x, -Math.sin((18 + i * angle) / 180.0 * Math.PI) * R + y);
ctx.lineTo(Math.cos((18 + i * angle) / 180.0 * Math.PI) * R + x, -Math.sin((18 + i * angle) / 180.0 * Math.PI) * R + y);
// 內圆顶点坐标
ctx!.lineTo(Math.cos((54 + i * angle) / 180.0 * Math.PI) * r + x, -Math.sin((54 + i * angle) / 180.0 * Math.PI) * r + y);
ctx.lineTo(Math.cos((54 + i * angle) / 180.0 * Math.PI) * r + x, -Math.sin((54 + i * angle) / 180.0 * Math.PI) * r + y);
}
// closePath:关闭路径,将路径的终点与起点相连
ctx!.closePath();
ctx!.lineWidth = 3;
ctx!.fillStyle = '#E4EF00';
ctx!.strokeStyle = "red";
ctx!.fill();
ctx!.stroke();
ctx.closePath();
ctx.lineWidth = 3;
ctx.fillStyle = '#E4EF00';
ctx.strokeStyle = "red";
ctx.fill();
ctx.stroke();
ctx!.lineWidth = 10;
ctx!.beginPath()
ctx!.moveTo(170, 100)
ctx!.lineTo(255, 15)
ctx!.lineTo(340, 100)
ctx!.closePath()
ctx!.fill()
ctx!.strokeStyle = "blue"
ctx!.stroke()
ctx!.beginPath()
ctx!.moveTo(170, 145)
ctx!.lineTo(255, 45)
ctx!.lineTo(340, 145)
ctx!.closePath()
ctx!.fill()
ctx!.strokeStyle = "gray"
ctx!.stroke()
ctx.lineWidth = 10;
ctx.beginPath()
ctx.moveTo(170, 100)
ctx.lineTo(255, 15)
ctx.lineTo(340, 100)
ctx.closePath()
ctx.fill()
ctx.strokeStyle = "blue"
ctx.stroke()
ctx.beginPath()
ctx.moveTo(170, 145)
ctx.lineTo(255, 45)
ctx.lineTo(340, 145)
ctx.closePath()
ctx.fill()
ctx.strokeStyle = "gray"
ctx.stroke()
// 未设置beginPath,导致上下表现一致,与前端一致
ctx!.moveTo(170, 190)
ctx!.lineTo(255, 90)
ctx!.lineTo(340, 190)
ctx!.closePath()
ctx!.fillStyle = "orange"
ctx!.fill()
ctx!.strokeStyle = "khaki"
ctx!.stroke()
ctx!!.update()
ctx.moveTo(170, 190)
ctx.lineTo(255, 90)
ctx.lineTo(340, 190)
ctx.closePath()
ctx.fillStyle = "orange"
ctx.fill()
ctx.strokeStyle = "khaki"
ctx.stroke()
ctx.update()
},
hex(num : number) : string {
if (num == 0) {
......@@ -226,82 +226,82 @@
return result
},
drawhouse() {
let ctx = (this.$refs['draw-house'] as Element).getDrawableContext()
ctx!!.reset()
ctx!!.lineWidth = 10;
let ctx = uni.getElementById('draw-house')!.getDrawableContext()
ctx!.reset()
ctx.lineWidth = 10;
// Wall
ctx!.strokeRect(75, 140, 150, 110);
ctx.strokeRect(75, 140, 150, 110);
// Door
ctx!.fillRect(130, 190, 40, 60);
ctx.fillRect(130, 190, 40, 60);
// Roof
ctx!.beginPath();
ctx!.moveTo(50, 140);
ctx!.lineTo(150, 60);
ctx!.lineTo(250, 140);
ctx!.closePath();
ctx!.stroke();
ctx!!.update()
ctx.beginPath();
ctx.moveTo(50, 140);
ctx.lineTo(150, 60);
ctx.lineTo(250, 140);
ctx.closePath();
ctx.stroke();
ctx.update()
},
drawPoint() {
let ctx = (this.$refs['draw-style'] as Element).getDrawableContext()
ctx!!.reset()
let ctx = uni.getElementById('draw-style')!.getDrawableContext()
ctx!.reset()
for (let i = 0; i < 6; i++) {
for (let j = 0; j < 6; j++) {
ctx!!.strokeStyle = `rgb(0,${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)})`;
ctx!.beginPath();
ctx!.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true);
ctx!.stroke();
ctx.strokeStyle = `rgb(0,${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)})`;
ctx.beginPath();
ctx.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true);
ctx.stroke();
}
}
for (let i = 0; i < 6; i++) {
for (let j = 0; j < 6; j++) {
ctx!!.fillStyle = `rgb(${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)},0)`;
ctx!.fillRect(180 + j * 25, i * 25, 25, 25);
ctx.fillStyle = `rgb(${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)},0)`;
ctx.fillRect(180 + j * 25, i * 25, 25, 25);
}
}
ctx!!.update()
ctx.update()
},
drawRect() {
let ctx = (this.$refs['draw-odd'] as Element).getDrawableContext()
ctx!!.reset()
let ctx = uni.getElementById('draw-odd')!.getDrawableContext()
ctx!.reset()
// Create path
ctx!!.moveTo(30, 90);
ctx!.lineTo(110, 20);
ctx!.lineTo(240, 130);
ctx!.lineTo(60, 130);
ctx!.lineTo(190, 20);
ctx!.lineTo(270, 90);
ctx!.closePath();
ctx.moveTo(30, 90);
ctx.lineTo(110, 20);
ctx.lineTo(240, 130);
ctx.lineTo(60, 130);
ctx.lineTo(190, 20);
ctx.lineTo(270, 90);
ctx.closePath();
// Fill path
ctx!.fillStyle = "green";
ctx!.fill("evenodd");
ctx!!.update()
ctx.fillStyle = "green";
ctx.fill("evenodd");
ctx.update()
},
drawArcTo() {
let ctx = (this.$refs['draw-arcto'] as Element).getDrawableContext()
let ctx = uni.getElementById('draw-arcto')!.getDrawableContext()
ctx!.reset()
ctx!.beginPath();
ctx!.moveTo(50, 20);
ctx!.bezierCurveTo(230, 30, 150, 60, 50, 100);
ctx!.stroke();
ctx.beginPath();
ctx.moveTo(50, 20);
ctx.bezierCurveTo(230, 30, 150, 60, 50, 100);
ctx.stroke();
ctx!.fillStyle = "blue";
ctx.fillStyle = "blue";
// start point
ctx!.fillRect(50, 20, 10, 10);
ctx.fillRect(50, 20, 10, 10);
// end point
ctx!.fillRect(50, 100, 10, 10);
ctx.fillRect(50, 100, 10, 10);
ctx!.fillStyle = "red";
ctx.fillStyle = "red";
// control point one
ctx!.fillRect(230, 30, 10, 10);
ctx.fillRect(230, 30, 10, 10);
// control point two
ctx!.fillRect(150, 70, 10, 10);
ctx!.update()
ctx.fillRect(150, 70, 10, 10);
ctx.update()
}
}
}
......
const PAGE_PATH = "/pages/API/element-takesnapshot/element-takesnapshot";
describe("element-takesnapshot", () => {
let page;
function getData(key = '') {
return new Promise(async (resolve, reject) => {
const data = await page.data()
resolve(key ? data[key] : data)
})
}
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
await page.waitFor(600);
});
it("takeSnapshot", async () => {
await page.waitFor(600)
let btnTakeSnapshot = await page.$('.btn-TakeSnapshot')
await btnTakeSnapshot.tap()
page.waitFor(600)
const image = await getData('snapImage')
console.log(image)
///storage/emulated/0/Android/data/io.dcloud.uniappx/apps/__UNI__3584C99/cache/temp/screenshot/1697513148915.png
expect(image.length).toBeGreaterThan(20)
});
});
<template>
<view>
<page-head id="page-head" title="getElementById"></page-head>
<view class="uni-padding-wrap" id="snapshot-content">
<text id="text">this is text</text>
<view id="view" class="uni-common-mt" style="border: 1px solid red">this is view</view>
</view>
<button class="uni-btn" @click="changeViewStyle">
修改 view 宽高及背景色
</button>
<button class="uni-btn btn-TakeSnapshot" type="primary" @tap="takeSnapshotClick">
点击截图
</button>
<image style="margin-top: 20px;" :src="snapImage" mode="aspectFit" @longpress="saveToAlbum"></image>
</view>
</template>
<script lang="uts">
export default {
data() {
return {
snapImage: "/static/uni.png"
}
},
methods: {
changeViewStyle() {
const text = uni.getElementById('text')!
text.style.setProperty('color', 'red')
const view = uni.getElementById('view')!
view.style.setProperty('width', '90%')
view.style.setProperty('height', '50px')
view.style.setProperty('backgroundColor', '#007AFF')
},
takeSnapshotClick() {
const view = uni.getElementById('snapshot-content')!
view.takeSnapshot({
success: function (res) {
console.log(res.tempFilePath)
this.snapImage = res.tempFilePath
uni.showToast({
title: '截图成功,路径:' + res.tempFilePath,
icon: "none"
})
},
fail: function (res) {
console.log(res)
uni.showToast({
icon: 'error',
title: '截图失败'
})
}
})
},
saveToAlbum(e : TouchEvent) {
// console.log(e.currentTarget!.getAttribute("src"));
let filePath : string = e.currentTarget!.getAttribute("src") as string
uni.showActionSheet({
itemList: ["保存"],
success: res => {
// console.log(res.tapIndex);
if (res.tapIndex == 0) {
uni.saveImageToPhotosAlbum({
filePath: filePath,
success() {
uni.showToast({
position: "center",
icon: "none",
title: "图片保存成功,请到手机相册查看"
})
},
fail(e) {
uni.showModal({
content: "保存相册失败,errCode:" + e.errCode + ",errMsg:" + e.errMsg + ",errSubject:" + e.errSubject,
showCancel: false
});
}
})
}
},
fail: () => { },
complete: () => { }
});
}
}
}
</script>
......@@ -18,7 +18,11 @@
scrollData: [] as Array<string>,
size_enum: [{ "value": 0, "name": "item---0" }, { "value": 3, "name": "item---3" }] as ItemType[],
scrollIntoView: "",
refresherrefresh: false
refresherrefresh: false,
refresher_default_style_input: "black",
text: ['继续下拉执行刷新', '释放立即刷新', '刷新中', ""],
state: 3,
reset: true
}
},
onLoad() {
......@@ -36,17 +40,30 @@
list_view_touchend() { console.log("手指触摸动作结束") },
list_view_tap() { console.log("手指触摸后马上离开") },
list_view_longpress() { console.log("如果一个组件被绑定了 longpress 事件,那么当用户长按这个组件时,该事件将会被触发。") },
list_view_refresherpulling() { console.log("下拉刷新控件被下拉") },
list_view_refresherpulling(e : RefresherEvent) {
console.log("下拉刷新控件被下拉")
if(this.reset) {
if(e.detail.dy > 45) {
this.state = 1
} else {
this.state = 0
}
}
},
list_view_refresherrefresh() {
console.log("下拉刷新被触发 ")
this.refresherrefresh = true
this.refresher_triggered_boolean = true
this.state = 2
this.reset = false;
setTimeout(function(){
this.refresher_triggered_boolean = false
}, 1500)
},
list_view_refresherrestore() {
this.refresherrefresh = false
this.state = 3
this.reset = true
console.log("下拉刷新被复位")
},
list_view_refresherabort() { console.log("下拉刷新被中止") },
......@@ -90,6 +107,13 @@
return true
}
return false
},
change_refresher_style_boolean(checked : boolean) {
if(checked) {
this.refresher_default_style_input = "none"
} else {
this.refresher_default_style_input = "black"
}
}
}
}
......@@ -102,6 +126,7 @@
:scroll-left="scroll_left_input" :show-scrollbar="show_scrollbar_boolean" :scroll-into-view="scrollIntoView"
:scroll-with-animation="scroll_with_animation_boolean" :refresher-enabled="refresher_enabled_boolean"
:refresher-background="refresher_background_input" :refresher-triggered="refresher_triggered_boolean"
:refresher-default-style="refresher_default_style_input"
@click="list_view_click" @touchstart="list_view_touchstart" @touchmove="list_view_touchmove"
@touchcancel="list_view_touchcancel" @touchend="list_view_touchend" @tap="list_view_tap"
@longpress="list_view_longpress" @refresherpulling="list_view_refresherpulling"
......@@ -115,6 +140,9 @@
class="list-item">
<text>{{key}}</text>
</list-item>
<list-item slot="refresher" class="refresh-box">
<text class="tip-text">{{text[state]}}</text>
</list-item>
</list-view>
</view>
......@@ -125,6 +153,7 @@
<boolean-data :defaultValue="false" title="设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发"
@change="change_refresher_triggered_boolean"></boolean-data>
<boolean-data :defaultValue="false" title="开启下拉刷新" @change="change_refresher_enabled_boolean"></boolean-data>
<boolean-data :defaultValue="false" title="开启自定义样式" @change="change_refresher_style_boolean"></boolean-data>
<boolean-data :defaultValue="false" title="是否在设置滚动条位置时使用滚动动画,设置false没有滚动动画"
@change="change_scroll_with_animation_boolean"></boolean-data>
<boolean-data :defaultValue="true" title="控制是否出现滚动条" @change="change_show_scrollbar_boolean"></boolean-data>
......@@ -163,4 +192,17 @@
align-items: center;
justify-content: center;
}
.tip-text {
color: #888;
font-size: 12px;
}
.refresh-box {
justify-content: center;
align-items: center;
flex-direction: row;
height: 45px;
width: 100%;
}
</style>
......@@ -45,16 +45,16 @@
// this.sliderValue = value
// TODO 跳过vue框架,直接修改原生组件
(this.$refs["slider1"]! as SliderElement[]).forEach((item) => {
(this.$refs["slider1"]! as UniSliderElement[]).forEach((item) => {
item.value = value
});
(this.$refs["slider2"]! as SliderElement[]).forEach((item) => {
(this.$refs["slider2"]! as UniSliderElement[]).forEach((item) => {
item.value = value
});
(this.$refs["slider3"]! as SliderElement[]).forEach((item) => {
(this.$refs["slider3"]! as UniSliderElement[]).forEach((item) => {
item.value = value
});
(this.$refs["slider4"]! as SliderElement[]).forEach((item) => {
(this.$refs["slider4"]! as UniSliderElement[]).forEach((item) => {
item.value = value
});
}
......
describe('component-native-sticky-header', () => {
let page
beforeAll(async () => {
page = await program.reLaunch('/pages/component/sticky-header/sticky-header')
await page.waitFor(200)
})
//检测吸顶效果
it('check_sticky_header', async () => {
await page.callMethod('confirm_scroll_top_input', 600)
await page.waitFor(400)
const image = await program.screenshot();
expect(image).toMatchImageSnapshot();
})
})
<template>
<list-view :scroll-y="true" class="page" rebound="false" :scroll-top="scroll_top_input" :refresher-enabled="refresher_enabled_boolean"
:refresher-triggered="refresher_triggered_boolean" @refresherrefresh="list_view_refresherrefresh">
<list-item type = 1>
<swiper indicator-dots="true" circular="true">
<swiper-item v-for="i in 3" :item-id="i">
<image src="/static/shuijiao.jpg" style="height: 240px;"></image>
<text style="position: absolute;">{{i}}</text>
</swiper-item>
</swiper>
</list-item>
<list-item class="content-item" type = 2>
<text class="text">向上滑动页面,体验sticky-header吸顶效果。</text>
</list-item>
<sticky-header>
<scroll-view style="background-color: #f5f5f5; flex-direction: row;" :scroll-x="true" :scroll-y="false" :show-scrollbar="false">
<view class="flex-row" style="align-self: flex-start; flex-direction: row;">
<text ref="swipertab" class="sift-item"
v-for="(name,index) in sift_item" @click="clickTH(index)">
{{name}}
</text>
</view>
</scroll-view>
</sticky-header>
<list-item v-for="(item,index) in list_item" :key="index" class="content-item" type = 3>
<text class="text">{{item}}</text>
</list-item>
</list-view>
</template>
<script>
export default {
data() {
return {
sift_item: ["排序", "筛选"],
list_item: [] as Array<string>,
refresher_enabled_boolean: true,
refresher_triggered_boolean: false,
scroll_top_input: 0
}
},
onLoad() {
let lists : Array<string> = []
for (let i = 0; i < 40; i++) {
lists.push("item---" + i)
}
this.list_item = lists
},
methods: {
list_view_refresherrefresh() {
console.log("下拉刷新被触发 ")
this.refresher_triggered_boolean = true
setTimeout(function(){
this.refresher_triggered_boolean = false
}, 1500)
},
confirm_scroll_top_input(value : number) {
this.scroll_top_input = value
},
clickTH(index:number){
console.log("点击表头:" + index);
}
}
}
</script>
<style>
.page {
flex: 1;
background-color: #f5f5f5;
}
.content-item {
padding: 15px;
margin: 5px 0;
background-color: #fff;
}
.text {
font-size: 14px;
color: #666;
line-height: 20px;
}
.sift-item {
color: #555;
font-size: 16px;
padding: 12px 15px;
}
</style>
<template>
<view>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="text-box" scroll-y="true">
<text class="text">{{text}}</text>
</view>
<view class="uni-btn-v">
<button class="uni-btn" type="primary" :disabled="!canAdd" @click="add">add line</button>
<button class="uni-btn" type="warn" :disabled="!canRemove" @click="remove">remove line</button>
<button class="uni-btn" type="primary" @click="textProps">更多属性示例</button>
</view>
</view>
<view>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="text-box" scroll-y="true">
<text class="text">{{ text }}</text>
</view>
<view class="uni-btn-v">
<button class="uni-btn" type="primary" :disabled="!canAdd" @click="add">
add line
</button>
<button
class="uni-btn"
type="warn"
:disabled="!canRemove"
@click="remove"
>
remove line
</button>
<button class="uni-btn" type="primary" @click="textProps">
更多属性示例
</button>
</view>
</view>
</view>
</template>
<script lang="uts">
export default {
data() {
return {
title: 'text',
texts: [
'HBuilderX,轻巧、极速,极客编辑器',
'uni-app x,终极跨平台方案',
'uniCloud,js serverless云服务',
'uts,大一统语言',
'uniMPSdk,让你的App具备小程序能力',
'uni-admin,开源、现成的全端管理后台',
'uni-id,开源、全端的账户中心',
'uni-pay,开源、云端一体、全平台的支付',
'uni-ai,聚合ai能力',
'uni-cms,开源、云端一体、全平台的内容管理平台',
'uni-im,开源、云端一体、全平台的im即时消息',
'uni统计,开源、完善、全平台的统计报表',
'......'
] as string[],
text: '',
canAdd: true,
canRemove: false,
extraLine: [] as string[]
}
export default {
data() {
return {
title: 'text',
texts: [
'HBuilderX,轻巧、极速,极客编辑器',
'uni-app x,终极跨平台方案',
'uniCloud,js serverless云服务',
'uts,大一统语言',
'uniMPSdk,让你的App具备小程序能力',
'uni-admin,开源、现成的全端管理后台',
'uni-id,开源、全端的账户中心',
'uni-pay,开源、云端一体、全平台的支付',
'uni-ai,聚合ai能力',
'uni-cms,开源、云端一体、全平台的内容管理平台',
'uni-im,开源、云端一体、全平台的im即时消息',
'uni统计,开源、完善、全平台的统计报表',
'......'
] as string[],
text: '',
canAdd: true,
canRemove: false,
extraLine: [] as string[]
}
},
methods: {
add: function () {
this.extraLine.push(this.texts[this.extraLine.length % 12]);
this.text = this.extraLine.join('\n');
this.canAdd = this.extraLine.length < 12;
this.canRemove = this.extraLine.length > 0;
},
methods: {
add: function () {
this.extraLine.push(this.texts[this.extraLine.length % 12]);
remove: function () {
if (this.extraLine.length > 0) {
this.extraLine.pop();
this.text = this.extraLine.join('\n');
this.canAdd = this.extraLine.length < 12;
this.canRemove = this.extraLine.length > 0;
},
remove: function () {
if (this.extraLine.length > 0) {
this.extraLine.pop();
this.text = this.extraLine.join('\n');
this.canAdd = this.extraLine.length < 12;
this.canRemove = this.extraLine.length > 0;
}
},
textProps: function () {
uni.navigateTo({
url: '/pages/component/text/text-props'
})
}
}
}
},
textProps: function () {
uni.navigateTo({
url: '/pages/component/text/text-props'
})
}
}
}
</script>
<style>
.text-box {
margin-bottom: 40rpx;
padding: 40rpx 0;
display: flex;
min-height: 300rpx;
background-color: #FFFFFF;
justify-content: center;
align-items: center;
}
.text-box {
margin-bottom: 40rpx;
padding: 40rpx 0;
display: flex;
min-height: 300rpx;
background-color: #ffffff;
justify-content: center;
align-items: center;
}
.text {
font-size: 30rpx;
color: #353535;
line-height: 54rpx;
text-align: center;
}
</style>
\ No newline at end of file
.text {
font-size: 30rpx;
color: #353535;
line-height: 54rpx;
text-align: center;
}
</style>
<template>
<view class="page">
<unicloud-db ref="udb" v-slot:default="{data, loading, error}" :collection="collection" loadtime="manual">
<view v-if="error" class="error">{{error}}</view>
</unicloud-db>
<view class="form-item">
<text class="form-item-label">姓名</text>
<input class="form-item-input" placeholder="姓名" v-model="username" />
</view>
<view class="form-item">
<text class="form-item-label">电话</text>
<input class="form-item-input" placeholder="电话" v-model="mobile" />
</view>
<view class="form-item">
<text class="form-item-label">邮箱</text>
<input class="form-item-input" placeholder="邮箱地址" v-model="email" />
</view>
<view class="form-item">
<text class="form-item-label">备注</text>
<textarea class="form-item-input" placeholder="备注" v-model="comment" />
</view>
<view class="form-item">
<text class="form-item-label">性别</text>
<radio-group class="radio-list" @change="radioChange">
<view class="radio-item" v-for="(item, _) in genderList" :key="item.value">
<radio :value="item.value" :checked="item.value == gender" />
<text>{{item.text}}</text>
</view>
</radio-group>
</view>
<button class="btn-add" type="primary" @click="submit">保存</button>
</view>
</template>
<script>
import { COLLECTION_NAME, GenderType, GenderList, UNICLOUD_DB_CONTACTS_ADD } from './types.uts'
export default {
data() {
return {
collection: COLLECTION_NAME,
username: "",
mobile: "",
gender: "",
comment: "",
email: "",
genderList: GenderList as GenderType[],
$uniCloudElement: null as UniCloudDBElement | null
}
},
onReady() {
this.$uniCloudElement = this.$refs['udb'] as UniCloudDBElement
},
methods: {
radioChange(e : RadioGroupChangeEvent) {
this.gender = e.detail.value
},
submit() {
const value = {
username: this.username,
gender: parseInt(this.gender),
mobile: this.mobile,
comment: this.comment,
email: this.email,
};
this.$uniCloudElement!.add(value, {
showToast: false,
needLoading: true,
loadingTitle: "正在保存...",
success: (_ : UniCloudDBAddResult) => {
// TODO 后续通过 EventChannel 实现
uni.$emit(UNICLOUD_DB_CONTACTS_ADD, '')
setTimeout(() => {
uni.navigateBack()
}, 500)
},
fail: (err : any | null) => {
const error = err as UniCloudError
uni.showModal({
content: error.errMsg,
showCancel: false
})
}
})
}
}
}
</script>
<style>
.page {
padding: 15px;
}
.form-item {
flex-direction: row;
margin-bottom: 15px;
align-items: center;
}
.form-item-label {
width: 45px;
margin-right: 10px;
}
.form-item-input {
flex: 1;
font-size: 14px;
color: #666;
border: 1px #e5e5e5 solid;
border-radius: 5px;
padding: 8px;
}
.radio-list {
flex-direction: row;
}
.radio-item {
flex-direction: row;
margin-right: 30px;
align-items: center;
}
.btn-add {
margin-top: 50px;
}
</style>
\ No newline at end of file
<template>
<scroll-view class="page">
<unicloud-db ref="udb" v-slot:default="{data, loading, error}" :collection="collection" :where="where"
loadtime="manual" page-data="replace">
<view v-if="error!=null" class="error">{{error.errMsg}}</view>
<view v-if="loading" class="loading">正在加载...</view>
<view v-if="data.length>0">
<view class="form-item">
<text class="form-item-label">姓名</text>
<text class="form-item-input">{{data[0]['username']}}</text>
</view>
<view class="form-item">
<text class="form-item-label">电话</text>
<text class="form-item-input">{{data[0]['mobile']}}</text>
</view>
<view class="form-item">
<text class="form-item-label">邮箱</text>
<text class="form-item-input">{{data[0]['email']}}</text>
</view>
<view class="form-item">
<text class="form-item-label">备注</text>
<text class="form-item-input">{{data[0]['comment']}}</text>
</view>
<view class="form-item">
<text class="form-item-label">性别</text>
<text class="form-item-input">{{displayGender(data[0]['gender'])}}</text>
</view>
<button class="btn-update" type="default" @click="gotoUpdatePage(data[0].getString('_id'))">编辑</button>
</view>
</unicloud-db>
</scroll-view>
</template>
<script>
import { COLLECTION_NAME, GenderType, GenderList, UNICLOUD_DB_CONTACTS_UPDATE } from './types.uts'
export default {
data() {
return {
collection: COLLECTION_NAME,
where: '',
$whereID: '',
$uniCloudElement: null as UniCloudDBElement | null
}
},
onLoad(options : Map<string, string>) {
this.$whereID = options['id'] as string;
this.where = `_id=='${this.$whereID}'`;
},
onShow() {
// TODO 后续通过 EventChannel 实现
uni.$off(UNICLOUD_DB_CONTACTS_UPDATE, this.onDataChange);
},
onUnload() {
// TODO 后续通过 EventChannel 实现
uni.$off(UNICLOUD_DB_CONTACTS_UPDATE, this.onDataChange);
},
onReady() {
this.$uniCloudElement = this.$refs['udb'] as UniCloudDBElement
this.$uniCloudElement!.loadData()
},
methods: {
displayGender(value : any | null) : string {
const str = (value ?? 0).toString()
return (GenderList as GenderType[]).find((item : GenderType) : boolean => {
return item.value == str
})!.text;
},
gotoUpdatePage(id : string | null) {
// TODO 后续通过 EventChannel 实现
uni.$on(UNICLOUD_DB_CONTACTS_UPDATE, this.onDataChange);
uni.navigateTo({
url: './edit?id=' + id
})
},
onDataChange(id : string) {
this.$uniCloudElement!.loadData()
}
}
}
</script>
<style>
.page {
padding: 15px;
}
.loading {
align-items: center;
}
.form-item {
flex-direction: row;
margin-bottom: 15px;
align-items: center;
padding: 8px 0;
}
.form-item-label {
width: 45px;
margin-right: 10px;
}
.form-item-input {
flex: 1;
font-size: 14px;
color: #666;
}
</style>
<template>
<view class="page">
<navbar>
<template v-slot:left>
<text class="btn-cancel">取消</text>
</template>
<template v-slot:right>
<text class="btn-update" @click="update">保存</text>
</template>
</navbar>
<scroll-view class="scroll-view" :scroll-y="true">
<unicloud-db ref="udb" v-slot:default="{data, loading, error}" :collection="collection" :where="where"
page-data="replace" loadtime="manual" @load="onQueryLoad">
<view v-if="error!=null" class="error">{{error.errMsg}}</view>
<view v-if="loading" class="loading">正在加载...</view>
<view v-if="data.length>0">
<view class="form-item">
<text class="form-item-label">姓名</text>
<input class="form-item-input" placeholder="姓名" v-model="username" />
</view>
<view class="form-item">
<text class="form-item-label">电话</text>
<input class="form-item-input" placeholder="电话" v-model="mobile" />
</view>
<view class="form-item">
<text class="form-item-label">邮箱</text>
<input class="form-item-input" placeholder="邮箱地址" v-model="email" />
</view>
<view class="form-item">
<text class="form-item-label">备注</text>
<textarea class="form-item-input" placeholder="备注" v-model="comment" />
</view>
<view class="form-item">
<text class="form-item-label">性别</text>
<radio-group class="radio-list" @change="radioChange">
<view class="radio-item" v-for="(item, _) in genderList" :key="item.value">
<radio :value="item.value" :checked="item.value == gender" />
<text>{{item.text}}</text>
</view>
</radio-group>
</view>
<button class="btn-delete" type="warn"
@click="remove(data[0].getString('_id'), data[0].getString('username'))">删除联系人</button>
</view>
</unicloud-db>
</scroll-view>
</view>
</template>
<script>
import { COLLECTION_NAME, GenderType, GenderList, UNICLOUD_DB_CONTACTS_UPDATE, UNICLOUD_DB_CONTACTS_DELETE } from './types.uts'
import navbar from './navbar.uvue'
export default {
components: {
navbar
},
data() {
return {
collection: COLLECTION_NAME,
where: '',
username: "",
mobile: "",
gender: '',
comment: "",
email: "",
genderList: GenderList as GenderType[],
$whereID: '',
$uniCloudElement: null as UniCloudDBElement | null
}
},
onLoad(options : Map<string, string>) {
this.$whereID = options['id'] as string;
this.where = `_id=='${this.$whereID}'`;
},
onReady() {
this.$uniCloudElement = this.$refs['udb'] as UniCloudDBElement
this.$uniCloudElement!.loadData()
},
methods: {
radioChange(e : RadioGroupChangeEvent) {
this.gender = e.detail.value
},
update() {
const value = {
username: this.username,
gender: parseInt(this.gender),
mobile: this.mobile,
comment: this.comment,
email: this.email,
};
this.$uniCloudElement!.update(this.$whereID, value, {
showToast: false,
needLoading: true,
needConfirm: false,
loadingTitle: "正在保存...",
success: (_ : UniCloudDBUpdateResult) => {
// TODO 后续通过 EventChannel 实现
uni.$emit(UNICLOUD_DB_CONTACTS_UPDATE, this.$whereID)
setTimeout(() => {
uni.navigateBack()
}, 500)
},
fail: (err : any | null) => {
const error = err as UniCloudError
uni.showModal({
content: error.errMsg,
showCancel: false
})
}
})
},
remove(id : string | null, name : string | null) {
this.$uniCloudElement!.remove(id!, {
needConfirm: true,
needLoading: true,
loadingTitle: "正在删除...",
confirmTitle: "确定删除?",
confirmContent: name,
success: (_ : UniCloudDBRemoveResult) => {
// TODO 后续通过 EventChannel 实现
uni.$emit(UNICLOUD_DB_CONTACTS_DELETE, this.$whereID)
setTimeout(() => {
uni.navigateBack({
delta: 2
})
}, 500)
},
fail: (err : any | null) => {
const error = err as UniCloudError
uni.showModal({
content: error.errMsg,
showCancel: false
})
}
})
},
onQueryLoad(data : Array<UTSJSONObject>, _ : boolean) {
if (data.length == 0) {
return
}
const data1 = data[0];
this.username = data1.getString('username') ?? "";
this.mobile = data1.getString('mobile') ?? "";
this.gender = data1.getNumber('gender')?.toString() ?? '0';
this.comment = data1.getString('comment') ?? "";
this.email = data1.getString('email') ?? "";
}
}
}
</script>
<style>
.page {
flex: 1;
}
.scroll-view {
padding: 15px;
flex: 1;
}
.loading {
align-items: center;
}
.form-item {
flex-direction: row;
margin-bottom: 15px;
align-items: center;
}
.form-item-label {
width: 45px;
margin-right: 10px;
}
.form-item-input {
flex: 1;
font-size: 14px;
color: #666;
border: 1px #e5e5e5 solid;
border-radius: 5px;
padding: 8px;
}
.radio-list {
flex-direction: row;
}
.radio-item {
flex-direction: row;
margin-right: 30px;
align-items: center;
}
.btn-cancel {
color: #fff;
margin-left: 15px;
}
.btn-update {
color: #fff;
margin-right: 15px;
}
.btn-delete {
margin-top: 350px;
}
</style>
<template>
<view class="page">
<unicloud-db ref="udb" v-slot:default="{data, pagination, loading, hasMore, error}" :collection="collection"
:page-size="10" :getcount="true" loadtime="manual">
<view v-if="error!=null" class="error">{{error.errMsg}}</view>
<list-view ref="listView" class="list-view" :scroll-y="true" @scrolltolower="loadMore()">
<list-item class="list-item" v-for="(item, _) in data" @click="gotoDetailPage(item['_id'] as string)">
<view class="list-item-fill">
<text class="name">{{item['username']}}</text>
<text class="mobile">{{item['mobile']}}</text>
</view>
</list-item>
</list-view>
<view v-if="loading" class="loading">正在加载...</view>
<view v-if="data.length>0" class="pagination">
<text class="pagination-item">{{data.length}} / {{pagination.count}}</text>
</view>
</unicloud-db>
<view class="btn-plus" @click="gotoAddPage">
<text class="btn-plus-text">+</text>
</view>
</view>
</template>
<script>
import { COLLECTION_NAME, UNICLOUD_DB_CONTACTS_ADD, UNICLOUD_DB_CONTACTS_UPDATE, UNICLOUD_DB_CONTACTS_DELETE } from './types.uts'
export default {
data() {
return {
collection: COLLECTION_NAME,
$uniCloudElement: null as UniCloudDBElement | null
}
},
onReady() {
// TODO 后续通过 EventChannel 实现
uni.$on(UNICLOUD_DB_CONTACTS_DELETE, this.onDataChange);
this.$uniCloudElement = this.$refs['udb'] as UniCloudDBElement
this.$uniCloudElement!.loadData()
},
onUnload() {
// TODO 后续通过 EventChannel 实现
uni.$off(UNICLOUD_DB_CONTACTS_ADD, this.onDataChange);
uni.$off(UNICLOUD_DB_CONTACTS_UPDATE, this.onDataChange);
uni.$off(UNICLOUD_DB_CONTACTS_DELETE, this.onDataChange);
},
onShow() {
// TODO 后续通过 EventChannel 实现
uni.$off(UNICLOUD_DB_CONTACTS_ADD, this.onDataChange);
uni.$off(UNICLOUD_DB_CONTACTS_UPDATE, this.onDataChange);
},
onPullDownRefresh() {
this.$uniCloudElement!.loadData({
clear: true,
success: (_ : UniCloudDBGetResult) => {
uni.stopPullDownRefresh()
}
})
},
methods: {
loadMore() {
this.$uniCloudElement!.loadMore()
},
gotoAddPage() {
// TODO 后续通过 EventChannel 实现
uni.$on(UNICLOUD_DB_CONTACTS_ADD, this.onDataChange);
uni.navigateTo({
url: './add'
})
},
gotoDetailPage(id : string) {
// TODO 后续通过 EventChannel 实现
uni.$on(UNICLOUD_DB_CONTACTS_UPDATE, this.onDataChange);
uni.navigateTo({
url: './detail?id=' + id
})
},
onDataChange(id : string) {
this.$uniCloudElement!.loadData({
clear: true
})
}
}
}
</script>
<style>
.page {
flex: 1;
flex-direction: column;
}
.loading {
align-items: center;
padding: 20px;
}
.list-view {
flex: 1;
flex-direction: column;
}
.list-item {
flex-direction: row;
padding: 10px;
background-color: #fff;
margin-bottom: 1px;
}
.mobile {
margin-top: 5px;
}
.btn-plus {
position: absolute;
width: 64px;
height: 64px;
right: 20px;
bottom: 20px;
align-items: center;
justify-content: center;
background-color: #1e90ff;
border-radius: 64px;
}
.btn-plus-text {
font-size: 30px;
color: #fff;
}
.pagination {
align-items: center;
background-color: #f8f8f8;
padding: 15px;
}
</style>
<template>
<view class="navigation-bar">
<view :style="statusBarStyle"></view>
<view class="navigation-bar-header">
<view class="navbar-left" @click="back">
<slot name="left">1</slot>
</view>
<view class="navbar-content">
<slot name="middle"></slot>
</view>
<view class="navbar-right">
<slot name="right"></slot>
</view>
</view>
</view>
</template>
<script>
export default {
name: "navbar",
props: {
},
data() {
return {
statusBarHeight: 0
};
},
computed: {
statusBarStyle() : string {
return `padding-top:${this.statusBarHeight}px`
},
},
created() {
this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
setTimeout(() => {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#007AFF'
})
}, 100)
},
methods: {
back() {
uni.navigateBack({})
}
}
}
</script>
<style>
.navigation-bar {
background-color: #007AFF;
flex-direction: column;
}
.navigation-bar-header {
position: relative;
flex-direction: row;
align-items: center;
height: 45px;
}
.navbar-content {
flex: 1;
align-items: center;
}
</style>
export const COLLECTION_NAME = 'opendb-contacts'
export type GenderType = {
text : string,
value : string,
}
export const GenderList = [
{
text: "未知",
value: "0"
},
{
text: "男",
value: "1"
},
{
text: "女",
value: "2"
},
] as GenderType[]
export const UNICLOUD_DB_CONTACTS_ADD = 'unicloud-db-contacts-add'
export const UNICLOUD_DB_CONTACTS_UPDATE = 'unicloud-db-contacts-update'
export const UNICLOUD_DB_CONTACTS_DELETE = 'unicloud-db-contacts-delete'
......@@ -12,9 +12,6 @@
<boolean-data :defaultValue="false" title="是否阻止本节点的祖先节点出现点击态" @change="change_stop_propagation_boolean"></boolean-data>
<enum-data :items="start_time_enum" title="按住后多久出现点击态" @change="radio_change_start_time_enum"></enum-data>
<enum-data :items="stay_time_enum" title="手指松开后点击态保留时间" @change="radio_change_stay_time_enum"></enum-data>
<view class="uni-padding-wrap uni-common-mt uni-common-mb">
<button class="uni-common-mt" @click="goGeneralAttribute('/pages/component/view/view-draw')">DrawableContext</button>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
......@@ -46,11 +43,6 @@ export default {
radio_change_stay_time_enum(time : number) {
this.stay_time = time
},
goGeneralAttribute(path: string) {
uni.navigateTo({
url: path,
})
},
},
}
</script>
......
......@@ -34,7 +34,6 @@ const pages = [
'/pages/component/text/text',
'/pages/component/textarea/textarea',
// '/pages/component/video/video',
'/pages/component/view/view-draw',
'/pages/component/view/view',
// '/pages/component/web-view/web-view', // 动态内容
'/pages/component/web-view-local/web-view-local',
......@@ -120,6 +119,9 @@ const pages = [
'/pages/template/swiper-list/swiper-list',
'/pages/template/swiper-list2/swiper-list2',
// '/pages/template/swiper-vertical-video/swiper-vertical-video'
// api
'/pages/API/element-draw/element-draw',
]
let page;
......
......@@ -146,6 +146,15 @@
name: 'element元素',
url: 'get-element-by-id',
api: ["getElementById"]
},
{
name: 'element draw',
url: 'element-draw',
api: ["Element.getDrawableContext"]
},{
name: 'element截图',
url: 'element-takesnapshot',
api: ["Element.takeSnapshot"]
},
{
name: 'node节点',
......
......@@ -87,7 +87,10 @@ export default {
*/
{
name: 'list-view',
},
},
{
name: 'sticky-header',
}
] as Page[],
},
{
......@@ -217,6 +220,17 @@ export default {
url: '/pages/component/web-view-local/web-view-local',
},
] as Page[],
},
{
id: 'unicloud-db',
name: 'unicloud-db',
pages: [
{
name: '联系人',
enable: true,
url: '/pages/component/unicloud-db-contacts/list'
}
] as Page[],
},
/*
{
......
......@@ -141,7 +141,7 @@ export default {
{
id: 'scroll-sticky',
url: 'scroll-sticky',
name: '吸顶',
name: 'scroll-view自定义滚动吸顶',
open: false,
pages: [] as Page[],
},
......
<template>
<view style="width: 100%;height: 100%;">
<view class="banner" @click="bannerClick(banner)">
<image class="banner-img" :src="banner.cover"></image>
<text class="banner-title">{{ banner.title }}</text>
</view>
<list-view class="uni-list-content" refresher-enabled=true @refresherrefresh="onRefresherrefresh"
:refresher-triggered="refresherTriggered" scroll-y = true>
<list-item v-for="(value, index) in listData" :key="index">
<view class="uni-list-cell" hover-class="uni-list-cell-hover" @click="goDetail(value)">
<view class="uni-media-list">
<image class="uni-media-list-logo" :src="value.cover"></image>
<view class="uni-media-list-body">
<text class="uni-media-list-text-top">{{ value.title }}</text>
<view class="uni-media-list-text-bottom">
<text class="uni-media-list-text">{{ value.author_name }}</text>
<text class="uni-media-list-text">{{ value.published_at }}</text>
</view>
</view>
</view>
</view>
</list-item>
</list-view>
</view>
<list-view style="flex: 1;" refresher-enabled=true @refresherrefresh="onRefresherrefresh"
:refresher-triggered="refresherTriggered">
<list-item class="banner" @click="bannerClick(banner)">
<image class="banner-img" :src="banner.cover"></image>
<text class="banner-title">{{ banner.title }}</text>
</list-item>
<sticky-header>
<view style="width: 100%;height:44px;background-color: #f5f5f5;flex-direction: row;justify-content:center;align-items:center;">
<button style="height: 40px;font-size: 13px;" v-for="(name,index) in th_item" @click="clickTH(index)">
{{name}}
</button>
</view>
</sticky-header>
<list-item v-for="(value, index) in listData" :key="index">
<view class="uni-list-cell" hover-class="uni-list-cell-hover" @click="goDetail(value)">
<view class="uni-media-list">
<image class="uni-media-list-logo" :src="value.cover"></image>
<view class="uni-media-list-body">
<text class="uni-media-list-text-top">{{ value.title }}</text>
<view class="uni-media-list-text-bottom">
<text class="uni-media-list-text">{{ value.author_name }}</text>
<text class="uni-media-list-text">{{ value.published_at }}</text>
</view>
</view>
</view>
</view>
</list-item>
</list-view>
</template>
<script>
type Banner = {
cover: string | null,
title: string | null,
post_id: string | null
}
type Item = {
author_name: string,
cover: string,
id: number,
post_id: string,
published_at: string,
title: string
}
type Banner = {
cover : string | null,
title : string | null,
post_id : string | null
}
type Item = {
author_name : string,
cover : string,
id : number,
post_id : string,
published_at : string,
title : string
}
export default {
data() {
return {
refresherTriggered: false,
banner: {} as Banner,
listData: [] as Item[],
last_id: '',
pageVisible: false
};
},
onLoad() {
this.pageVisible = true; //设这个变量是为了避免联网结束后页面已经关闭,此时还继续执行回调逻辑的问题。不是必须的
this.getBanner();
this.getList();
},
onUnload() {
this.pageVisible = false;
},
methods: {
getBanner() {
let data = {
column: 'id,post_id,title,author_name,cover,published_at' //需要的字段名
};
uni.request<Banner>({
url: 'https://unidemo.dcloud.net.cn/api/banner/36kr',
data: data,
success: data => {
if(this.pageVisible){
this.refresherTriggered = false
if (data.statusCode == 200) {
export default {
data() {
return {
th_item: ["排序", "筛选"],
refresherTriggered: false,
banner: {} as Banner,
listData: [] as Item[],
last_id: '',
pageVisible: false
};
},
onLoad() {
this.pageVisible = true; //设这个变量是为了避免联网结束后页面已经关闭,此时还继续执行回调逻辑的问题。不是必须的
this.getBanner();
this.getList();
},
onUnload() {
this.pageVisible = false;
},
methods: {
getBanner() {
let data = {
column: 'id,post_id,title,author_name,cover,published_at' //需要的字段名
};
uni.request<Banner>({
url: 'https://unidemo.dcloud.net.cn/api/banner/36kr',
data: data,
success: data => {
if (this.pageVisible) {
this.refresherTriggered = false
if (data.statusCode == 200) {
const result = data.data
if(result != null){
if (result != null) {
this.banner = result;
}
}
}
},
fail: (e) => {
console.log('fail', e);
}
});
},
getList() {
let url = "https://unidemo.dcloud.net.cn/api/news?column=id,post_id,title,author_name,cover,published_at";
/* if (this.last_id != "") {
const minId = parseInt((this.last_id))
const time = new Date().getTime() + '';
const pageSize = 10;
url = url + "&minId=" + minId + "&time=" + time + "&pageSize=" + pageSize;
} */
}
}
},
fail: (e) => {
console.log('fail', e);
}
});
},
getList() {
let url = "https://unidemo.dcloud.net.cn/api/news?column=id,post_id,title,author_name,cover,published_at";
/* if (this.last_id != "") {
const minId = parseInt((this.last_id))
const time = new Date().getTime() + '';
const pageSize = 10;
url = url + "&minId=" + minId + "&time=" + time + "&pageSize=" + pageSize;
} */
uni.request<Item[]>({
url: url,
method:"GET",
success: (res) => {
if(this.pageVisible){
if (res.statusCode == 200) {
uni.request<Item[]>({
url: url,
method: "GET",
success: (res) => {
if (this.pageVisible) {
if (res.statusCode == 200) {
console.log(res);
const result = res.data
if(result != null){
this.listData = result //因本接口没有更多分页数据,所以重新赋值。正常有分页的列表应该如下面push方式增加数组项
// this.listData.push(...result)
// this.last_id = this.listData[0].id + "";
}
this.refresherTriggered = false;
}
}
},
fail: (res) => {
if(this.pageVisible){
console.log('fail', res);
this.refresherTriggered = false
}
}
});
},
goDetail(e: Item) {
const detail = e;
const post_id = detail.post_id;
const cover = detail.cover;
const title = detail.title;
uni.navigateTo({
url: '/pages/template/list-news/detail/detail?post_id=' + post_id + "&cover=" + cover + "&title=" + title
});
},
bannerClick(e:Banner){
const detail = e;
const post_id = detail.post_id;
const cover = detail.cover;
const title = detail.title;
uni.navigateTo({
url: '/pages/template/list-news/detail/detail?post_id=' + post_id + "&cover=" + cover + "&title=" + title
});
},
onRefresherrefresh() {
if(this.pageVisible){
this.refresherTriggered = true
this.getBanner();
this.getList();
}
}
}
};
const result = res.data
if (result != null) {
this.listData = result //因本接口没有更多分页数据,所以重新赋值。正常有分页的列表应该如下面push方式增加数组项
// this.listData.push(...result)
// this.last_id = this.listData[0].id + "";
}
this.refresherTriggered = false;
}
}
},
fail: (res) => {
if (this.pageVisible) {
console.log('fail', res);
this.refresherTriggered = false
}
}
});
},
goDetail(e : Item) {
const detail = e;
const post_id = detail.post_id;
const cover = detail.cover;
const title = detail.title;
uni.navigateTo({
url: '/pages/template/list-news/detail/detail?post_id=' + post_id + "&cover=" + cover + "&title=" + title
});
},
bannerClick(e : Banner) {
const detail = e;
const post_id = detail.post_id;
const cover = detail.cover;
const title = detail.title;
uni.navigateTo({
url: '/pages/template/list-news/detail/detail?post_id=' + post_id + "&cover=" + cover + "&title=" + title
});
},
clickTH(index:number){
uni.showModal({
content: "点击表头项:" + index,
showCancel: false
});
},
onRefresherrefresh() {
if (this.pageVisible) {
this.refresherTriggered = true
this.getBanner();
this.getList();
}
}
}
};
</script>
<style>
.banner {
height: 360rpx;
overflow: hidden;
position: relative;
background-color: #ccc;
}
.banner {
height: 360rpx;
overflow: hidden;
position: relative;
background-color: #ccc;
}
.banner-img {
width: 100%;
}
.banner-img {
width: 100%;
}
.banner-title {
max-height: 84rpx;
overflow: hidden;
position: absolute;
left: 30rpx;
bottom: 30rpx;
width: 90%;
font-size: 32rpx;
font-weight: 400;
line-height: 42rpx;
color: white;
}
.banner-title {
max-height: 84rpx;
overflow: hidden;
position: absolute;
left: 30rpx;
bottom: 30rpx;
width: 90%;
font-size: 32rpx;
font-weight: 400;
line-height: 42rpx;
color: white;
}
.uni-media-list {
padding: 22rpx 30rpx;
box-sizing: border-box;
display: flex;
width: 100%;
flex-direction: row;
}
.uni-media-list {
padding: 22rpx 30rpx;
box-sizing: border-box;
display: flex;
width: 100%;
flex-direction: row;
}
.uni-media-list-logo {
width: 180rpx;
height: 140rpx;
}
.uni-media-list-logo {
width: 180rpx;
height: 140rpx;
}
.uni-media-list-body {
flex: 1;
padding-left: 15rpx;
justify-content: space-around;
}
.uni-media-list-body {
flex: 1;
padding-left: 15rpx;
justify-content: space-around;
}
.uni-list-content{
background-color: #FFFFFF;
position: relative;
display: flex;
flex-direction: column;
border-bottom: 1px solid #c8c7cc;
flex: 1;
}
.uni-list-content {
background-color: #FFFFFF;
position: relative;
display: flex;
flex-direction: column;
border-bottom: 1px solid #c8c7cc;
flex: 1;
}
.uni-media-list-text-top {
/* height: 74rpx; */
font-size: 28rpx;
lines:2;
overflow: hidden;
}
.uni-media-list-text-top {
/* height: 74rpx; */
font-size: 28rpx;
lines: 2;
overflow: hidden;
}
.uni-media-list-text-bottom {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.uni-media-list-text-bottom {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.uni-media-list-text {
color: #9D9D9F;
font-size: 25rpx;
}
.uni-media-list-text {
color: #9D9D9F;
font-size: 25rpx;
}
</style>
......@@ -2,10 +2,10 @@
<list-view ref="listView" class="list" :rebound="false" :scroll-y="true" :custom-nested-scroll="true"
@scrolltolower="loadData(null)">
<list-item class="list-item" v-for="(item, _) in dataList" :key="item.plugin_id">
<view class="list-item-icon" v-if="item.plugin_id!=-1">
<view class="list-item-icon">
<image class="list-item-icon-image" :src="item.plugin_img_link"></image>
</view>
<view class="list-item-fill" v-if="item.plugin_id!=-1">
<view class="list-item-fill">
<view class="flex-row">
<text class="title">{{item.plugin_name}}</text>
</view>
......@@ -22,8 +22,9 @@
<text class="author">{{item.author_name}}</text>
</view>
</view>
<!-- TODO 暂时这样写才能保证 loading 在 list 底部 -->
<view v-if="item.plugin_id==-1" class="loading">
</list-item>
<list-item>
<view class="loading">
<text class="loading-text">{{loadingText}}</text>
</view>
</list-item>
......@@ -81,35 +82,17 @@
} else {
return ""
}
},
}
},
created() {
this.insertLoadingData()
if (this.preload) {
this.loadData(null)
}
},
methods: {
// TODO 目前 list-item 不支持注释节点
// 暂时在数据末尾插入一条空数据用于显示 loading
insertLoadingData() {
const loadingData = {
plugin_id: -1,
plugin_img_link: '',
plugin_name: '',
plugin_intro: '',
score: 0,
tags: [],
update_date: '',
author_name: '',
} as ListItem
this.dataList.push(loadingData)
},
refreshData(loadComplete : (() => void) | null) {
this.dataList.length = 0
this.$currentPage = 1
this.insertLoadingData()
this.loadData(loadComplete)
},
loadData(loadComplete : (() => void) | null) {
......@@ -131,9 +114,7 @@
return
}
// TODO
this.dataList.splice(this.dataList.length - 1, 0, ...responseData.data)
// this.dataList.push(...responseData.data)
this.dataList.push(...responseData.data)
if (responseData.data.length == 0) {
this.isEnded = true
......@@ -254,20 +235,12 @@
}
.loading {
/* position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0; */
flex:1;
margin: -10px;
padding: 20px;
background-color: #f8f8f8;
margin-bottom: 1px;
justify-content: center;
}
.loading-text {
padding: 20px;
text-align: center;
}
</style>
{
"bsonType": "object",
"permission": {
"read": true,
"create": true,
"update": true,
"delete": true
},
"required": ["username", "mobile"],
"properties": {
"_id": {
"description": "存储文档 ID(用户 ID),系统自动生成"
},
"username": {
"bsonType": "string",
"title": "姓名",
"description": "姓名",
"order": 1,
"trim": "both"
},
"gender": {
"bsonType": "int",
"title": "性别",
"description": "用户性别:0 未知 1 男性 2 女性",
"order": 2,
"defaultValue": 0,
"enum": [{
"text": "未知",
"value": 0
},
{
"text": "男",
"value": 1
},
{
"text": "女",
"value": 2
}
]
},
"mobile": {
"bsonType": "string",
"title": "电话",
"order": 3,
"description": "电话",
"pattern": "^\\+?[0-9-]{3,20}$",
"trim": "both"
},
"email": {
"bsonType": "string",
"format": "email",
"title": "邮箱",
"order": 4,
"description": "邮箱地址",
"trim": "both"
},
"comment": {
"bsonType": "string",
"title": "备注",
"order": 5,
"description": "备注",
"trim": "both",
"component": {
"name": "textarea"
}
},
"create_date": {
"bsonType": "timestamp",
"description": "创建时间",
"forceDefaultValue": {
"$env": "now"
}
}
},
"version": "0.0.1"
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册