vue开发遇到的问题及解决方法(自用)

vue项目创建很慢的解决方法

检查node和npm版本是否过低

node -v
npm -v

更新npm和node

npm install -g npm
npm install -g n

更改淘宝镜像

npm config set registry [https://registry.npm.taobao.org](https://registry.npm.taobao.org/) --global

npm config set disturl [https://npm.taobao.org/dist](https://npm.taobao.org/dist) --global

axios请求中,参数只传递一个值,而非一个对象

// 在请求中加入以下内容
headers: {
  'Content-Type': 'application/json;'
}

vue文件流(blob)下载

// 在axios请求中加入以下内容
responseType: 'blob'

调整element ui组件样式

方法一
在不带scoped的style标签中写样式。最好在要调整的组件的外面报上一层标签,给这个标签设置class。这样防止修改整个项目中的该el标签样式
方法二
使用样式穿透/deep/

el-table多选,换页回显

// 给el-table绑定属性row-key,可以定义一个函数,这个函数要返回独一无二的值作为row-key
// 给多选框列绑定属性 :reserve-selection="true"
<el-table
  :row-key="getRowKeys"
>
  <el-table-column header-align="center" align="center"
    type="selection"
    min-width="40"
    :reserve-selection="true"
  >
  </el-table-column>
</el-table>

getRowKeys (row) {
  return row.id
}

微信端项目调试

1.npm serve
2.下载微信开发者工具
3.用开发者工具访问项目链接
4.用微信登录
5.在开发者工具中获取token等数据,在项目的相应位置设置这些数据(如vuex中)。
6.在浏览器中访问项目链接

el-tabs下边框线

是.el-tabs__nav-wrap::after的样式

父元素min-height

父元素设置了min-height,子元素无法继承height属性,即子元素height: xxx%无效
解决:给父元素外层再包一层div,并给外层的这个div设置display:flex

<div class = "main-outer">
  <div class = "main">
    <div class = "son">
    </div>
  </div>
</div>

<style lang = "less">
.main-outer{
  display: flex;
  .main {
    min-height: 200px;
    .son {
      height: 50%;
    }
  }
}
</style>

备注!!!!!!!!!!!!!!!!!!!!!!

如果给父元素设置了定位(非static),且子元素是absolute定位,或fixed定位(但父元素要设置transform或perspective 或 filter,才能将视口改为父元素),则子元素height设置百分比,可以取到用父元素的真实高度(应该是因为子元素设置了absolute后,仅根据非static的父元素来定位,所以高度等数据是在父元素计算完成后才计算的,因此能取到值)
当仅有1个子元素时,也可以父子元素都不加定位,父元素设置display: grid后,子元素高度百分比就可以取到了

el-submenu手机端 水平菜单 子菜单问题

子菜单点击显示/隐藏
点击子菜单的选项,先隐藏再弹出一次
都可以用menu-trigger="click"解决

header main footer布局样式

将footer设置为absolute定位并设定高度h,且为main的子元素。将main设relative定位,且padding-bottom:h

多行文字,超出部分省略号

给元素设置

overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 4;/*文字行数*/
-webkit-box-orient: vertical;

el-upload自动上传文件

<el-upload
// ...
:auto-upload="false"
:on-change="changeFile">

在changeFile中调接口

当路由'/xxx'没有对应组件时

在vue router中,设置

{
  path: '/xxx', 
  redirect: '/xxxxxxx'
}

未定义路由

在routes数组加入

{
  path: '*',
  component: () => import('xxx/xxx.vue')
}

多级路由,title动态修改的问题

在父组件的钩子函数(如mounted)中

document.title = this.$route.meta.title ? this.$route.meta.title : 'default-title'

路由配置中,子组件的meta中写子组件的title
例如parent组件中用<router-view>显示son组件,路由配置如下

{
    path: '/son',
    component: parent,
    children: [
      { path: '', component: son, meta: { title: 'son-title } }
    ]
  }

vue transition页面左右滑动 宽度重绘慢一拍

给切换到的页面加width:100%
在<transition>和<router-view>之间加keep-alive

<img>的src存在referer头限制

在<header>中加

<meta name="referrer" content="no-referrer" />

参见https://www.jianshu.com/p/7a5be2fb7197

创建数组并赋值为0,1,2...n-1

new Array(n).map((cur, index) => index)
 不可行!!!

原因:
https://www.jianshu.com/p/ff5cbc2c69be
js数组对未主动赋值的下标进行“空置”处理,即遍历不到该下标
而...解构可以将数组解构为length长度;apply也有相同的效果,给Array构造函数强行赋值n长度并map遍历

// 用...解构数组
let arr = [...new Array(n)].map((cur, index) => index)
// 或用apply
let arr = Array.apply(null, new Array(n)).map((cur, index) => index)

el-radio取消选择

给el-radio绑定原生点击事件

<el-radio @click.native.prevent="clickRadio('radio1')" v-model="xxx" :label="one">单选框</el-radio>

// 在methos中
clickRadio (e) {
  if (e === 'radio1') {
    if (this.xxx === 'one') {
      this.xxx = 'two'
    } else {
        this.xxx = 'one'
    }
  }
}

vue动态添加对象属性,并将属性值绑定到v-if上。无效,属性改变,视图不变

根据官方文档定义:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。应该使用this.$set(this.obj,属性名,属性值)给对象添加属性

如下写法,点击按钮是无法改变div的显示隐藏的

<div v-for = (cur, index) in list>
  <div v-if = "hide[index]"></div>
  <button @click = "triggerHide(index)"></button>
</div>

data () {
  return {
    list: [.....],
    hide: {}
  }
},
methods: {
  triggerHide (index) {
    this.hide[index] = !this.hide[index]
  }
},
created () {
  this.list.forEach((cur, index)=> {
    this.hide[index] = false
  })
}

正确写法
修改created中的代码

created () {
  this.list.forEach((cur, index)=> {
    this.$set(this.hide, index, !this.hide[index])
  })
}

隐藏除表格外的滚动条

用:not()选择器

:not(.el-table__body-wrapper)::-webkit-scrollbar {
    display: none; /* Chrome Safari */
  }
  :not(.el-table__body-wrapper){
    scrollbar-width: none; /* firefox */
    -ms-overflow-style: none; /* IE 10+ */
  }

  .el-table__body-wrapper{
    scrollbar-width: thin;
    scrollbar-color: #535353 #ededed;
  }
  .el-table__body-wrapper::-webkit-scrollbar {
    /*滚动条整体样式*/
    width : 8px;  /*高宽分别对应横竖滚动条的尺寸*/
    height: 8px;
    display: inline;
  }
  .el-table__body-wrapper::-webkit-scrollbar-thumb {
    /*滚动条里面小方块*/
    border-radius: 8px;
    box-shadow   : inset 0 0 3px rgba(0, 0, 0, 0.1);
    background   : #DDDDDD;
  }
  .el-table__body-wrapper::-webkit-scrollbar-track {
    /*滚动条里面轨道*/
    /*box-shadow   : inset 0 0 5px rgba(0, 0, 0, 0.2);*/
    border-radius: 8px;
    background: rgba(255,255,255,0);
  }

vue折叠动画

https://blog.csdn.net/sriting/article/details/106111020

vue首页骨架屏

vue项目默认的挂载是替换index.html中的<div id="app"></div>,所以可以再该div中加入骨架屏的代码,当打开网页时,会默认显示index.html中原有的div#app,请求资源并挂载后,index.html中的div#app会被替换
骨架屏元素动画参考代码

        .skeleton-bar {
          //width: 500px;
          //height: 50px;
          //border: 1px solid red;
          border: 1px solid #DDDDDD;
          animation: loading 1.4s ease infinite;
          -webkit-animation: loading 1.4s ease infinite;
          background-image: -webkit-gradient(linear, left top, right top, color-stop(25%, #f0f0f0), color-stop(37%, #e3e3e3), color-stop(63%, #f0f0f0));
          background-image: -o-linear-gradient(left, #f0f0f0 25%, #e3e3e3 37%, #f0f0f0 63%);
          background-image: linear-gradient(90deg, #f0f0f0 25%, #e3e3e3 37%, #f0f0f0 63%);
          background-size: 400% 100%

        }
        @-webkit-keyframes loading {
          0% {
            background-position: 100% 50%
          }

          to {
            background-position: 0 50%
          }
        }
        @keyframes loading {
          0% {
            background-position: 100% 50%
          }

          to {
            background-position: 0 50%
          }
        }

PC端vue 滚动分页

核心是监听scroll事件,4个重要数值
scrollTop:滚动条距离顶部的距离
clientHeight:浏览器窗口高度
scrollHeight:列表元素内容的高度
bottomHeight:距离底部多远的时候加载新数据
这4个数值满足以下关系时,加载新数据
scrollTop +clientHeight >= scrollHeight - height

let scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
clientHeight = window.innerHeight,
scrollHeight = this.$refs.xxxxxx.scrollHeight, // xxxxxxx是自己定义的ref
height = 200 // 根据项目需求来

需要注意的问题
1.如果是多层router-view嵌套,要注意scrollTop的值
在浏览器里,一层层网上找,看每一层,之道body的高度是否正确,正确的那个才是能获取到scrollTop的。
我的做法是取消html,body,#app的高度,都是适应内容,所以scrollTop可以用上面的方式获取,否则可能为0
2.注册和取消监听事件
如果router-view没用keep-alive,可以在mounted和beforeDestroy钩子里注册和取消
否则在activated和deactivated里注册和取消

打开弹窗 阻止页面滚动

在打开弹窗时设置

document.body.style.height = '100vh'

v-for 中动态绑定ref

直接绑定会有问题,如获取不到
解决:
vue3中似乎有新特性解决此问题,后面再研究
在v-for中给ref绑定一个固定的字符串,在获取的时候用下标获取

// template
<div v-for="(item, index) in list" ref="itemNode"></div>
// script
this.$refs['itemNode'][index]

vue引入cdn

当组件需要import xxx from 'xxxxx cdn'时,我目前采用的方法肯定不是最优解,但有用。

// 在index.html中,加入
<script id="rendered-js" type="module">
  import xxx from 'xxxxxxxx'

  window.xxx = xxx
</script>
// 在组件中
let xxx = window.xxx

在拦截器中获取当前路由

先引用vue-router对象,用router.currentRoute.path

列表中 不同item高度相等,内容对齐

如商城,很多商品,商品展示图片,名字,价格。名字不一样长,有可能要换行,则只用flex布局对不齐
列表考虑使用grid布局,item使用flex

禁止ios浏览器自动缩放

在index.html的head中加入

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover">

有时手机浏览器会自动放大页面,加入上面的meta禁止页面缩放

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342