vue+element使用笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。有问题可加微信meizu_mx4 https://blog.csdn.net/sinat_15955423/article/details/87783150

前言:我使用的是vue+element admin,里面用的组件都来自于element.eleme.io

备注:host:如果配置为127.0.0.1,只能本机访问,如果配置为0.0.0.0,则可以局域网访问

如果想内网穿透:报 invalid host header,只需在webpack.dev.conf.js加上

 
devServer: {
    disableHostCheck: true,
}

以下都是我使用过程中用到的小窍门我会记录下来:

1.获取表格tableData的索引值,注意不是每列里的key,是index

使用:scope.$index

效果:比如我想要只在第一列显示增加按钮

那我可以加一个

v-if="scope.$index === 0"

效果:

2.判断对象是否为空可以用ES6语法判断它的长度

Object.keys(this.form.paramList).length === 0

3.vue在数组指定位置追加列

 this.tableDataGzh.splice(-1, 0, list);//在倒数第二列追加

实现效果在追加和删除:

4.element里togglerowselection无效爬坑

官网demo: http://element-cn.eleme.io/#/duo-xuan

我想在打开编辑框时默认就选中为true的数据,可是官方demo没有详细说这个咋用,我一直以为那个row是对应的行数字

官方代码:

rows.forEach(row => {
            this.$refs.multipleTable.toggleRowSelection(row);
          });

我测试官方的row就是数字,然后我在我的项目里这样写无效果。

解决代码:

this.tableDataGzh.map((tableinfo, index) => {
                        if (tableinfo['isApi'] === true) {
                            this.$nextTick(() => {   // 延迟回调
                                console.log(this.$refs["multipleTable"])
                                this.$refs["multipleTable"].toggleRowSelection(this.tableDataGzh[index], true);
                            })
                        }
                    })

实际上要传的是对应的列,不是第几列数。说明:

multipleTable是对应table的ref

效果:

5.element的多选框实现单选:

vue:

<el-table-column label="放大关键词">
    <template slot-scope="scope">
      <el-checkbox v-model="scope.row.isBigWord" 
                   @change="handleChecked(scope.$index)">
      </el-checkbox>
    </template>
</el-table-column>

 js:

handleChecked(val) {
    for (let i = 0; i < this.tableDataXcx.length; i++) {
        if (i !== val) {
            this.tableDataXcx[i]['isBigWord'] = false;
        }
    }
},

6.格式化时间

在 utils目录里的index.js里写:

export function parseTime(time, cFormat) {
  if (arguments.length === 0) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if (('' + time).length === 10) time = parseInt(time) * 1000
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

export function formatTime(time, option) {
  time = +time * 1000
  const d = new Date(time)
  const now = Date.now()

  const diff = (now - d) / 1000

  if (diff < 30) {
    return '刚刚'
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + '分钟前'
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前'
  } else if (diff < 3600 * 24 * 2) {
    return '1天前'
  }
  if (option) {
    return parseTime(time, option)
  } else {
    return (
      d.getMonth() +
      1 +
      '月' +
      d.getDate() +
      '日' +
      d.getHours() +
      '时' +
      d.getMinutes() +
      '分'
    )
  }
}

然后把这个文件在script里引入:

import {parseTime} from '@/utils'

vue文件里写:

<el-table-column :label="$t('messageManage.createTime')" min-width="100" align="center">
    <template slot-scope="scope">
        <span>{{ scope.row.createTime/1000 | formatTime }}</span>
    </template>
</el-table-column>

效果:

vue里写:

<el-table-column :label="$t('messageManage.createTime')" min-width="100" align="center">
    <template slot-scope="scope">
        <span>{{ scope.row.createTime | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
    </template>
</el-table-column>

效果:

js:

this.tableData.list.forEach(message => {
     /* 格式化时间 */
     if (message.createTime) {
         message.createTime = parseTime(message.createTime)
        }
})

 vue:

<el-table-column :label="$t('messageManage.createTime')" prop="createTime" min-width="100" align="center"/>

效果和上面的一个一样

7.[Vue warn]: Error in render: "TypeError: _self.$scopedSlots.default is not a function"报错解决:

经过反复排查,没发现哪里写的有问题,最后在 https://forum.vuejs.org/t/weird-vuejs-error-with-elementui-table-self-scopedslots-default-is-not-a-function/12933/4找到答案

1.要么把v-if改成v-show

2.要么用v-if的时候加个key属性

8.Select 选择器在编辑时默认值不显示对应的名称

因为前期没那么多数据,就先把下拉写成死的,却遇到编辑页不显示对应名称的问题,但是不写死的那种都是OK的。最后看接口返回值发现返回的key不是string类型而是number,以后写死值的时候一定要注意类型

改成

效果:

9.element的select下拉选中不显示对应的项

因为上面一个下拉框选中会联动下面一个下拉框,上面一个下拉框选中后应该把下面的下拉框选中值重置,我之前是直接把的值设为null,在编辑时没事,但是新增时上面选中后,下面的下拉框选中不显示内容,于是我加了个判断,就是在下面一个下拉判断是不是之前有值,有就设为null,这样就可以避免在新增时下拉框选中不显示值的问题,还可以在上面一个下拉更改时,下面的框被重置掉

10.element如何并排显示,用<el-col></el-col>给span,整个span默认应该是分成了24块,下面的span和不超过24就行,

:gutter="50"这个值是块之间间隔
<el-row :gutter="50">
 <el-col :span="10">
  <el-form-item :label-width="formLabelWidth" label="主订单号:">
    123
  </el-form-item> 
 </el-col>
 <el-col :span="8">
  123
 </el-col>
 <el-col :span="6">
  123
 </el-col>
</el-row>

效果图:

不加gutter

加:gutter="50"

11.2019-3-15今天遇到浏览器接收接口response和preview的显示的值还不一样,发现原来接口传的那个值是long类型,js会把它给精度丢失掉,浏览器显示的值用的preview的值,显示时少了一位,建议转成string

12.js转换数组某列类型

getBizTypeByBizId(params).then(res => {
    const _data = res.data
    if (_data && _data.code === '200') {
        let BizIdOptions = _data.data
        this.BizIdOptions = BizIdOptions.map((item) => {
            item.bizId = Number(item.bizId)
            return{
                ...item,
            }
        });
    }
}).catch(err => {
    console.log(err.stack)
})

 效果:

13.上传图片限制高宽

官网的demo没有说怎么限制高宽(像素) 只有大小和图片格式

官网:

修改后:

<el-form-item :label-width="formLabelWidth" label="店铺logo" prop="shopLogoUrl">
    <el-upload
            class="avatar-uploader"
            action="/ms-api/account/uploadScenicAccountPic"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload">
        <img v-if="imageUrl" :src="imageUrl" class="avatar">
        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
    </el-upload>
    <span>图片格式:png;图片尺寸:150x150</span>
</el-form-item>
handleAvatarSuccess(res, file) {
    if (res.code === '200') {
        this.imageUrl = res.data[0].url
        this.form.shopLogoUrl = this.imageUrl
    } else {
        this.$notify({
            title: "失败",
            message: res.msg,
            type: "error",
        });
    }
},
beforeAvatarUpload(file) {
    const isPNG = file.type === 'image/png';
    const isLt2M = file.size / 1024 / 1024 < 2;

    if (!isPNG) {
        this.$message.error('上传图片只能是 PNG 格式!');
    }
    if (!isLt2M) {
        this.$message.error('上传图片大小不能超过2M!');
    }
    const isSize = new Promise(function(resolve, reject) {
        let width = 150;
        let height = 150;
        let _URL = window.URL || window.webkitURL;
        let image = new Image();
        image.onload = function() {
            let valid = image.width === width && image.height === height;
            valid ? resolve() : reject();
        };
        image.src = _URL.createObjectURL(file);
    }).then(
        () => {
            return file;
        },
        () => {
            this.$message.error('上传图片尺只能是 150*150!');
            return Promise.reject();
        }
    );
    return isPNG && isLt2M && isSize;
},

猜你喜欢

转载自blog.csdn.net/sinat_15955423/article/details/87783150