文章目录
一、vue-cli(脚手架)
vue-cli是vue官方提供的快速搭建项目的工具
1.1 安装
vue -V
检测版本
npm uninstall vue-cli -g
如果不是需要的版本,就卸载该版本
npm install -g @vue/cli
安装3.X.X的版本
vue -V
没有红色error的话,检测会出现版本号,有红色error 的话,检测会报错
npm install -g @vue/cli-init
安装好3.X.X的版本后,如果有需要,可以通过该命令桥接cli2 版本
1.2 项目结构
项目需要使用的依赖文件
- node_modules
静态资源文件 (不会变动的文件)
- public
- img // 图片资源
- index.html // 主页面
- robots.txt // 爬虫协议
放置组件和入口文件
- src
- assets // 静态资源文件(可能会变动的文件)
- components // 子组件
- views // 子页面
- App.vue // 项目主组件
- main.js // 主页面的js文件(入口文件)
- registerServiceWorker.js // 使项目变成一个PWA
- router.js // 路由配置文件
- store.js // 状态管理器配置文件
测试
- tests
- utils // 单元测试
- e2e // e2e或者端到端(end-to-end)或者UI测试
- .browserslistrc // 浏览器版本的设置 使用最新的版本
- .editorconfig // 代码编写规范
- .eslintrc.js // eslint的配置文件,eslint是用来管理和检测js代码风格的工具,可以和编辑器搭配使用,
- .gitignore // git的忽略文件
- babel.config.js // babel配置文件
- cypress.json // 测试的插件配置
- package.json // 项目及工具的依赖配置文件
- postcss.config.js // css的配置
- README.md //项目说明
1.3 项目结构详解
App.vue是唯一的主组件,所有页面都是在App.vue下进行切换的。,index.html是项目的页面,main.js是项目的入口文件,主要作用是初始化vue实例并使用需要的插件。可以理解成index.html通过main.js将App.vue组件中的内容替换掉了index.html中的内容,
main.js中引入了App.vue,并且new Vue()了一次,我们可以把main.js理解成是index.html页面中的js文件,此时new Vue()中的el绑定的则是index.html中的#app,所以这个new Vue()是对index.html页面的实例,接着在实例中注册了App.vue组件,通过template挂载到了index.html中的#app里,完全覆盖掉了index.html中的内容。下图(网上找的)展现了这一流程:
1.4 创建项目
vue create 目录名
cd 目录名
npm run serve
【注】其中会涉及到定制化安装,选项按需选择,不影响项目的主体,没有安装的之后也可以安装(之后的内容),要删除保存过的定制方案,在C:\Users\Admin找到.vuerc删除即可
二、vue-dev-tools(调试工具)
2.1 安装——命令行
https://github.com/vuejs/vue-devtools
- Clone this repo downloadzip 到桌面
- 安装依赖
npm install
- build目录项目就有各种浏览器的安装包
npm run build
- 打开 chrome -> 设置->更多工具->扩展应用->开发者模式->加载扩展程序->指向->build目录项目下的chrome
2.2 安装——工具
下载谷歌访问助手,访问Chrome网上应用店,搜索vue-dev-tools下载即可
三、vue-router(路由)
vue-router是官方提供的的路由工具,采用路由能轻松实现单页面程序
3.1 安装
npm i vue-router -S
【注】自定义安装vue-cli时选择了路由,则不需要安装
3.2 配置示例
// 引入需要的功能模块
import Router from 'vue-router'
// 引入需要渲染的组件
import Header from '@/components/Header'
// 安装 || 注册插件到全局
Vue.use(Router)
// 创建路由(传递配置)
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
// 配置路由(建立组件和请求的对应关系)
routes: [
// 重定向
{path: '/',redirect: '/home'},
{
path: '/home', // 路径
// 指向的组件变量名可以唯一标识一个路由,当path嵌套过深的时候,可以解决path过长的问题
name: 'home',
components: {
header: Header, // 注册已经引入的组件
default: () => import('@/views/home/index.vue') // 路由懒加载
},
// 子路由配置
children: [
{path: '',redirect: 'concern'},
{
path: 'concern',
name: 'concern',
components:{
default: () => import('@/components/home/Concern.vue')
}
},
// 动态路由配置{path:'xx/:动态路由变量',component:xx}
{
path: '/concern-detail/:id',
name: 'concern-detail',
components: {
default: () =>
import('@/components/ConcernDetail.vue')
}
}
]
}
]
})
3.3 渲染示例
<!--渲染路由配置中名为default的组件-->
<router-view></router-view>
<!--// 渲染路由配置中名为header的组件-->
<router-view name="header"></router-view>
3.4 跳转示例
3.4.1 声明式跳转
- router-link to=‘xx/路由名?a=1b=2’
- router-link :to=’{path:’’,name:‘xx’,params:{id:1},query:{a:2,b:3},redirect:’…’}’
name相当于起了一个名字,可以唯一标识一个路由,当path嵌套过深的时候,可以解决path过长的问题。
3.4.2 编程式跳转
不需要像声明式跳转一样将标签改为router-link,再编译回原来的标签,编程式跳转直接使用原生html的标签即可,只需在上面绑定一个事件,在事件中使用下方的语法即可完成跳转
// 添加一个路由 (记录到历史记录)
this.$router.push(xx/路由名?a=1b=2)
this.$router.push({name:'xx',params:{id:1},query:{a:2,b:3}})
// 替换一个路由 (不记录到历史记录)
this.$router.replace({name:'...'})
// 回退/前进
this.$router.go(-1|1)|goBack()
3.4.3 接收参数和数据
- 模板: {{$route.params|query|path}}
- 组件: this.$route.params|query
3.5 导航守卫
3.5.1 全局守卫
router.beforeRouteEnter(to,from,next){} 前置守卫,进入
进入条件
同步条件 本地(Cookie,localstroge,状态管理)
异步条件 读库(mysql,mongodb)
to 目标路由
from 当前路由next 是个函数
next() 是否跳转,默认参数为true
next(‘字符路径’)/next({对象路径}) 重定向
router.beforeRouteLeave(to,from,next){} 后置守卫,离开
3.5.2 路由独享的守卫
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
3.5.3 组件内的守卫
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) { 前置
// 在渲染该组件的对应路由被confirm 前调用
// 不能获取组件实例this,因为当守卫执行前,组件实例还没被创建
},
beforeRouteLeave (to, from, next) { 后置
// 导航离开该组件的对应路由时调用
// 可以访问组件实例this
}
}
路由数据预载:
router.beforeEach((to,from,)=>{})//全局
beforeEnter:(to,from,)=>{}//独享
beforeRouteEnter(to,from,next){//组件内部
1. 数据附加到目标路由上 to.query.数据名=值
2. next( _this => _this.属性="拿到的数据")
}
四、vuex(状态管理)
store完整的状态管理对象,适合用来开发中大型应用,集中式数据管理, 一处修改,多处使用
4.1 配置
npm i vuex -s
import vuex from 'vuex // 引入
Vue.use(vuex) // 安装插件
new Vue({store}) // 注册到根
4.2 图示
五、UI库
推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用。
5.1 element-ui(PC端)
一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库
5.1.1 安装
推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用。
npm i element-ui -S
5.1.2 引入(main.js)
- 完整引入
import Vue from 'vue'
import ElementUI from 'element-ui'
Vue.use(ElementUI);
- 按需引入
import Vue from 'vue'
import { Button, Select, ...... } from 'element-ui';
Vue.use(Button)
Vue.use(Select)
5.1.3 使用
根据官方文档中各组件的使用举例来使用即可,最重要的是理解要使用的组件所依赖的数据
5.2 vant(移动端)
一套轻量、可靠的移动端 Vue 组件库
5.2.1 安装
npm i vant -S
5.2.2 引入
- 完整引入
import Vue from 'vue';
import Vant from 'vant';
Vue.use(Vant);
- 按需引入
import Vue from 'vue'
import{Popup, Button, ......}from'vant'
Vue.use(Popup);
Vue.use(Button);
......
5.2.3 使用
根据官方文档中各组件的使用举例来使用即可,最重要的是理解要使用的组件所依赖的数据
六、axios(数据请求)
6.1 安装
npm i axios
6.2 特点
处理多次请求
- 并行无关联
axios()
axios()
- 串行有关联
axios(1).then(res=>axios(2).then())
let res1 = await axios(1)
let res2 = await axios(2)
- 抓取所有的结果,做一次渲染
axios.all ~~ Promise.all
axios.all([
axios.get('https://api.github.com/xxx/1'),
axios.get('https://api.github.com/xxx/2')
])
.then((res)={res==array<object>})
array<object> == [{1},{err:xx,msg:xxx,data:{}}]
axios.all([
axios.get('https://api.github.com/xxx/1'),
axios.get('https://api.github.com/xxx/2')
])
.then(axios.spread(function (userResp, reposResp) {
// 上面两个请求都完成后,才执行这个回调方法
console.log('User', userResp.data);
console.log('Repositories', reposResp.data);
}));
当所有的请求都完成后,会收到一个数组,包含着响应对象,其中的顺序和请求发送的顺序相同,可以使用axios.spread 分割成多个单独的响应对象
6.3 拦截器
axios.interceptors.request.use(function (config) {
// 请求之前,做点事
// config.headers={"Content-Type":"xxxxx"} 添加请求头
console.log('显示loading')
return config;
}, function (error) {
// 错误请求,做点事
return Promise.reject(error);
});
// 响应式,数据返回时
axios.interceptors.response.use(function (response) {
console.log('loading消失')
return response;
}, function (error) {
return Promise.reject(error);
});