2.第三方库集成

2.1. vue.config.js配置

Vue CLI依赖于Webpack,但是Vue CLI是将Webpack中的配置隐藏起来了,如果我们对Webpack中的某些配置不满意,如果我们确实想要修改CLI中Webpack的某个配置,可以通过vue.config.jsvue.config.js中的配置会和Vue CLI中Webpack的配置合并

https://cli.vuejs.org/

遇到问题先从官方文档找答案

vue.config.js有三种配置方式:(终于把这点搞懂了!)

* 方式一:直接通过CLI提供给我们的选项来配置:(名称和webpack中的可能不一样,但是一一对应)
* 比如publicPath:配置应用程序部署的子目录(默认是 `/`,相当于部署在 `https://www.my-app.com/`);
* 比如outputDir:修改输出的文件夹;
* 方式二:通过configureWebpack修改webpack的配置:(和webpack中的名称一样,直接合并)
* 可以是一个对象,直接会被合并;
* 可以是一个函数,会接收一个config,可以通过config来修改配置;

* 方式三:通过chainWebpack修改webpack的配置:(对webpack中的相关配置进行覆盖)
* 是一个函数,会接收一个基于 [webpack-chain](https://github.com/mozilla-neutrino/webpack-chain) 的config对象,可以对配置进行修改;

对比下面方式二的1和方式二的2以及方式三对别名的修改,因为方式二的第一种是和webpack的配置合并,而webpack中是有对src起别名为'@',所以如下操作。但是方式二的2以及方式三是对webpack中相关配置进行覆盖,所以需要拿到src,重新对它起别名,因此要获取path,拿到绝对路径(这里又涉及到一个require的查找规则,注意复习(jsplus--24))。另外注意方式二接收函数和方式三的区别。

 1 const path = require(‘path’)
 2 
 3 
 4 module.exports = {
 5   // 配置方式二:
 6   configureWebpack: {
 7     resolve: {
 8       alias: {
 9         components: '@/components'
10       }
11     }
12   },
13   configureWebpack: (config) => {
14     config.resolve.alias = {
15       '@': path.resolve(__dirname, 'src'),
16       components: '@/components'
17     }
18   },
19   // 方式三:
20   chainWebpack: (config) => {
21     config.resolve.alias
22       .set('@', path.resolve(__dirname, 'src'))
23       .set('components', '@/components')
24   }
25 }

2.2. vue-router集成(怎么这个步骤就记不住呢)

  • 安装vue-router的最新版本:
1 npm install vue-router@next
  • 创建router对象:(在src下新建一个router文件夹,下面index.ts)
 1 import { createRouter, createWebHashHistory } from 'vue-router'
 2 import { RouteRecordRaw } from 'vue-router'
 3 
 4 const routes: RouteRecordRaw[] = [ #ts是有类型的哦!
 5 {
 6 path: '/',
 7 redirect: '/main'
 8 },
 9 {
10 path: '/main',
11 component: () => import('../views/main/main.vue')
12 },
13 {
14 path: '/login',
15 component: () => import('../views/login/login.vue')
16 }
17 ]
18 
19 const router = createRouter({
20 routes,
21 history: createWebHashHistory()
22 })
23 
24 export default router 
  • 安装router 注册路由:
1 import router from './router' #export default导出的router 不需要括号
2 
3 createApp(App).use(router).mount('#app')
  • 在App.vue中配置跳转:
1 <template>
2 <div id="app">
3 <router-link to="/login">登录</router-link>
4 <router-link to="/main">首页</router-link>
5 <router-view></router-view>
6 </div>
7 </template>

2.3. vuex集成

  • 安装vuex:
1 npm install vuex@next
  • 创建store对象:(在src下面新建一个store文件夹,然后新建一个index.ts)
 1 import { createStore } from 'vuex'
 2 
 3 const store = createStore({
 4 state() {
 5 return {
 6 name: 'coderwhy'
 7 }
 8 }
 9 })
10 
11 export default store
  • 安装store 注册:
1 import store from './store'
2 createApp(App).use(router).use(store).mount('#app')
  • 在App.vue中使用:
1 <h2>{{ $store.state.name }}</h2>

 使用volar插件对ts的检测会更加严格,比如上面的$store在script中没有声明就会报错(没有报错啊!!),这里可以

在shims-vue.d.ts中声明一下:(不过因为我使用的是vetur插件,所以就不需要。这两个插件的作用就是语法高亮 错误提示等)

1 declare let $store: any

2.4. element-plus集成(这部门直接看官网更好)

Element Plus,一套为开发者、设计师和产品经理准备的基于Vue3.0桌面端组件库

* 相信很多同学在Vue2中都使用过element-ui,而element-plus正是element-ui针对于vue3开发的一个UI组件库;
* 它的使用方式和很多其他的组件库是一样的,所以学会element-plus,其他类似于ant-design-vue、NaiveUI、VantUI都是差不多的;

安装element-plus

1 npm install element-plus

2.4.1. 全局引入

一种引入element-plus的方式是全局引入,代表的含义是所有的组件和插件都会被自动注册:

1 import ElementPlus from 'element-plus'
2 import 'element-plus/dist/index.css'
3 
4 import router from './router'
5 import store from './store'
6 
7 createApp(App).use(router).use(store).use(ElementPlus).mount('#app')

---全局引入(所有的组件全部集成):优点:集成比较简单 缺点:会全部打包
---局部引入(按需引用):优点:包会小一些

 快速开始 | Element Plus (gitee.io)

官网按需引入的方法好像一直在该,这次按照它上面来居然没成功,所以还是把过程记录一下吧!
1 npm install -D unplugin-vue-components

修改vue.config.js的配置

1 const Components = require('unplugin-vue-components/webpack')
2 const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
  configureWebpack: {
    plugins: [
      Components({
        resolvers: [ElementPlusResolver()]
      })
    ]
  },

然后就可以直接使用了,但是要注意,图标比较特殊哦!

补充知识点

app.use()中可以传入一个函数,也可以传入一个对象。

传入一个函数时,默认会自动执行这个函数,并且会把app传入此函数。

传入一个对象时,默认会去执行这个对象的install,在执行这个对象的install时也会默认传入app

2.5. axios集成(难点

  • 安装axios:
npm install axios
  • 封装axios:(为什么要封装?1、如果不封装,各个文件中都直接使用axios,那么一旦axios不更新了或者升级了,我们就要改很多地方,维护起来很麻烦;2、在发送网络请求时可能有很多共同的特性,比如像后台管理系统这样的项目一般除了登录接口之外,其他接口在进行请求时都需要携带token,每个token最好放在header里面,再发送请求,既然每个请求都需要做这个操作,不如封装起来,不然会有很多重复逻辑。)
  • 封装逻辑:(感觉自己突然顿悟了!!!)在src--service中创建一个index.ts作为service的出口文件(其他地方需要使用只需导入'./service'就可以了,不用加index.ts),在service--request中创建index.ts里面封装一个HYRequest类,如下。在src--service--index.ts中实例化HYRequest这个类,然后其他地方就可以直接使用实例.方法进行调用!
  • 我们之前用的axios.get等等中的axios其实是axios实例
  • 为什么要选择把所有的axios封装到一个类中?如果有很多逻辑需要封装,类是一个不错的选择,因为类具有更强的封装性,类本身就具备封装(还有继承、多态)
  • 封装逻辑详细描述:

1.大多数情况下项目是只有一个base_url的,但是如果一个项目有两个base_url呢?我们要导出两个new Request吗?要知道axios是可以配置base_url的,也就是说我根本没办法区分谁是谁,那怎么办?可以在对axios进行封装的时候根据不同的config就创建不同的axios实例

    2.思考:有一些公共的逻辑,比如除了login页面都要进行的携带token,再比如loading动画,这些操作写在哪更合适呢?

      答:写到拦截器中!

      再复杂一点,比如不同实例拦截的东西不一样,怎么办?

      答:所以想让每个实例都有自己的拦截器,但是config里面可以不能传拦截器,那就要自己定义类,后面再把这些类型定义的抽取出去。

 

     关于拦截器我们即让某一个实例有,又让整个类都有,又让某个请求有

 

 

 

 

 

 

     3.token放在哪?因为每个请求都需要携带token,所以token应该放在实例的请求拦截中。Bearer是信差、信使的意思,我们把Bearer和token的拼接值放在Authorization字段

 

 

 

 4.拦截器响应拦截,拦截到的res有哪些呢?

 

 

 

       其实我们要使用的就是res.data,而响应拦截本来就是把响应到的数据处理后再返回,所以现在我们就不要再返回res了,而是返回res.data

      5.第一种响应失败会返回一个错误码。

 

第二种是表面请求成功但是没有返回对应的数据

 

 

 

 

 

       6.关于el-loading使用中遇见的一些问题

      • 按道理我是按需引入element-plus,想要使用哪个样式直接用就可以了,但是使用el-loading如果不导入样式,就没有样式        
1 import { ElLoading } from 'element-plus'
2 // 按道理这里是不需要导入样式的 不知道问题出在哪
3 import 'element-plus/theme-chalk/el-loading.css'
  • loading应该放在所有实例都有的请求拦截器上
 1 // 添加所有的实例都有的拦截器
 2     this.instance.interceptors.request.use(
 3       (config) => {
 4         ElLoading.service({
 5           lock: true,
 6           text: '正在请求数据...',
 7           background: 'rgba(0, 0, 0, 0.5)',
 8           fullscreen: true
 9         })
10         return config
11       },
12       (err) => {
13         return err
14       }
15     ),
      • 下面就是请求开始时进行loading的展示,数据响应后取消loading的展示

7.现在又有一个问题,我们在外面还是拿不到数据,数据是在request请求中拿到的,怎么办?

    • Promise 通过return new Promise((resolve,reject)=> {}),但你会发现代码会报错,因为现在request函数的返回值类型需要是Promise类型,具体什么类型应该是由外界决定的,这里就涉及到泛型了,具体见代码:

    •  定义类型,通过泛型传过去

      •  当然被调用的函数要通过resolve把res传出去    

    这时又出现问题了:我希望res是我之前定义的T类型,但是它告诉我res是AxiosResponse类型

      解决:

       怎么解决上面的问题?

      

       改成any,有点粗暴!

       8.封装get、post、delete、patch其实就是调用request

 

参照代码

 

补充一点:ElLoading的类型要从哪看呢?

 

 

 在最后那几个文件夹里面找找吧,能找到的!

 

2.6环境变量的配置

见32ppt

补充知识点:

当在项目中加载一些特殊文件时,比如.vue,.png,.jpg,.jpeg,默认ts是不认识这些文件的,会报错。而这里不会报错,是因为在我们使用CLI创建项目时,内部已经帮我们做了一些处理。

************

补充知识点:

defineComponent的意义:从js的角度来说,相当于传入一个组件然后返回这个组件,没有什么意义。

从ts的角度来说,可以通过泛型进行默认类型推导,能传入哪些东西,不能传入哪些有明确的规定,可以让编写的代码更加严谨。

 

posted @ 2021-12-05 15:13  不爱吃小红薯的小橘子  阅读(311)  评论(0)    收藏  举报