Giter Site home page Giter Site logo

dingyong0214 / thorui-uniapp Goto Github PK

View Code? Open in Web Editor NEW
2.5K 58.0 385.0 11.14 MB

ThorUI组件库,轻量、简洁的移动端组件库。组件文档地址:https://thorui.cn/doc

License: MIT License

Vue 75.94% CSS 3.69% JavaScript 20.24% SCSS 0.11% HTML 0.02%
uni-app vue uniapp component vue-component demo-app components template

thorui-uniapp's Issues

ActionSheet组件显示错位

iphonex --真机显示效果如下图
微信图片_20190709095500

---------------------------------------------- 分割线 -------------------------------------------------

微信图片_20190709095512

---------------------------------------------- 分割线 -------------------------------------------------

微信图片_20190709095517

tui-list-cell的border在h5不显示

.tui-list-cell::after {
  content: '';
  position: absolute;
  border-bottom: 1rpx solid #eaeef1;
  -webkit-transform: scaleY(0.5);
  transform: scaleY(0.5);
  bottom: 0;
  right: 0;
  left:0;
}

border-bottom: 1rpx在h5是0.5px,显示不出来

全局Style统一问题

近两个月来,一直在使用Thor-UI,也非常看好整体的设计,但是在使用过程中仍然遇到很多问题,针对这些问题对组件做了些自定义修改。
其中最严重的问题在于,整体项目如果需要更改主题色彩,则需要到组件中每一个使用该颜色的位置更改RGB16进制码,这样的操作工作量大且很容易出错,因此,我希望能够引入uni-app官方推荐的scss预处理器,在降低代码冗余的同时,可以全局统一管理色彩等元素。
如果需要也可告知,我可以协助参与项目。

TuiGridItem 设置 prop "cell"时,提示Vue warn

Vue warn]: Invalid prop: type check failed for prop "cell". Expected Number with value 5, got String with value "5".

found in

---> at Users/zhuwei/HBuilderProjects/Start_Rfid/components/grid-item/grid-item.vue

at Users/zhuwei/HBuilderProjects/Start_Rfid/components/grid/grid.vue
... (1 recursive calls)
at Users/zhuwei/HBuilderProjects/Start_Rfid/components/card/card.vue






input输入框闪烁问题

你好,刚接触小程序,发现微信小程序输入框闪烁,uniapp本身也存在这个问题。想问下这个是微信小程序问题,还是uniapp的问题?能不能避免掉?谢谢。

上传组件 完善

首先, 请原谅我使用 typescript 来写 (我个人喜欢 typescript , 它可以减少很多常见的错误),
正因为是 typescript , 所以我就不 PR 了。
我这个版本里面, 增加了 outField 用了 从 服务端返回的json 上获取一个字段

关于 @Prop , @Model, @Emit 的关系 请查看此文档 https://github.com/kaorun343/vue-property-decorator#Watch , 里面又 对应的代码, 很容易理解

以下是我的代码

<template>
  <view class="tui-container">
    <view class="tui-upload-box">
      <view class="tui-image-item" v-for="(item,index) in imageList" :key="index">
        <image
          :src="item.image"
          class="tui-item-img"
          @click.stop="previewImage(index)"
          mode="aspectFill"
        />
        <view v-if="!forbidDel" class="tui-img-del" @click.stop="delImage(index)"></view>
        <view v-if="imageList[index].state!='uploaded'" class="tui-upload-mask">
          <view class="tui-upload-loading" v-if="imageList[index].state == 'uploading'"></view>
          <text class="tui-tips">{{getStateText(index)}}</text>
          <view
            class="tui-mask-btn"
            v-if="imageList[index].state=='fail'"
            @click.stop="reUpload(index)"
            hover-class="tui-hover"
            :hover-stay-time="150"
          >重新上传</view>
        </view>
      </view>
      <view v-if="isShowAdd" class="tui-upload-add" @click="chooseImage">
        <view class="tui-upload-icon tui-icon-plus"></view>
      </view>
    </view>
  </view>
</template>
<script lang="ts">
import Vue from "vue";
import { Component, Prop, Model, Emit, Watch } from "vue-property-decorator";
import { httpClient } from "../../core/httpclient";
@Component
export default class MultiImgUpload extends Vue {
  /** v-model 的值 */
  @Model("change", { type: Array, default: () => [] })
  value!: string[];

  /**上传地址 */
  @Prop({ type: String, default: `/api/upload/image` })
  uploadApi!: string;

  /**禁止删除 */
  @Prop({ type: Boolean, default: false })
  forbidDel!: boolean;

  /**禁止添加 */
  @Prop({ type: Boolean, default: false })
  forbidAdd!: boolean;

  /** 限制数量 */
  @Prop({ type: Number, default: 9 })
  limit!: number;

  /**上传时表单字段的名字 默认 file */
  @Prop({ type: String, default: "file" })
  filedName!: string;

  /** 服务端api 返回的json种的字段 默认 data */
  @Prop({ type: String, default: "data" })
  outField!: string;

  @Emit("change")
  emitChange(val: string[]) {
    return val;
  }

  @Emit("add")
  emitAdd(newFile: string) {
    this.emitChange(
      this.imageList
        .filter(x => x.state == "uploaded")
        .map(x => x.value as string)
    );
    return newFile;
  }

  @Emit("delete")
  emitDelete(file: string) {
    this.emitChange(
      this.imageList
        .filter(x => x.state == "uploaded")
        .map(x => x.value as string)
    );
    return file;
  }

  imageList: ImageItem[] = [];

  get isShowAdd() {
    let isShow = true;
    if (this.forbidAdd || (this.limit && this.imageList.length >= this.limit)) {
      isShow = false;
    }
    return isShow;
  }

  mounted() {
    if (this.imageList.length > this.value.length) {
      this.imageList.length = this.value.length; // 切掉多的
    }
    for (let i = 0; i < this.value.length; i++) {
      let img = this.imageList[i] ?? new ImageItem();
      img.value = this.value[i];
      img.state = "uploaded";
    }
  }

  getStateText(index: number) {
    let img = this.imageList[index];
    let txt = "";
    switch (img.state) {
      case "pre":
        txt = "准备上传";
        break;
      case "uploading":
        txt = "上传中...";
        break;
      case "uploaded":
        txt = "上传完成";
        break;
      case "fail":
        txt = "上传失败";
        break;
    }
    return txt;
  }

  chooseImage() {
    uni.chooseImage({
      count: this.limit - this.imageList.length,
      success: e => {
        let imageArr: ImageItem[] = [];
        for (let i = 0; i < e.tempFilePaths!.length; i++) {
          let len = this.imageList.length;
          if (len >= this.limit) {
            uni.showToast({
              title: `最多可上传${this.limit}张图片`,
              icon: "none"
            });
            break;
          }
          let path = e.tempFilePaths![i] as string;
          let item = new ImageItem();
          item.preValue = path;
          item.state = "pre";
          imageArr.push(item);
          this.imageList.push(item);
        }
        //this.change();
        for (let item of imageArr) {
          this.uploadImage(item); // 不等待,并行上传
        }
      }
    });
  }

  reUpload(index: number) {
    let img = this.imageList[index];
    this.uploadImage(img);
  }

  /**上传单个照片 */
  uploadImage(img: ImageItem) {
    img.state = "uploading";
    if (this.uploadApi == null || this.uploadApi == "") {
      img.state = "uploaded";
      return;
    }
    httpClient
      .uploadFile<ApiResult<string>>(this.uploadApi, {
        filePath: img.preValue,
        fileType: "image",
        name: this.filedName
      })
      .then(x => {
        if (x.data.successed) {
          img.state = "uploaded";
          img.value = (x.data as any)[this.OutField] as string;
          this.emitAdd(img.value);
        } else {
          img.state = "fail";
        }
      })
      .catch(err => {
        console.log(err);
        img.state = "fail";
      });
  }

  delImage(index: number) {
    let item = this.imageList[index];
    this.imageList.splice(index, 1);
    if (item.state == "uploaded") {
      this.emitDelete(item.value as string);
    }
  }

  previewImage(index: number) {
    let item = this.imageList[index];
    uni.previewImage({
      current: item.image,
      loop: true,
      urls: this.imageList.map(x => x.image)
    });
  }
}

class ImageItem {
  value?: string;
  preValue?: string;
  state: UpStates = "uploaded";
  get image() {
    return this.value ?? this.preValue;
  }
}
type UpStates = "pre" | "uploading" | "uploaded" | "fail";
</script>
<style lang="scss" scoped>
@font-face {
  font-family: "tuiUpload";
  src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAATcAA0AAAAAByQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAEwAAAABoAAAAciR52BUdERUYAAASgAAAAHgAAAB4AKQALT1MvMgAAAaAAAABCAAAAVjxvR/tjbWFwAAAB+AAAAEUAAAFK5ibpuGdhc3AAAASYAAAACAAAAAj//wADZ2x5ZgAAAkwAAADXAAABAAmNjcZoZWFkAAABMAAAAC8AAAA2FpiS+WhoZWEAAAFgAAAAHQAAACQH3QOFaG10eAAAAeQAAAARAAAAEgwAACBsb2NhAAACQAAAAAwAAAAMAEoAgG1heHAAAAGAAAAAHwAAACABEgA2bmFtZQAAAyQAAAFJAAACiCnmEVVwb3N0AAAEcAAAACgAAAA6OMUs4HjaY2BkYGAAYo3boY/i+W2+MnCzMIDAzb3qdQj6fwPzf+YGIJeDgQkkCgA/KAtvAHjaY2BkYGBu+N/AEMPCAALM/xkYGVABCwBZ4wNrAAAAeNpjYGRgYGBl0GJgZgABJiDmAkIGhv9gPgMADTABSQB42mNgZGFgnMDAysDA1Ml0hoGBoR9CM75mMGLkAIoysDIzYAUBaa4pDA7PGJ9xMjf8b2CIYW5gaAAKM4LkANt9C+UAAHjaY2GAABYIVmBgAAAA+gAtAAAAeNpjYGBgZoBgGQZGBhBwAfIYwXwWBg0gzQakGRmYnjE+4/z/n4EBQksxSf6GqgcCRjYGOIeRCUgwMaACRoZhDwCiLwmoAAAAAAAAAAAAAAAASgCAeNpdjkFKw0AARf/vkIR0BkPayWRKQZtYY90ohJju2kOIbtz0KD1HVm50UfEmWXoAr9ADOHFARHHzeY//Fx8Ci+FJfIgdJFa4AhgiMshbrCuIsLxhFJZVs+Vl1bT1GddtbXTC3OhohN4dg4BJ3zMJAnccyfm468ZzHXddrH9ZKbHzdf9n/vkY/xv9sPQXgGEvBrHHwst5kTbXLE+YpYVPkxepPmW94W16UbdNJd6f3SAzo5W7m1jaKd+8ZZIvk5nlKw9SK6Wle7BLS3f/bTzQLmfAF2T1NsQAeNp9kD1OAzEQhZ/zByQSQiCoXVEA2vyUKRMp9Ailo0g23pBo1155nUg5AS0VB6DlGByAGyDRcgpelkmTImvt6PObmeexAZzjGwr/3yXuhBWO8ShcwREy4Sr1F+Ea+V24jhY+hRvUf4SbuFUD4RYu1BsdVO2Eu5vSbcsKZxgIV3CKJ+Eq9ZVwjfwqXMcVPoQb1L+EmxjjV7iFa2WpDOFhMEFgnEFjig3jAjEcLJIyBtahOfRmEsxMTzd6ETubOBso71dilwMeaDnngCntPbdmvkon/mDLgdSYbh4FS7YpjS4idCgbXyyc1d2oc7D9nu22tNi/a4E1x+xRDWzU/D3bM9JIbAyvkJI18jK3pBJTj2hrrPG7ZynW814IiU68y/SIx5o0dTr3bmniwOLn8owcfbS5kj33qBw+Y1kIeb/dTsQgil2GP5PYcRkAAAB42mNgYoAALjDJyIAOWMGiTIxMjMxsKak5qSWpbFmZiRmJ+QAmgAUIAAAAAf//AAIAAQAAAAwAAAAWAAAAAgABAAMABAABAAQAAAACAAAAAHjaY2BgYGQAgqtL1DlA9M296nUwGgA+8QYgAAA=)
    format("woff");
  font-weight: normal;
  font-style: normal;
}
.tui-upload-icon {
  font-family: "tuiUpload" !important;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  padding: 10rpx;
}
.tui-icon-delete:before {
  content: "\e601";
}
.tui-icon-plus:before {
  content: "\e609";
}
.tui-upload-box {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
}
.tui-upload-add {
  width: 220rpx;
  height: 220rpx;
  font-size: 68rpx;
  font-weight: 100;
  color: #888;
  background-color: #f7f7f7;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.tui-image-item {
  width: 220rpx;
  height: 220rpx;
  position: relative;
  margin-right: 20rpx;
  margin-bottom: 20rpx;
}
.tui-image-item:nth-of-type(3n) {
  margin-right: 0;
}
.tui-item-img {
  width: 220rpx;
  height: 220rpx;
  display: block;
}
.tui-img-del {
  width: 36rpx;
  height: 36rpx;
  position: absolute;
  right: -12rpx;
  top: -12rpx;
  background: #eb0909;
  border-radius: 50%;
  color: white;
  font-size: 34rpx;
  z-index: 999;
}
.tui-img-del::before {
  content: "";
  width: 16rpx;
  height: 1px;
  position: absolute;
  left: 10rpx;
  top: 18rpx;
  background: #fff;
}
.tui-upload-mask {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-around;
  padding: 40rpx 0;
  box-sizing: border-box;
  background: rgba(0, 0, 0, 0.6);
}
.tui-upload-loading {
  width: 28rpx;
  height: 28rpx;
  border-radius: 50%;
  border: 2px solid;
  border-color: #b2b2b2 #b2b2b2 #b2b2b2 #fff;
  animation: tui-rotate 0.7s linear infinite;
}
@keyframes tui-rotate {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}
.tui-tips {
  font-size: 26rpx;
  color: #fff;
}
.tui-mask-btn {
  padding: 6rpx 16rpx;
  border-radius: 40rpx;
  text-align: center;
  font-size: 24rpx;
  color: #fff;
  border: 1rpx solid #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
.tui-hover {
  opacity: 0.5;
}
</style>

使用swipe-action乱码问题

<view class="container"> <tui-swipe-action :actions="actions" @click="handlerButton" v-for="(item,index) in cartList" :key="index" :params="item"> <template v-slot:content> <view class="list-item"> <!-- <image :src="'../../static/images/news/'+item.img+'.jpg'" class="item-img"></image> --> <view class="item-box"> <view class="item-title">{{item.title}}</view> <view class="item-time">2019-06-01</view> </view> </view> </template> </tui-swipe-action> </view>

import tuiSwipeAction from '@/components/swipe-action/swipe-action.vue';

actions: [{
name: '删除',
color: '#fff',
fontsize: 30,//单位upx
width: 80, //单位px
//icon: 'like.png',//此处为图片地址
background: '#ed3f14'
},
]
使用方式都是按照demo的使用方式来使用的,但是我的在显示时出现了乱码的情况,这个是什么问题呢?
“删除”变成了这个“ɾ��”

uniapp运行时报错

项目 'ThorUI组件库' 开始编译...
17:26:38.174 请注意运行模式下,因日志输出、sourcemap以及未压缩源码等原因,性能和包体积,均不及发行模式。
17:26:38.188 正在编译中...
17:26:39.323 INFO Starting development server...
17:27:16.034 WARNING: Module Warning (from ./node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/templateLoader.js):
17:27:16.046 (Emitted value instead of an instance of Error) : component lists rendered with v-for should have explicit keys. See https://vuejs.org/guide/list.html#key for more info.
17:27:16.047 Module Warning (from ./node_modules/postcss-loader/src/index.js):
17:27:16.057 Warning
17:27:16.057 (393:2) Gradient has outdated direction syntax. Replace cover to farthest-corner.
17:27:16.064 Module Warning (from ./node_modules/postcss-loader/src/index.js):
17:27:16.074 Warning
17:27:16.074 (393:2) Second Autoprefixer control comment was ignored. Autoprefixer applies control comment to whole block, not to next rules.
17:27:16.080 Module Warning (from ./node_modules/postcss-loader/src/index.js):
17:27:16.081 Warning
17:27:16.086 (394:2) Gradient has outdated direction syntax. Replace cover to farthest-corner.
17:27:16.087 Module Warning (from ./node_modules/postcss-loader/src/index.js):
17:27:16.093 Warning
17:27:16.094 (399:2) Gradient has outdated direction syntax. Replace cover to farthest-corner.
17:27:16.100 Module Warning (from ./node_modules/postcss-loader/src/index.js):
17:27:16.101 Warning
17:27:16.106 (402:2) Gradient has outdated direction syntax. Replace cover to farthest-corner.
17:27:16.107 Module Warning (from ./node_modules/postcss-loader/src/index.js):
17:27:16.112 Warning
17:27:16.116 (415:2) Gradient has outdated direction syntax. Replace cover to farthest-corner.
17:27:16.121 App running at:
17:27:16.126 - Local: http://localhost:8080/
17:27:16.127 - Network: http://192.168.31.100:8080/

actionsheet组件bug

actionsheet
报错:Props with type Object/Array must use a factory function to return the default value.
需要修改成:
//菜单按钮数组,自定义文本颜色,红色参考色:#e53a37 itemList: { type: Array, default:() => [{ text: "确定", color: "#1a1a1a" }] },

tui-button组件对微信form submit捕捉事件问题

使用tui-button组件不能触发formsubmit事件
修改前,这种使用方式不能触发

<form @submit="handleSubmit">
    <tui-button formType="submit" type="primary">提交</tui-button>
</form>

修改后,这种方式可以正确捕获

<form @submit="handleSubmit">
    <button class="tui-btn tui-primary" hover-class="tui-primary-hover" formType="submit">提交</button>
</form>

app端扩展组件tabBar中间按钮凸起样式有问题

app端扩展组件tabBar中间按钮凸起样式有问题:蓝色图片不在凸起的半圆中间位置

另外就是直接导入组件库运行报错。
nvue中不支持如下css。如全局或公共样式受影响,建议将告警样式写在ifndef APP-PLUS-NVUE的条件编译中,详情如下:
23:39:23.574 ERROR: Selector page is not supported. Weex only support single-classname selector at App.vue:18
23:39:23.586 WARNING: background is not a standard property name (may not be supported), suggest background-color at App.vue:19
23:39:23.586 WARNING: display is not a standard property name (may not be supported) at App.vue:23
23:39:23.596 WARNING: box-sizing is not a standard property name (may not be supported) at App.vue:25
23:39:23.596 ERROR: Selector button::after is not supported. Weex only support single-classname selector at App.vue:31
23:39:23.606 WARNING: border is not a standard property name (may not be supported) at App.vue:32
23:39:23.621 WARNING: background is not a standard property name (may not be supported), suggest background-color at App.vue:38
23:39:23.630 WARNING: white-space is not a standard property name (may not be supported) at App.vue:42
23:39:23.643 WARNING: content is not a standard property name (may not be supported) at App.vue:50
23:39:23.643 WARNING: border-bottom is not a standard property name (may not be supported) at App.vue:52
23:39:23.661 WARNING: -webkit-transform is not a standard property name (may not be supported) at App.vue:53
23:39:23.677 WARNING: border-bottom is not a standard property name (may not be supported) at App.vue:60
23:39:23.678 WARNING: background is not a standard property name (may not be supported), suggest background-color at App.vue:67
23:39:23.698 WARNING: background is not a standard property name (may not be supported), suggest background-color at App.vue:74
23:39:23.698 WARNING: background is not a standard property name (may not be supported), suggest background-color at App.vue:77
23:39:23.710 WARNING: background is not a standard property name (may not be supported), suggest background-color at App.vue:81
23:39:23.710 WARNING: background is not a standard property name (may not be supported), suggest background-color at App.vue:85
23:39:23.721 WARNING: background is not a standard property name (may not be supported), suggest background-color at App.vue:89
23:39:23.722 WARNING: background is not a standard property name (may not be supported), suggest background-color at App.vue:94

对formValidation的一点改进

场景

{
					name: "weight",
					rule: ["isAmount","range:[40,300]"],
					msg: ["请输入正确的体重,允许两位小数", "体重在40~300公斤之间,请检查"]
				}

这种情况下,字段非必须输入的,也就是没有"required"验证规则,不输入,没问题,但是真的输入了,仍然需要对合法性进行校验。

改进

formValidation.js/validation函数:

..........
validation: function(formData, rules) {
		for (let item of rules) {
			let key = item.name;
			let rule = item.rule;
			let msgArr = item.msg;
			if (!key || !rule || rule.length === 0 || !msgArr || msgArr.length === 0) {
				continue;
			}
			//规则中不包含:"required",则为非必填
			let isValid = rule.indexOf('required') == -1;
			for (let i = 0, length = rule.length; i < length; i++) {
				let ruleItem = rule[i];
				let msg = msgArr[i];
				if (!ruleItem || !msg) {
					continue;
				}
				//数据处理
				let value = null;
				if (~ruleItem.indexOf(":")) {
					let temp = ruleItem.split(":");
					ruleItem = temp[0];
					value = temp[1];
				}
				///没设置required规则,也没输入数据,则直接返回,也就是允许为空
				if (isValid && formData[key].length <= 0) {
					return "";
				}
				//否则,仍然继续验证
				let isError = false;
				switch (ruleItem)
..........

建议增加table组件

建议增加table组件,一些单据类列表管理,还是有很多地方会使用到。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.