标签 前端 下的文章

引言

相信大家平常在开发过程中,经常会遇到此类需求。危险操作(如删除,退出登录)往往需要弹框提示给用户二次确认一下。本文介绍的是,如何使用js方法装饰器,封装二次确认弹框操作,增加小伙伴的开发效率。

装饰器介绍

2020-08-03T08:01:10.png

装饰器是对类、函数、属性之类的一种装饰,可以针对其添加一些额外的行为。详细使用,自行百度!

常规手段

view

<div class="bg-white flex justify-center">
    <div class="btn-primary" @click="clickMe">点我</div>
</div>

js

clickMe() {
    uni.showModal({
      title: "点击提示",
      content: "你确定要点我?",
      success: (res) => {
        if (res.confirm) {
          console.log("点我干啥");
        }
      },
    });
 }

效果展示

装饰器点击效果

装饰器写法

confirm.js

function confirm(message: string, title: string, cancelFn = function() {}) {
  return function(target: any, name: string, descriptor: any) {
    const originFn = descriptor.value;
    descriptor.value = function(rest: any) {
      uni.showModal({
        title: title,
        content: message,
        success: (res) => {
          if (res.confirm) {
            originFn.apply(this, rest);
          }
        },
      });
    };
  };
}

main.js

@confirm("你确定要点我?","点击提示")
  clickMe() {
    // uni.showModal({
    //   title: "点击提示",
    //   content: "你确定要点我?",
    //   success: (res) => {
    //     if (res.confirm) {
    //       console.log("点我干啥");
    //     }
    //   },
    // });
    console.log("点我干啥");
  }

效果展示

装饰器点击效果

Vue环境变量和模式

Vue环境变量和模式

我最开始使用vue的判断环境的方法是

let BASE_URL = process.env.NODE_ENV == "development" ? "http:/localhost" : "xxx"

在这种情况下,需要先判断它的编译环境,进而根据环境适用对应的值。如果只有一个地方的变量跟环境有关,情况还好。但是若有多个,则需要复制多个判断或者封装成一个方法。但也只能使用于两个环境,如果存在多个环境,诸如开发,测试,预发布,正式等环境,这个方法就捉襟见肘了。所以,我们需要设置Vue环境变量和模式,好像webpack也可以实现?(好吧,这不是重点)

实现方式

vue允许你在项目根目录下添加.env.[mode]的文件来指定环境变量。

.env                # 在所有的环境中被载入
.env.local          # 在所有的环境中被载入,但会被 git 忽略
.env.[mode]         # 只在指定的模式中被载入
.env.[mode].local   # 只在指定的模式中被载入,但会被 git 忽略

比如我,我添加了.env.local,.env.development,.env.test,.env.production等文件,.env.local文件内容如下。

.env.local
VUE_APP_BUILD_MODE = 'development'
VUE_APP_BASE_URL = 'http://172.16.6.132:8002/threemiju/'

对应package.json的script如下:

"scripts": {
    "serve": "vue-cli-service serve --mode",
    "serve:test": "vue-cli-service serve --mode test",
    "build:test": "vue-cli-service build --mode test",
    "build:production": "vue-cli-service build --mode production",
    "deploy:test": "git push && git push gitlab dev && vue-cli-service build --mode test"
  },
请注意,此处有一个坑。当你使用yarn run build:test的时候,你会发现,假如你使用了异步组件,却会神奇的发现,它并没有把把代码切割,只编译成了一个app.js文件,这是由于你使用了--mode test, 导致它认为你并不是prodution环境。所以,你需要对.env.test做以下修改
  • .env.test
NODE_ENV = 'production'
VUE_APP_BUILD_MODE = 'test'
VUE_APP_BASE_URL = 'https://m.gileey.cn/threemiju/'

主动设置NODE_ENV即可。

环境变量的使用场景

  1. BASE_URL
export const baseURL = process.env.VUE_APP_BASE_URL;
  1. BUILD_MODE

在显示版本号时同时显示编译环境

<span :title="mode">{{ version }}</span>
data(){
return {mode: process.env.VUE_APP_BUILD_MODE}
}

本地变量(*.local)的一些应用场景

  1. BASE_URL: 在不同的开发机器下,请求不同内网地址
  2. APP_SECRET: 该字段不宜出现在共有仓库

该文章为异教徒解决方案,各位看官看下即可,切勿模仿!!!

问题描述

原生的el-upload只支持上传图片时候的预览和回显,这是因为只针对img标签做了适配,如下图。

2020-06-03T05:42:34.png

而如果我们上传视频,则会出现一个白方框,用户体验不佳。

2020-06-03T05:45:07.png

解决思路

其实正确的解决思路应该是

  1. show-file-list属性设置为false。然后再自己循环显示file-list,以及追加对应的预览,删除按钮及功能。
  2. 设置自定义模板内容(推荐使用)

但是我觉得这样太麻烦了(时间问题)。

于是我突发奇想,如果我将img标签改成video标签呢?如下图

2020-06-03T05:46:56.png

发现居然完美契合,毫无违和感。

预览的实现

在做到把img改为video标签之前,还需要解决的另一个问题就是,如何让视频也支持预览。老规矩,我们先来看看官方Demo怎么实现预览的。

2020-06-03T05:54:03.png

官方的做法是增加一个dialog,然后在点击预览图片时将文件url传给dialog。我们先来实现一下改写一下dialog

<el-dialog :visible.sync="dialogVisible" :modal-append-to-body="true">
      <video width="100%" muted autoplay="autoplay" loop="loop" v-if="dialogImageUrl[dialogImageUrl.length - 1] == 4" :src="dialogImageUrl"></video>
      <img width="100%" v-else :src="dialogImageUrl" alt />
    </el-dialog>
tips: 我这种判断MP4格式的方式实属异端,不建议模仿。

替换img标签

一到标签节点的操作,我第一想到的就是document操作(异端+1),直接上代码。

 changeVideoTag(){
      let videoTag = document.querySelector('.video img')
      console.log('检测到应为video的img标签', videoTag)
      if(videoTag){
        let parentNode = videoTag.parentNode
        let newElement = document.createElement('video')
        newElement.setAttribute('class', videoTag.getAttribute('class'))
        newElement.setAttribute('src', videoTag.getAttribute('src'))
        parentNode.insertBefore(newElement, videoTag)
      }
    },

该函数负责寻找video类下的img标签,然后在img标签之前,添加一个同样的videos元素节点,此处你可以选择是否移除原img标签。

最终实现效果

gif.gif

最后的话

  1. 这种方法非常不推荐使用,强烈建议使用自定义模板缩略图
  2. 这种方法非常不推荐使用,强烈建议使用自定义模板缩略图
  3. 这种方法非常不推荐使用,强烈建议使用自定义模板缩略图