1 安装好vs code和nodejs(检查nodejs版本)
2 全局安装vue-cli,vue-cli可以帮助我们快速构建Vue项目
vuecli3:
① 安装命令: npm install -g @vue/cli
② 创建vue项目:vue create myvue 或基于ui界面创建Vue项目,命令:vue ui
vuecli3官网:https://cli.vuejs.org/zh/guide/installation.html
vuecli2:
① npm install -g vue-cli 卸载:npm uninstall -g vue-cli
② 安装webpack,它是打包js的工具:npm install -g webpack
③ vue init webpack myvue
接着会出现一些配置项,可以根据需要配置,也可以默认,直接按回车
3 安装依赖性 注意:要在项目文件的目录下
安装命令:npm install
4 启动服务,这个必须是在myvue的目录下,如果不在 cd 文件夹目录
cli2: npm run dev 或 npm run start
cli3: npm run serve
5 成功之后,接着在浏览器里输入:http://localhost:8080,看到如下画面就是成功了
6 如果研发手机端 我用的是vant 安装vant
(官网:https://vant-contrib.gitee.io/vant/#/zh-CN/quickstart)
安装命令:npm i vant -S
element官网:https://element-plus.gitee.io/zh-CN/guide/design.html
备注:
Element-ui适用于vue2
Element-plus适用于vue3
7 在main.js中引用vant
8 报错:
解决办法:这是因为开启了eslint 编码规范检查,找到webpack.base.conf.js文件:找到这行代码注释掉就可以了
9 app.vue是主界面
原始配置:
如果要替换首界面文件则:
10 插入轮播图片
但是页面不现实,打开F12 发现报错vant Failed to resolve directive: lazy
解决方法:这是因为Vant自定义指令找不到
import Vant,{Lazyload} from 'vant';
import 'vant/lib/index.css';
Vue.use(Vant);
Vue.use(Lazyload);
11 调式
12 运行服务 cli2: npm run dev cli3: npm run serve
如果报错
配置dev 或者 serve
13 打包 npm run build
打包完成后 包生成在根目录下 dist文件夹
vuecli3:
如果想要修改dist或则static文件名称,需要新建vue.config.js,文章下面会详细介绍
vuecli2:
如果想要修改dist或则static文件名称,需要打开config / index.js
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/index.html'),//生成html文件路径
// Paths
assetsRoot: path.resolve(__dirname, '../dist'), // 对应的就是dist的文件夹名称
assetsSubDirectory: 'static', // 对应的就是dist下的static文件夹
assetsPublicPath: './',
14 npm run build打包项目之后,生成的dist文件里面有被压缩后的static文件跟index.html,直接打开index.html页面是空白的
vuecli3:
内容为:
module.exports = {
// 基本路径
publicPath: './',
// 输出文件目录
outputDir: 'dist',
configureWebpack: {
externals: {
}
}
}
vuecli2:
这样打开index.html就是首界面啦!!!
15 下面该配置axios 读取后台接口了
① 安装语句:npm install axios -S
② 新建一个src/plugins/axios.js文件:用于配置请求拦截器、跨域等问题
③ 报错:Expected indentation of 2 spaces but found 8
解决办法:添加一下校验规则
④ 在新建的js文件中 实例化axios
较科学的封装好的axios:(axios.js)
import axios from 'axios'
import { Notify } from 'vant';
// 创建 axios 实例
const requests = axios.create({
//baseURL: process.env.VUE_APP_API, // 基础url,如果是多环境配置这样写,也可以像下面一行的写死,在.env.production中配置
baseURL: 'http://www.neimXXXX.com/realEstateOnline',
timeout: 6000 // 请求超时时间
})
// 错误处理函数
const err = (error) => {
if (error.response) {
const data = error.response.data
// const token = Vue.ls.get(ACCESS_TOKEN)
if (error.response.status === 403) {
Notify({ type: 'danger', message: data.message || data.msg });
}
if (error.response.status === 401) {
Notify({ type: 'danger', message: '你没有权限。' });
// if (token) {
// store.dispatch('Logout').then(() => {
// setTimeout(() => {
// window.location.reload()
// }, 1500)
// })
// }
}
}
return Promise.reject(error)
}
// request interceptor(请求拦截器)
//requests.interceptors.request.use(config => {
//// const token = Vue.ls.get(ACCESS_TOKEN)
//const token = localStorage.getItem('token')
//if (token) {
//config.headers['token'] = token // 让每个请求携带自定义 token 请根据实际情况自行修改
//}
//return config
//}, err)
requests.interceptors.request.use(
(config) => {
console.log(config)
// config.data = JSON.stringify(config.data);
if (config.url == "/licenseService/connect/token") {
config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
} else if (config.url == "/Files") {
config.headers['Content-Type'] = 'multipart/form-data';
} else {
config.headers['Content-Type'] = 'application/json;charset=UTF-8';
}
let token = localStorage.Authorization;
if (token) { // 判断是否存在token,如果存在的话,则每个http header都加上token
config.headers['Authorization'] = token;
}
return config
},
(error) => {
return Promise.reject(error);
}
);
// response interceptor(接收拦截器)
requests.interceptors.response.use((response) => {
const res = response.data
if (res.code !== 0 && res.code !== 200) {
Notify({ type: 'danger', message: res.message || res.msg });
// 401:未登录;
if (res.code === 401 || res.code === 403 || res.code === 999) {
Notify({ type: 'danger', message: '请登录' });
}
return Promise.reject('error')
} else {
return res
}
}, err)
//一定要有
export default {
requests
}
备注:如果使用配置文件,则:
⑤ main.js 引入,添加到vue原型
⑥ 使用axios
mounted () {
this.axios.get("/PublishContent/Content", {
params: {
type: '机构简介', //类型 string
title: '机构简介', //标题 string
}
}).then(res => {
this.message = res.data.content;
})
.catch(() => {
this.$toast.fail('系统错误')
});
}
}
⑦ 报错:
解决办法: this.axios 确实没有get函数,get函数在 this.axios.requests之下,所以将第三步的请求换成
这个丢了也会报错
⑧ 访问axios 终于成功了 虽然是200 但是 一直进catch
找了半天 终于找到原因,是因为封装axios中的接收拦截器 设置不对
二次封装了axios,会判断返回的 res数据 是否包含 res.code !== 0 && res.code !== 200 根据后端接口实际情况进行修改即可,我是直接注释掉,就不报错了
到此,终于访问到值了!!!!!
axios配置参考网址:https://www.cnblogs.com/nogodie/p/9853660.html
16 跨域问题
① 首先在根目录下 新建vue.config.js
module.exports = {
filenameHashing: true,
pages: {
index: {
entry: 'src/main.js',
template: 'public/index.html',
filename: 'index.html',
chunks: ['chunk-vendors', 'chunk-common', 'index'],
},
},
configureWebpack: {
output: {
filename: `[name].${new Date().getTime()}.js`,
chunkFilename: `[name].${new Date().getTime()}.js`
},
},
lintOnSave: false,
productionSourceMap: false,
//输出路径
publicPath: './',
//输出文件名称
outputDir: 'dist',
devServer: {
host: 'localhost',
port: 8080, // 端口号
https: false, // https:{type:Boolean}
open: true, // 配置自动启动浏览器
hotOnly: true, // 热更新
proxy: {
// 配置多个跨域
'/api': {
target: 'http://www.neimegztlaxx.com/XXXXOnline',//跨域接口的地址
changeOrigin: false,
pathRewrite: {
'^/api': ''
}
}
}
},
pluginOptions: {
'style-resources-loader': {
preProcessor: 'stylus',
patterns: []
}
}
}
② 封装的axios中,将baseURL设置为‘’,但是打包的时候 需要换回URL,部署时一般用到nginx代理进行跨域
③ 使用axios时前面需要加 /api
④ 这样就完成了跨域,但是我调式的时候发现访问地址 还是我本机的地址 根本不是我代理的地址,我就以为没有代理过去,这个问题折腾了我一天!!!
后来我发现 虽然代理成功,但是地址还是会显示本机IP
其实已经成功了
17 配置路由
vuecli2中自带Vue-router,vueli3中需要自己配置 之前写过一篇文章《vue-cli + vant 路由的设置》 专门介绍如何配置
备注:Vue-router 中有hash模式和history模式,vue的路由默认是hash模式,一般开发的单页应用的URL都会带有#号的hash模式
注意: 首界面 设置
18 页面刷新 reload
在所想添加reload的vue里直接如下:
19 接下来就剩最后一步 进行登录和token验证!!!
在前后端完全分离的情况下,Vue项目中实现token验证大致思路如下:
1、第一次登录的时候,前端调后端的登陆接口,发送用户名和密码
2、后端收到请求,验证用户名和密码,验证成功,就给前端返回一个token
3、前端拿到token,将token存储到localStorage和vuex中,并跳转路由页面
4、前端每次跳转路由,就判断 localStroage 中有无 token ,没有就跳转到登录页面,有则跳转到对应路由页面
5、每次调后端接口,都要在请求头中加token
6、后端判断请求头中有无token,有token,就拿到token并验证token,验证成功就返回数据,验证失败(例如:token过期)就返回401,请求头中没有token也返回401
7、如果前端拿到状态码为401,就清除token信息并跳转到登录页面
步骤:
① 代码
登录账号
登录
② axios中 添加请求拦截器
requests.interceptors.request.use(
(config) => {
console.log(config)
// config.data = JSON.stringify(config.data);
// 因为做了跨域,所以 接口前面也要添加 /api 即可
if (config.url == "/api/licenseService/connect/token") {
config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
} else if (config.url == "/Files") {
config.headers['Content-Type'] = 'multipart/form-data';
} else {
config.headers['Content-Type'] = 'application/json;charset=UTF-8';
}
let token = localStorage.Authorization;
if (token) { // 判断是否存在token,如果存在的话,则每个http header都加上token
config.headers['Authorization'] = token;
}
return config
},
(error) => {
return Promise.reject(error);
}
);
③ 成功
备注知识:
① localStorage作为HTML5本地存储web storage特性的API之一,主要作用是将数据保存在客户端中,而客户端一般是指上海网站设计用户的计算机。在移动设备上,由于大部分浏览器都支持web storage特性,因此在android和ios等智能手机上的web浏览器都能正常使用该特性。
localStorage保存的数据,一般情况下是永久保存的,也就是说只要采用localstorage保存信息,数据便一直存储在用户的客户端中。即使用户关闭当前web浏览器后重新启动,数据让然存在。知道用户或程序明确制定删除,数据的生命周期才会结束。
在安全性方面,localstorage是域内安全的,即localstorage是基于域的。任何在该域内的所有页面,都可以访问localstorage数据。但让然存在一个问题,就是各个浏览器厂商的浏览器之间的数据是各自独立的。也就是说,如果在firefox中使用localstorage存储一组数据,在chrome浏览器下是无法读取的。同样,由于localstorage数据是保存在用户的设备中的,因此同一个应用程序在不同设备上保存的数据是不同的。
② vue中sessionStorage的使用
localStorage 和 sessionStorage 属性允许在浏览器中存储 key/value 对的数据。
sessionStorage 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。
参考文章:https://blog.csdn.net/zzqq12345/article/details/107461098
③ vuex就是一个存放多个组件共用的一个数据的存放、更改、处理的一个容器,就是说来存放处理公共数据的工具,存放的数据一变,各个组件都会更新,也就是说存放的数据是响应式的
笔记中有一篇是 vue中使用vuex 详细介绍了vuex的用法