一、vue-cli
vue-cli俗称vue脚手架,是vue官方提供的快速生成vue 工程化项目的工具。
1.官网:https://cn.vuejs.org/
中文官网: https://cli.vuejs.org/zh/
特点:基于webpack,功能丰富且易于扩展,支持创建vue2和vue3的项目
2.全局安装:
npm install -g @vue/cli
查看vue-cli的版本,检查vue-cli是否安装成功
vue --version
3.解决Windows PowerShell 不识别vue命令的问题
a.以管理员身份运行 PowerShell
b.执行set-ExecutionPolicy RemoteSigned命令
c.输入字符Y,回车即可
4.基于vue ui 创建vue项目
本质:通过可视化面板采集到的用户配置信息后,在后台基于命令行的方式自动初始化项目
a.在终端下运行vue ui 命令,自动在浏览器中打开创建项目的可视化面板
b.在详情页面填写vue项目名称
c. 在预设页面选择手动配置项目
d.在功能页面勾选需要安装的功能(css预处理器,使用配置文件)
e.在配置页面勾选vue的版本和需要的预处理器
f.将刚才所有的配置保存为预设模板,方便下一次创建项目时直接复用之前的配置
5.基于命令行创建vue项目
vue create my-project
a.在终端下运行vue create 002demo命令,基于交互式的命令行创建vue的项目
b.选择要安装的功能(手动选择要安装的功能)
把babel,eslint等插件的配置信息存储到单独的配置文件中(推荐)
把babel,eslint等插件的配置信息存储到package.json中(不推荐)
erer
二、组件库
1.element-plus
地址:https://element-plus.org/zh-CN/
全局引入
npm install element-plus --save
npm install @element-plus/icons-vue
// main.js
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import App from './App.vue'
const app = createApp(App)
app.use(ElementPlus)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.mount('#app')
也可以将element相关代码拆分
element.js
import { ElButton,ElIcon } from 'element-plus'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
export const setupElement = (app) =>{
app.component(ElButton.name, ElButton)
app.component(ElIcon.name, ElIcon)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
}
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import {setupElement} from './element.js'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(router)
setupElement(app)
app.mount('#app')
按需引入
npm install -D unplugin-vue-components unplugin-auto-import
vue.config.js
const AutoImport = require('unplugin-auto-import/webpack').default;
const Components = require('unplugin-vue-components/webpack').default;
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers');
module.exports = {
configureWebpack: {
resolve: {
alias: {
components: '@/components'
}
},
//配置webpack自动按需引入element-plus,
plugins: [
AutoImport({
resolvers: [ElementPlusResolver()]
}),
Components({
resolvers: [ElementPlusResolver()]
})
]
}
};
<template>
<div class="hello">
<el-button color="#626aef">Default</el-button>
<el-button>我是 ElButton</el-button>
<el-button type="primary" circle>
<el-icon :size="20">
<Edit />
</el-icon>
</el-button>
</div>
</template>
<script>
import { Edit } from '@element-plus/icons-vue'
export default {
name: 'HelloWorld',
components: {
Edit
}
}
</script>
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
// import {setupElement} from './element.js'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(router)
// setupElement(app)
app.mount('#app')
三、axios拦截器
拦截器会在每次发起ajax请求和得到相应的时候自动被触发。
应用场景:token身份验证,loading效果。
main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import axios from 'axios'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(router)
axios.defaults.baseURL='http://localhost:3000'
app.config.globalProperties.$http=axios
app.mount('#app')
<template>
</template>
<script>
export default {
methods:{
async getData(){
const {data:res} = await this.$http.get('/goodsList')
console.log('res',res);
}
},
created(){
this.getData()
}
}
</script>
配置请求拦截器,响应拦截器
通过axios.interceptors.request.use(成功的回调,失败的回调)可以配置请求拦截器。
通过axios.interceptors.response.use(成功的回调,失败的回调)可以配置相应拦截器。
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import axios from 'axios'
import 'element-plus/dist/index.css'
import { ElLoading } from 'element-plus'
const app = createApp(App)
app.use(router)
axios.defaults.baseURL='http://localhost:3000'
// axios.interceptors.request.use(config=>{
// config.headers.Authorization='Bearer xxx'
// return config
// })
let loadingInstance=null
axios.interceptors.request.use(config=>{
loadingInstance = ElLoading.service({fullscreen:true})
return config
})
axios.interceptors.response.use((response)=>{
loadingInstance.close()
return response
},(error)=>{return Promise.reject(error)} )
app.config.globalProperties.$http=axios
app.mount('#app')
拆分axios
// src/http.js
import axios from 'axios';
import { ElLoading } from 'element-plus';
const http = axios.create({
baseURL: 'http://localhost:3000',
});
let loadingInstance = null;
http.interceptors.request.use(config => {
loadingInstance = ElLoading.service({ fullscreen: true });
if(localStorage.getItem('token')){
config.hearders.token=localStorage.getItem('token')
}
return config;
});
http.interceptors.response.use(
response => {
loadingInstance.close();
return response;
},
error => {
loadingInstance.close();
switch(error.response.status){
case 404:console.log("您请求的路径不存在,或者错误");break;
case 500:console.log("服务器出错");break;
}
return Promise.reject(error);
}
);
export default http;
main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import http from './http'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(router)
app.config.globalProperties.$http=http
app.mount('#app')
拆分发请求的api
api.js
import http from "./http";
//获取商品列表
// export const getGoodsListApi=()=>{
// return http.get("/goodsList")
// }
export const getGoodsListApi=()=>{
return http({
url:"/goodsList",
methods:'get'
})
}
四、proxy跨域代理
1.解决方法
a.把axios的请求根路径设置为vue项目的根路径
b.vue项目发请请求的接口不存在,把请求转交给proxy代理
c.代理把请求路径替换为devServer.proxy属性的值,发请真正的数据请求
d.代理把请求的数据,转发为axios
vue.config.js
const AutoImport = require('unplugin-auto-import/webpack').default;
const Components = require('unplugin-vue-components/webpack').default;
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers');
const { defineConfig } = require('@vue/cli-service');
module.exports = defineConfig({
configureWebpack: {
resolve: {
alias: {
components: '@/components'
}
},
plugins: [
AutoImport({
resolvers: [ElementPlusResolver()]
}),
Components({
resolvers: [ElementPlusResolver()]
})
]
},
devServer: {
proxy: {
'/apicity': { //axios访问 /apicity == target + /apicity
target: 'http://121.89.205.189:3000',//真正的服务器
changeOrigin: true, //创建虚拟服务器
pathRewrite: {
'^/apicity': '' //重写接口地址,去掉/apicity,
}
}
}
}
});
api.js
import http from "./http";
export const getCitysListApi=()=>{
return http({
url: "/apicity/city/sortCity.json",
methods:'get'
})
}
注意:a.derServer.proxy提供的代理功能,仅在开发调试阶段生效
b.项目上线发布时,依旧需要api接口服务器开启cors跨域资源共享