【vue起步】快速搭建vue项目引入第三方插件

3,752 阅读3分钟

小知识,大挑战!本文正在参与“  程序员必备小知识  ”创作活动

本文同时参与 「掘力星计划」  ,赢取创作大礼包,挑战创作激励金

前言

佛祖保佑, 永无bug。Hello 大家好!我是海的对岸!

快速搭建vue项目 文档传送门

我自己也写了一篇文章,新建vue项目,还包括创建vite vue3项目vite react项目【vite vue react】创建项目

关于快速新建vue项目网上教程很多,我就不多此一举,我这里主要讲vue项目新建之后,往里面引入第三方插件的引入方式及使用方式

快速创建项目(快速带过)

image.png

vscode 打开创建的项目 执行yarn serve

image.png

image.png

引入element-ui

element-ui传送门

安装

yarn add element-ui

image.png

引入,我们使用按需引用

  • 借助 babel-plugin-component,我们可以只引入需要的组件,以达到减小项目体积的目的。
yarn add babel-plugin-component -D

使用带有 -D后缀命令,可以将依赖安装到 package.jsondevDependencies

image.png

image.png

image.png

  • lib/element/index.js 文件内容如下
import "element-ui/lib/theme-chalk/index.css";

import {
  Pagination,
  Dialog,
  Autocomplete,
  Dropdown,
  DropdownMenu,
  DropdownItem,
  Menu,
  Submenu,
  MenuItem,
  MenuItemGroup,
  Input,
  InputNumber,
  Radio,
  RadioGroup,
  RadioButton,
  Checkbox,
  CheckboxButton,
  CheckboxGroup,
  Switch,
  Select,
  Option,
  OptionGroup,
  Button,
  ButtonGroup,
  Table,
  TableColumn,
  DatePicker,
  TimeSelect,
  TimePicker,
  Popover,
  Tooltip,
  Breadcrumb,
  BreadcrumbItem,
  Form,
  FormItem,
  Tabs,
  TabPane,
  Tag,
  Tree,
  Alert,
  Slider,
  Icon,
  Row,
  Col,
  Upload,
  Progress,
  Spinner,
  Badge,
  Card,
  Rate,
  Steps,
  Step,
  Carousel,
  CarouselItem,
  Collapse,
  CollapseItem,
  Cascader,
  ColorPicker,
  Transfer,
  Container,
  Header,
  Aside,
  Main,
  Footer,
  Timeline,
  TimelineItem,
  Link,
  Divider,
  Image,
  Calendar,
  Backtop,
  PageHeader,
  CascaderPanel,
  Loading,
  MessageBox,
  Message,
  Notification,
} from 'element-ui';

export default (Vue) => {
  Vue.use(Pagination);
  Vue.use(Dialog);
  Vue.use(Autocomplete);
  Vue.use(Dropdown);
  Vue.use(DropdownMenu);
  Vue.use(DropdownItem);
  Vue.use(Menu);
  Vue.use(Submenu);
  Vue.use(MenuItem);
  Vue.use(MenuItemGroup);
  Vue.use(Input);
  Vue.use(InputNumber);
  Vue.use(Radio);
  Vue.use(RadioGroup);
  Vue.use(RadioButton);
  Vue.use(Checkbox);
  Vue.use(CheckboxButton);
  Vue.use(CheckboxGroup);
  Vue.use(Switch);
  Vue.use(Select);
  Vue.use(Option);
  Vue.use(OptionGroup);
  Vue.use(Button);
  Vue.use(ButtonGroup);
  Vue.use(Table);
  Vue.use(TableColumn);
  Vue.use(DatePicker);
  Vue.use(TimeSelect);
  Vue.use(TimePicker);
  Vue.use(Popover);
  Vue.use(Tooltip);
  Vue.use(Breadcrumb);
  Vue.use(BreadcrumbItem);
  Vue.use(Form);
  Vue.use(FormItem);
  Vue.use(Tabs);
  Vue.use(TabPane);
  Vue.use(Tag);
  Vue.use(Tree);
  Vue.use(Alert);
  Vue.use(Slider);
  Vue.use(Icon);
  Vue.use(Row);
  Vue.use(Col);
  Vue.use(Upload);
  Vue.use(Progress);
  Vue.use(Spinner);
  Vue.use(Badge);
  Vue.use(Card);
  Vue.use(Rate);
  Vue.use(Steps);
  Vue.use(Step);
  Vue.use(Carousel);
  Vue.use(CarouselItem);
  Vue.use(Collapse);
  Vue.use(CollapseItem);
  Vue.use(Cascader);
  Vue.use(ColorPicker);
  Vue.use(Transfer);
  Vue.use(Container);
  Vue.use(Header);
  Vue.use(Aside);
  Vue.use(Main);
  Vue.use(Footer);
  Vue.use(Timeline);
  Vue.use(TimelineItem);
  Vue.use(Link);
  Vue.use(Divider);
  Vue.use(Image);
  Vue.use(Calendar);
  Vue.use(Backtop);
  Vue.use(PageHeader);
  Vue.use(CascaderPanel);

  Vue.use(Loading.directive);

  Vue.prototype.$loading = Loading.service;
  Vue.prototype.$msgbox = MessageBox;
  Vue.prototype.$alert = MessageBox.alert;
  Vue.prototype.$confirm = MessageBox.confirm;
  Vue.prototype.$prompt = MessageBox.prompt;
  Vue.prototype.$notify = Notification;
  Vue.prototype.$message = Message;
};

  • 把这个element插件 引入到 main.js

image.png

  • helloworld.vue原本的内容删掉,放一个elementbutton看看有没有成功
<template>
  <div class="hello">
    <el-button>112233</el-button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">

</style>

image.png

引入axios

安装

npm install axios --save
或
yarn add axios

还要安装一个 qs
yarn add qs

实现 接口统一管理

使用axios,封装axios,实现 接口统一管理  步骤:

  1. src/lib/下新建apis文件夹,文件夹里限价index.js,封装axios,  
  2. main.js 中 引入,
  3. 在各个子模块中调用
  4. vue.config.js配置

image.png

http.js

import axios from "axios";

// 创建 axios 实例
const requests = axios.create({
  // 这里我没有设置basURL,我是在vue.config.js 中的 devServer中的 host:localhost 上访问的
  // 如果要打包部署的话,用nginx 代理好一个端口,再进行接口的调整
  // baseURL: process.env.VUE_APP_API, // 基础url,如果是多环境配置这样写,也可以像下面一行的写死。
  // baseURL: 'http://168.192.0.123’,
  // 如果设置了代理,那你本地开发环境的axios的baseUrl要写为'',即空字符串
  baseURL: "",
  timeout: 6000, // 请求超时时间
});

// request interceptor(请求拦截器)
requests.interceptors.request.use((config) => {
  // 实际使用时,设置的token 验证
  // const token = localStorage.getItem('token');
  // if (token) {
    // config.headers['token'] = token; // 让每个请求携带自定义 token 请根据实际情况自行修改
  // }
  return config;
}, err);

// response interceptor(接收响应拦截器)
requests.interceptors.response.use((response) => {
  // debugger
  const res = response.data;
  if (res.code !== 0 && res.code !== 200) {
    this.$notify.error({
      title: "错误",
      message: res.message || res.msg,
    });
    // 401:未登录;
    if (res.code === 401 || res.code === 403) {
      this.$notify.error({
        title: "错误",
        message: "请登录",
      });
    }
    return Promise.reject("error");
  } else {
    return res;
  }
}, err);

// 错误处理函数
const err = (error) => {
  if (error.response) {
    const data = error.response.data;
    if (error.response.status === 403) {
      this.$notify.error({
        title: "错误",
        message: data.message || data.msg,
      });
    }
    if (error.response.status === 401) {
      this.$notify.error({
        title: "错误",
        message: "你没有权限。",
      });
      // if (token) {
      //   store.dispatch('Logout').then(() => {
      //     setTimeout(() => {
      //       window.location.reload()
      //     }, 1500);
      //   });
      // }
    }
  }
  return Promise.reject(error);
};

export default requests;
// 这里的提示消息 实际看你选用哪个UI框架
// 比如你使用 vant框架,可以用 Notify
// 这里面的 Notify 指的是前端vant框架里面的弹框组件,这里你可以按你自己的实际需求来决定选择提示框
// 比如你使用 element-ui框架,可以用 notify
// 本次 http.js 中用到的就是 element-ui框架的notify

index.js

import requests from "./http";
import qs from "qs";

// 接口文件呢,post请求参数名为data,get请求参数名为params

// qs主要有两个方法:
// 方法一:将对象序列化,多个对象之间用&拼接(拼接是由底层处理,无需手动操作)
// qs.stringify(); // 转换成查询字符串     将对象 序列化成URL的形式,以&进行拼接
let comments = { name: "hehe", age: 10 };
console.log("111", comments);
let comValue = qs.stringify(comments); // 'name=hehe&age=10'
console.log("222", comValue);
console.log("333", JSON.stringify(comments)); // '{"name":"hehe","age":10}'

// 方法二:将序列化的内容拆分成一个个单一的对象
// qs.parse(); // 转换成json对象
let comValue2 = qs.parse(comValue);
console.log("444", comValue2);

// 111 {name: 'hehe', age: 10}
// 222 name=hehe&age=10
// 333 {"name":"hehe","age":10}
// 444 {name: 'hehe', age: '10'}

const getTestData = () => {
  return requests({
    url: "/DemoData/pointList.json",
    method: "get",
  });
};

const apiMethods = {
  // 具体调用的方法名称
  getTestData,
  // 其他的详细接口,可以接着往下写
  // ...
};

// 直接导出整个api对象,需要用哪个detailMethod,就 apiMethods.detailMethod
export default apiMethods;

src/main.js 中 全局引入 封装的axios

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
...
// 引入封装的axios
import apiMethods from "./lib/apis";

...
// 使用处理好的axios
Vue.prototype.$apiMethods = apiMethods;

new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount("#app");

public/DemoData下,新建一个pointList.json文件

{
  "success": true,
  "code": 200,
  "msg": "操作成功",
  "count": 6,
  "data": [
    {
      "pointCode": "111",
      "pointName": "点位1"
    },
    {
      "pointCode": "222",
      "pointName": "点位2"
    }
  ]
}

这里需要注意一下

image.png

image.png

image.png

在子组件中引用axios

image.png

image.png

引入echarts

安装

yarn add echarts vue-echarts

注意,很多帖子说的就直接安装vue-echarts,而事实上仅仅安装vue-echarts新版本并不适用,一定要同时安装echarts

image.png

插曲 项目跑起来报错(解决过程)

image.png

解决这个问题,这里有个小插曲(回头看,这个问题其实挺狗血的,就是看错了,但是也解决了,解决过程就比较硬核)

插曲解决过程看这里:传送门

解决完之后,就正常了

image.png

image.png

老规矩,在lib文件夹内创建一个echarts文件夹,

image.png

index.js中的内容如下:

import echarts from 'echarts';
import Echart from 'vue-echarts';

export default(Vue) => {
  Vue.prototype.$echarts = echarts;
  Vue.component('Echart', Echart);
};

main.js中引入

...
// 引入 echarts
import echarts from './libs/echarts';

...
Vue.use(echarts);
...

HelloWorld.vue中 添加一个echarts图表看看

<template>
  <div class="hello">
    <el-button>112233</el-button>
    <div style="width: 95%; height: 170px; border: 1px solid">
      <Echart :options="echartObj" :autoResize="true" style="width: 100%; height: 100%"/>
    </div>
  </div>
</template>

<script>
import echart from "vue-echarts";

export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
  data() {
    return {
      echartObj: {},
    };
  },
  methods: {
    loadEcharts() {
      const XData = [
        "2019-07-01 00:00:00",
        "2019-07-01 00:01:00",
        "2019-07-01 00:02:00",
        "2019-07-01 00:03:00",
        "2019-07-01 00:04:00",
        "2019-07-01 00:05:00",
        "2019-07-01 00:06:00",
        "2019-07-01 00:07:00",
        "2019-07-01 00:08:00",
        "2019-07-01 00:09:00",
        "2019-07-01 00:10:00",
        "2019-07-01 00:11:00",
        "2019-07-01 00:12:00",
        "2019-07-01 00:13:00",
        "2019-07-01 00:14:00",
        "2019-07-01 00:15:00",
        "2019-07-01 00:16:00",
        "2019-07-01 00:17:00",
        "2019-07-01 00:18:00",
        "2019-07-01 00:19:00",
        "2019-07-01 00:20:00",
        "2019-07-01 00:21:00",
        "2019-07-01 00:22:00",
        "2019-07-01 00:23:00",
      ];
      const YData = [
        "1.3",
        "1.2",
        "1.0",
        "1.1",
        "1.3",
        "0.8",
        "0.9",
        "0.9",
        "1.3",
        "1.3",
        "1.2",
        "1.0",
        "1.1",
        "1.3",
        "0.8",
        "0.9",
        "0.9",
        "1.3",
        "1.1",
        "1.3",
        "0.8",
        "0.9",
        "0.9",
        "1.3",
      ];
      this.echartObj = {
        tooltip: {
          trigger: "axis",
          axisPointer: {
            type: "cross",
            label: {
              backgroundColor: "#6a7985",
            },
          },
        },
        grid: {
          top: "6%",
          left: "6%",
          right: "6%",
          bottom: "3%",
          containLabel: true,
        },
        xAxis: {
          type: "category",
          data: XData,
          axisLabel: {
            // 坐标轴刻度标签的相关设置。
            formatter(params) {
              let newParamsName = ""; // 最终拼接成的字符串
              const paramsNameNumber = params.length; // 实际标签的个数
              const provideNumber = 10; // 每行能显示的字的个数
              const rowNumber = Math.ceil(paramsNameNumber / provideNumber); // 换行的话,需要显示几行,向上取整
              /**
               * 判断标签的个数是否大于规定的个数, 如果大于,则进行换行处理 如果不大于,即等于或小于,就返回原标签
               */
              // 条件等同于rowNumber>1
              if (paramsNameNumber > provideNumber) {
                /** 循环每一行,p表示行 */
                // eslint-disable-next-line no-plusplus
                for (let p = 0; p < rowNumber; p++) {
                  let tempStr = ""; // 表示每一次截取的字符串
                  const start = p * provideNumber; // 开始截取的位置
                  const end = start + provideNumber; // 结束截取的位置
                  // 此处特殊处理最后一行的索引值
                  if (p === rowNumber - 1) {
                    // 最后一次不换行
                    tempStr = params.substring(start, paramsNameNumber);
                  } else {
                    // 每一次拼接字符串并换行
                    tempStr = `${params.substring(start, end)}\n`;
                  }
                  newParamsName += tempStr; // 最终拼成的字符串
                }
              } else {
                // 将旧标签的值赋给新标签
                newParamsName = params;
              }
              // 将最终的字符串返回
              return newParamsName;
            },
          },
        },
        yAxis: {
          type: "value",
        },
        series: [
          {
            data: YData,
            type: "line",
            smooth: true, // true: 折线变成曲线
            itemStyle: { normal: { color: "#47a6ff" } },
            areaStyle: {
              normal: {
                color: new echart.graphic.LinearGradient(0, 0, 0, 1, [
                  // 这里用到了echart
                  {
                    offset: 0,
                    color: "#47a6ff",
                  },
                  {
                    offset: 1,
                    color: "#fff",
                  },
                ]),
              },
            },
          },
        ],
      };
    },
  },
  mounted() {
    this.loadEcharts();
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
</style>

结果报错

image.png

百度了一下,说:

echarts如果是在5.0版本会报以上错误; 原因是因为graphic对象下没有LinearGradient方法; 可以通过降低版本解决:

yarn add echarts@4.8.0

image.png

重新降低版本安装之后

image.png

又报错,说要安装个 echarts/core,我记得以前没让我安装这个玩意啊,纳尼??

image.png

那安装下吧

yarn add echarts/core

结果没找到包,奇怪,我去翻了下以前用vue-echarts的项目,我以前用的时候,也没用到echarts/core,但是图表也能出来

以前用的vue-echarts是 5版本的稳定版

yarn add vue-echarts@5.0.0-beta.0

image.png

image.png

image.png

看看页面,唉,页面又报错了

image.png

排查了一下,本以为是少了一个组件没有安装

后来发现,是xAxis属性这里,少写了一个字母,拼错了

image.png

大家还是要细心细心再细心

效果如下:

image.png

引入vue-lottie

先简单介绍下vue-lootie

什么是Lottie

Lottie是一个可以通过bodymovin插件来解析Adobe After Effects动画,并生成json格式的文件。该json文件可以通过Lottie开源库在iOS,Android,macOS,React Native中进行解析生成动画效果。

为什么使用Lottie

一直以来我们的设计同学都是使用设计软件,设计动画效果,开发同学再通过代码来实现动效。对于复杂的动画,开发同学要用很长的时间来实现,并且还有可能无法达到设计同学的最初的效果。

还有一种实现动画的方式就是gif图。然而Android并不支持gif图,而且gif图对于移动端还有占用过多空间的问题。

那么,Lottie为我们做了什么呢。

首先,设计同学在Adobe After Effects上设计了动画效果,通过bodymovin插件,可以将动画导出成一个json文件。

然后,开发同学就可以通过Lottie将前面生成的json文件渲染成动画效果。

这样就可以高效的实现很多复杂动画效果啦。

安装

yarn add vue-lottie

和之前一样,将这个第三方插件 放在之前创建的 libs 文件夹内

Image.png

Image.png

如此便引入了vue-lottie

引入vue-amap

安装

npm install vue-amap --save
或
yarn add vue-amap

lib文件夹下新建一个VueAMap文件夹

注意:因为我有时会在两台电脑上写文章,而这2台电脑上的Vue项目对于lib文件夹命名没有统一,一台电脑上命名是lib,另一台电脑上是libs,所以你们看到截图里出现libs 不要惊讶,语言文字我会统一使用lib,大家注意一下)

image.png

index.js内容如下:

import VueAMap from 'vue-amap';

VueAMap.initAMapApiLoader({
  key: '', // 这里的key 需要去高德地图开发者平台上注册账号,申请开发者,获取key 
  plugin: [
    'AMap.Autocomplete', // 输入提示插件
    'AMap.PlaceSearch', // POI搜索插件
    'AMap.Scale', // 右下角缩略图插件 比例尺
    'AMap.OverView', // 地图鹰眼插件
    'AMap.ToolBar', // 地图工具条
    'AMap.MapType', // 类别切换控件,实现默认图层与卫星图、实施交通图层之间切换的控制
    'AMap.PolyEditor', // 编辑 折线多,边形
    'AMap.CircleEditor' // 圆形编辑器插件
  ],
  // 默认高德 sdk 版本为 1.4.4
  v: '1.4.15',
  uiVersion: '1.0.11' // 引入高德 UI 组件库 版本号
});

export default(Vue) => {
  Vue.component('VueAMap', VueAMap);
};

高德地图开发者平台,传送门

main.js中代码如下

image.png

如此,Vue版高德地图便引入进来了

引入nprogress

有时候,我们会看到,网站在跳转的时候,网页内容的正上方会有一个进度条一样的东西,这个进度条走完了,页面也跳转完了

效果就像微信公众上的跳转一样 ( 因为网络不给力,所以跳转完了,还是没内容出来,见笑了哈 )

NProgress.gif

1. 安装 nprogress

npm install --save nprogress 或者
或
yarn add nprogress

2. 用法

NProgress.start();

NProgress.done();

3.项目中引用

lib文件夹内,新建nprogress文件夹

image.png

index.js代码如下:

/*
 * @Author: your name
 * @Date: 2021-11-01 09:14:39
 * @LastEditTime: 2021-11-01 09:17:11
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \hello-world\src\libs\nprogress\index.js
 */
//导入
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'

const start = () => {
  NProgress.start()
}

const done = () => {
  NProgress.done()
}

export default {
  start,
  done,
}

4. router.js中调用

router.js代码如下:

/*
 * @Author: your name
 * @Date: 2021-07-15 09:44:34
 * @LastEditTime: 2021-11-01 09:22:43
 * @LastEditors: your name
 * @Description: In User Settings Edit
 * @FilePath: \hello-world\src\router\index.js
 */
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import NProgress from '../libs/nprogress'

Vue.use(VueRouter)

const routes = [
  {
    path: '/Home',
    name: 'Home',
    component: Home
  },
  {
    path: '/About',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  },
  ...
]

const router = new VueRouter({
  routes
})

router.beforeEach((to, from, next) => {
    NProgress.start()
    next()
})

router.afterEach(() => {
  NProgress.done()
})

export default router

完工

引入jquery

安装

yarn add jquery

lib文件夹内新建jquery文件夹

image.png

index.js代码如下:

import $ from 'jquery';

export default(Vue) => {
  Vue.prototype.$ = $;
};

main.js中引用

...
import jquery from './libs/jquery';

...

Vue.use(jquery);
...

在实际代码组件中使用

<template>
  <div>
      <div>
        <div id="ddd">123</div>
      </div>
  </div>
</template>
<script>
export default {
  name: 'test',
  methods: {
    test() {
      this.$("#ddd").css({ backgroundColor: "red" });
    }
  },
  mounted() {
    this.test();
  },
}
</script>
<style scoped>

</style>

image.png

引入cesium

因为cesium我写了一个系列,vue安装cesium,我放在了这个系列里面,需要安装的话,看我的这篇文章【vue-cesium】在vue上使用cesium开发三维地图(二)

引入highcharts

highchartshighcharts-vue专门写了一篇文章,请移步:【vue自定义组件】实现3d饼图组件

评论抽奖

欢迎在评论区讨论,掘金官方将在掘力星计划活动结束后,在评论区抽送100份掘金周边

  • 抽奖礼物:100份,掘金官方提供,包括掘金徽章、拖鞋、马克杯、帆布袋等,随机发放
  • 抽奖时间:「掘力星计划」活动结束后,预计3个工作日内,官方将在所有符合规则的活动文章评论区抽出
  • 抽奖方式:掘金官方随机抽奖+人工核实
  • 评论内容:与文章内容相关的评论、建议、讨论等,「踩踩」「学习了」等泛泛类的评论无法获奖

都看到这里了,求各位观众大佬们点个赞再走吧,你的赞对我非常重要