【vue备忘】使用require引入图片、$emit、public文件夹、$refs以及视图不更新等问题

8854次阅读 570人点赞 作者: WuBin 发布时间: 2021-02-24 09:29:04
扫码到手机查看

常用小技巧

this.$el[vue3]

在vue3中,获取组件的元素DOM节点,可以直接使用this.$el(它指的是当前组件的的元素)。比如一个组件:

<template>
<div
  class="progress-bar"
>
    <div
      class="progress-btn-wrapper"
      @touchstart.prevent="onTouchStart"
      @touchmove.prevent="onTouchMove"
      @touchend.prevent="onTouchEnd"
    >
    </div>
  </div>
</div>
</template>

这时候,使用this.$el获取的就是整个div.progress-bar这个DOM元素。

const progressBtnWidth = 16
onTouchMove(e) {
      const barWidth = this.$el.clientWidth - progressBtnWidth
}

上面获取的就是div.progress-bar的DOM元素宽度。但是值得注意的是:

this.$el是在mounted中才会出现的,在created的时候是没有的。

区分生产环境与开发环境

const debug = process.env.NODE_ENV !== 'production';
const url = debug ? localUrl : onlineUrl; 
// true就是本地开发环境,是false就是线上环境
// 如果是线上的环境
process.env.NODE_ENV === "development"

在组件中的Img标签引用本地图片

在组件中,需要引用本地图片资源,这个跟传统开发是有所区别的,如

<template>
  <img :src="localImg">
</template>
<script type="text/ecmascript-6">
  data() {
    return {
      localImg: require('../loading/myimg.jpg')
    }
  },
</script>

其中,目录结构是 src>components>loading>loading.vue, myimg.jpg 

vue文件和图片是同级目录  ../ 就是指的components目录

在vue3中使用@指代src目录:

loading: require('@/assets/images/default.png')

require是webpack提供的方法,他会自己判断是生成引用图片还是转化为base64格式的图片。

如果在HTML中引入同级目录下的图片(如在loading.vue中):

<img width="24" height="24" src="./loading.gif">

其中 loading组件目录下有loading.vue和loading.gif两个子文件。

require是vue-cli中的方法,在vite中是无法使用的,在vite中替代的方式:https://www.jb51.net/article/281969.htm

this.$emit向外发送事件

子组件向父组件发送事件

// children.vue
this.$emit('created', 参数1, 参数2...);

// father.vue
<children @created="getParams" />
methods: {
  getParams(参数1, 参数2) { ... }
}

如果父组件仅仅接收子组件的参数,那么父组件监听的时候,触发的方法只写方法名  ,不能加()否侧就接收不到传过来的数据了。

如果父组件接收事件的函数也要使用父组件的参数,那么就需要:

// child
this.$emit('freeDrop', child_args);

// father
<div v-for="(item, index) in datas" ...>
    <child @freeDrop="changeImg($event, index)">
</div>
methods:{
   changeImg(child_args, father_index) {
         console.log(child_args子组件传递的参数,  father_index父组件传递的index参数)
   }
} 

父组件用$event代表change事件对象,后面传递父元素自己的参数。index代表了父组件自己的第一个参数。

this.$refs获取DOM以及组件

1、如果获取的是一个DOM元素

<div ref="box">...</div>
this.$refs.box.style.color = 'red';

这时候this.$refs.box获取的就是div这个DOM元素

2、如果引用的是一个组件

<scroll ref="list"></scroll>
// this.$refs.list获取这个组件的实例,并执行组件的open()方法
this.$refs.list.open();

如果需要获取组件的DOM结构呢?

this.$refs.list.$el.style.top = '...'

public文件夹

放置在public文件夹的静态资源都会被简单的复制,而不经过 webpack。你需要通过绝对路径来引用它们。

在vue.config中,设置publicPath

module.exports = {
    // 打包文件的路径,设置为空,那么打包后的路径就是
   // script src="js/xxx"(js之前就是publicPath)
    publicPath:'',
}

在public/index.html中,通过<%= BASE_URL %>设置链接前缀(BASE_URL即是publicPath

<link rel="icon" href="<%= BASE_URL %>favicon.ico">

如果要在组件中使用,那么需要通过process.env.BASE_URL获得 (官方解释链接)

<iframe :src="`${publicPath}iframe/loading/index.html`" frameborder="0"></iframe>
// 然后在组件的JS中
data() {
    return {
      // 引用public文件夹的路径
      publicPath: process.env.BASE_URL
    }
}

Vue数据视图不更新

在一个组件实例中,只有在data里初始化的数据才是响应的,Vue不能检测到对象属性的添加或删除,没有在data里声明的属性不是响应的。Vue不允许在已经创建的实例上动态添加根级响应式属性

数组数据变动,使用某些方法操作数组,变动数据时,有些方法无法被vue监测。

push(),pop(),shift(),unshift(),splice(),sort(),reverse()

可被vue检测到,而filter(),concat(),slice()。这些不会改变原始数组,但总是返回一个新数组。则不会被检测到,可以用新数组替换旧数组。

vue不能检测以下变动的数组:

  • 当你利用索引直接设置一个项时,vm.items[indexOfItem] = newValue
  • 当你修改数组的长度时,例如:vm.items.length = newLength

如果修改数组中的值,应该使用splice()进行替换。
<li class="sliders-li"
      v-for="(item, index) in slider"
      :key="'sld' + index"
      :data-fold="`${isFolds[index]}`"
>
props: {
    slider: {
      type: Array,
      default() {
        return []
      }
    }
  },
data() {
    return {
      isFolds: []
    }
},
created() {
    this.setItemsFolds();
},
methods: {
    setItemsFolds() {
      setTimeout(() => {
        this.slider.forEach(() => {
          this.isFolds.push(false);
        });
      }, 200);
    },
toggleFoldItem(index) {
      let now = this.isFolds[index];
      // 如果使用this.isFolds[index] = !now 那么就不会被响应到!
      this.isFolds.splice(index, 1, !now);
      console.log(this.isFolds)
    }
} 

或者使用 this.$forceUpdate(); 强制更新视图。

eslint检查忽略

在书写代码时,经常会遇到:调试某一个部分的时候,去阻断其他的事件,这时候,往往会有一个报错,提示XXX没有使用,这时候,就需要忽略eslint的检查了。
// 忽略下方代码的eslint检查:
/* eslint-disable */
alert(‘foo’);

// 针对某一行禁用eslint检查:
alert(‘foo’); // eslint-disable-line

// 文件中禁用多项eslint规则的检查:
/* eslint-disable no-alert, no-console */
alert(‘foo’);
console.log(‘bar’);

v-for直接循环数字,固定循环次数

<li class="item"
      v-for="index of nums"
      :key="index"
>
data() {
    return {
        nums: 8
    }
}
// 或者直接:
v-for="index of 8"

vue中数据的深拷贝

当组件间传递对象时,由于此对象的引用类型指向的都是一个地址(除了基本类型跟null,对象之间的赋值,只是将地址指向同一个,而不是真正意义上的拷贝)。如

// 变量 var和let的结果相同
var e = 1;
var f = e;
f = 10;
console.log(e); // 1
//  数组
var a = [1,2,3];
var b = a;
b.push(4); // b中添加了一个4
console.log(a) // a变成了[1,2,3,4]
// 对象
let c = {x: 1, y: 2};
let d = c;
d.z = 100;
console.log(c) // {x: 1, y: 2, z: 100}

这就是由于对象类型直接赋值,只是将引用指向同一个地址,导致修改了obj会导致obj2也被修改。

所以let arr = this.data; arr.forEach(item => { item.xx = xx; }) 结果发现this.data中的xx属性也改变了。

要避免这种情况,就要使用一点点技巧,对数据进行深度拷贝。

// 对象
 var obj={}; 
// this.maindata 是在data中注册的对象
bj=JSON.parse(JSON.stringify(this.maindata)); 

// 数组: 使用解构赋值
let arr = [...this.mainArr]

npm常用操作

npm查询版本

npm -v

npm安装模块

npm install xxx】利用 npm 安装xxx模块到当前命令行所在目录;
【npm install -g xxx】利用npm安装全局模块xxx;

npm卸载模块

npm uninstall xxx】删除xxx模块;
【npm uninstall -g xxx】删除全局模块xxx;

本地安装时将模块写入package.json中

【npm install xxx】安装但不写入package.json;
【npm install xxx –save】 安装并写入package.json的”dependencies”中;
【npm install xxx --save-dev】 安装并写入package.json的”devDependencies”中

npm 安装淘宝镜像

npm install -g cnpm --registry=https://registry.npm.taobao.org

npm查看源

npm config get registry

改为镜像源

// 改为官方镜像源
npm config set registry https://registry.npmjs.org/
// 改为淘宝镜像源
npm config set registry http://registry.npm.taobao.org/

相关资料

点赞 支持一下 觉得不错?客官您就稍微鼓励一下吧!
关键词:vue中常用小技巧、备忘
推荐阅读
  • uniapp实现被浏览器唤起的功能

    当用户打开h5链接时候,点击打开app若用户在已经安装过app的情况下直接打开app,若未安装过跳到应用市场下载安装这个功能在实现上主要分为两种场景,从普通浏览器唤醒以及从微信唤醒。

    9094次阅读 588人点赞 发布时间: 2022-12-14 16:34:53 立即查看
  • Vue

    盘点Vue2和Vue3的10种组件通信方式

    Vue中组件通信方式有很多,其中Vue2和Vue3实现起来也会有很多差异;本文将通过选项式API组合式API以及setup三种不同实现方式全面介绍Vue2和Vue3的组件通信方式。

    3843次阅读 286人点赞 发布时间: 2022-08-19 09:40:16 立即查看
  • JS

    几个高级前端常用的API

    推荐4个前端开发中常用的高端API,分别是MutationObserver、IntersectionObserver、getComputedstyle、getBoundingClientRect、requ...

    14071次阅读 914人点赞 发布时间: 2021-11-11 09:39:54 立即查看
  • PHP

    【正则】一些常用的正则表达式总结

    在日常开发中,正则表达式是非常有用的,正则表达式在每个语言中都是可以使用的,他就跟JSON一样,是通用的。了解一些常用的正则表达式,能大大提高你的工作效率。

    12908次阅读 442人点赞 发布时间: 2021-10-09 15:58:58 立即查看
  • 【中文】免费可商用字体下载与考证

    65款免费、可商用、无任何限制中文字体打包下载,这些字体都是经过长期验证,经得住市场考验的,让您规避被无良厂商起诉的风险。

    11469次阅读 920人点赞 发布时间: 2021-07-05 15:28:45 立即查看
  • Vue

    Vue3开发一个v-loading的自定义指令

    在vue3中实现一个自定义的指令,有助于我们简化开发,简化复用,通过一个指令的调用即可实现一些可高度复用的交互。

    15588次阅读 1244人点赞 发布时间: 2021-07-02 15:58:35 立即查看
  • JS

    关于手机上滚动穿透问题的解决

    当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。在PC上使用css即可解决,但是在手机端,情况就变的比较复杂,就需要禁止触摸事件才可以。

    14795次阅读 1205人点赞 发布时间: 2021-05-31 09:25:50 立即查看
  • Vue

    Vue+html2canvas截图空白的问题

    在使用vue做信网单页专题时,有海报生成的功能,这里推荐2个插件:一个是html2canvas,构造好DOM然后转canvas进行截图;另外使用vue-canvas-poster(这个截止到2021年3月...

    28950次阅读 2273人点赞 发布时间: 2021-03-02 09:04:51 立即查看
  • Vue

    vue-router4过度动画无效解决方案

    在初次使用vue3+vue-router4时候,先后遇到了过度动画transition进入和退出分别无效的情况,搜遍百度没没找到合适解决方法,包括vue-route4有一些API都进行了变化,以前的一些操...

    24982次阅读 1925人点赞 发布时间: 2021-02-23 13:37:20 立即查看
交流 收藏 目录