标签 vue 下的文章

2020-06-23T12:06:46.png

tips: 请注意区分vue3.0和vue cli 3.x/4.x

创建项目

vue create -r https://registry.npm.taobao.org vue-next-test

2020-06-23T12:01:58.png

选择你喜欢的配置即可,创建成功后,从Demo来看,跟vue2.0的typescript写法差别看起来不大的样子。。。

未完待续

typescript

本文环境

  1. @vue/cli 4.3.1
  2. typescript 3.9.5

相关配置文件

  1. vue.config.js
  2. tsconfig.json
  3. shims-vue.d.ts

问题汇总

导入 vue 文件报错

错误信息:Cannot find module './App.vue' or its corresponding type declarations
解决方案:修改shims-vue.d.ts

declare module "*.vue" {
  import Vue from "vue";
  export default Vue;
}

Vscode 报错,编译不报错

解决方案:重启 Vscode

挂载原型$api 报错

解决方案:在src目录下新增vue-property.d.ts

import Vue from 'vue'
declare module "vue/types/vue" {
  interface Vue {
    $api: any;
  }
}

无法使用@components别名 alias 路径

解决方案: 修改tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": ["webpack-env", "vuex"],
    "paths": {
      "@/*": ["src/*"],
      "@/components": ["src/components"] // 添加这一行
    },
    "lib": ["esnext", "dom", "dom.iterable", "scripthost"]
  },
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "tests/**/*.ts", "tests/**/*.tsx"],
  "exclude": ["node_modules"]
}

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

问题描述

原生的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. 这种方法非常不推荐使用,强烈建议使用自定义模板缩略图

按官网文档一键配置按需引入总是无法生效,目测可能是激进式预设没有选babel的原因。故写此文详细记录折腾过程,望有效!

vue ui创建新项目

选择预设,bable,eslint,vuex,vue-router(历史模式)

vue ui安装element插件

选择配置

2020-05-01T03:05:01.png

改动的内容

  1. 自动创建了bable.config.js,并添加了内容。
  2. 创建了`@/src/plugins/element.js,设置了按需引入
  3. 改写了app.vue,添加了element按钮组件

运行测试

2020-05-01T03:10:21.png

加载成功

2020-05-01T03:11:11.png

Q&A

  1. 为什么需要bable来支持按需加载

如果不使用bable转码,那你按需引入会找不到该组件。这是由于bable在将组件库转码的过程中把element整个组件库编译成了各种独立的组件模块,进而实现按需加载的功能

  1. 如何添加需要的组件

使用vue ui添加后的组件会在plugins目录下创建element.js文件,然后在main.js中引入该文件。文件内容如下:

import Vue from "vue";
import { Button } from "element-ui";

Vue.use(Button);

这就是只引入Button的方法,如果要按需添加,只需要依葫芦画瓢即可!

2020-04-19T02:47:53.png

安装

全局安装@vue/cli

yarn global add @vue/cli

检查是否安装成功(需重启更新环境变量)

vue --version

2020-04-19T02:36:37.png

快速原型开发

新版本Vue中增加了该功能,方便快速进行单个Vue文件开发,需要先额外安装一个全局的扩展。

yarn global add @vue/cli-service-global

入手尝鲜

新建index.vue文件

<template>
    <div>Hello Vue</div>
</template>

运行服务

vue serve index.vue

效果

2020-04-19T02:47:22.png

创建项目

vue.config.js

在vue cli 3.x/4.x 中,使用vue.cofig.js来进行一些包括webpack的配置。比如我们可以想要一个控制台输出编译时间的配置,可以在如下设置

const moment = require('moment')

module.exports = {
  chainWebpack: config => {
    config
      .plugin('html')
      .tap(args => {
        args[0].title = '三只蜜桔后台管理系统·商户版',
        args[0].buildTime = moment().format('YYYY.MM.DD.HH.mm')
        return args
      })
  }
}

亦或者,我们想要在生产环境禁用console.log

const moment = require('moment')

module.exports = {
  chainWebpack: config => {
    config
      .plugin('html')
      .tap(args => {
        args[0].title = '三只蜜桔后台管理系统·商户版',
        args[0].buildTime = moment().format('YYYY.MM.DD.HH.mm')
        return args
      })
    config.optimization
      .minimizer('terser')
      .tap(args => {
        Object.assign(args[0].terserOptions.compress, {
          pure_funcs: ['console.log']
        })
        return args
      })
  },
  productionSourceMap: false,
  configureWebpack: {
    output: {
      filename: `${moment().format('YYYY.MM.DD.HH.mm')}.${process.env.NODE_ENV}.[name].js`,
      chunkFilename: `${moment().format('YYYY.MM.DD.HH.mm')}.${process.env.NODE_ENV}.[name].js`
    }
  }
}

v-html介绍

如果不使用v-html而是直接将html标签加入视图层会出现html标签不解析的情况,如果我们想实现解析的效果。vue中提供了v-html指令。使用 v-html 指令,你可以将html标签解析渲染到视图层。

微信小程序如何使用?

由于微信小程序只是类vue的,与vue存在着很多不同点。但是为了秉承将vue进行到底的宗旨,很多微信小程序开发框架如雨后春笋。在我使用的过程中,感觉uni-app与vue最为贴近,而且适配了很多vue的特性,如:v-model,filters,v-html等。官网是这样介绍的。

uni-app支持的vue特性

其中,他们是通过微信小程序rich-text的属性来实现v-html的效果的。所以,我们想知道支持什么标签,就得移步至rich-text | 微信开发文档

开始实现Demo

demo 中的需求是一个赛事报名list,其中赛事状态有,预报名,报名成功,正在进行,已结束等。

预实现方法:由于微信小程序的rich-text组件会禁用所有的节点事件,所以想通过@click绑定v-html节点事件,filter渲染界面。但是在实现过程中发现不支持在v-html中使用filter, 故后来采用methods的返回值来实现视图层的渲染。

methods实现v-html渲染

效果如下:至此效果,v-html解析成功

v-html 渲染效果

添加状态判断

最终效果

v-model 介绍

首先明确一点,v-model仅仅是语法糖。

<input type="text" v-model="something">

等价于

  <input
                type="text"
                v-bind:value="something"
                v-on:input="something = $event.target.value">

它将一个较复杂的input双向数据绑定简化了他的书写方式。

微信小程序绑定input

最开始我是使用微信推荐的写法

<input bindtap="input" />

然后在js里面解析event,然后再setData

uni-app下v-model的写法

本文采用uni-app自定义组件模式

wxml

...
<form @submit="formSubmit" @reset="formReset" :model="formItem" class="tm-every-center padding bg-white">
                    <view class="section flex align-center">
                        <view class="section__title">姓名:</view>
                        <input name="name" placeholder="请填写您的姓名" class="bg-gray" v-model="formItem.name" />
                    </view>
                    <view class="section flex align-center">
                        <view class="section__title">手机:</view>
                        <input name="name" placeholder="请填写您的姓名" class="bg-gray" v-model="formItem.phone" />
                    </view>
                    <view class="section flex align-center">
                        <view class="section__title">赛点:</view>
                        <input name="name" placeholder="请填写您的姓名" class="bg-gray" v-model="formItem.competition" />
                    </view>
                    <view class="btn-area margin-top"><button formType="submit" class="cu-btn">提交</button></view>
                </form>
                ...

然后在data里面设置

formItem: {
                name:'',
                phone:'',
                competition: ''
            }

在submit事件回调里面就可以这样写

submit(){
    this.$api.post(formItem).then(res => {
    })
}

完美解决微信小程序input书写过程冗余的情况。