目录
一.简介及基础
1.Vue2/3
(1)版本
- vue2.x中绝大多数的API与特性,在 vue3.x 中同样支持, vue3.x中还新增了3.x所特有的功能,并废弃了某些 2.x 中的旧功能
- 新增的功能例如: 组合式 API, 多根节点组件, 更好的TypeScript支持等
- 废弃的旧功能如下: 过滤器, 不再支持$on, $off和$once实例方法等
- https://v3.vuejs.org/guide/migration/introduction.html
(2)调试工具
Chrome 浏览器在线安装 vue-devtools
- vue 2.x: https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd
- vue 3.x: https://chrome.google.com/webstore/detail/vuejs-devtools/ljjemllljcmogpfapbkkighbhhppjdbg
- vue2和vue3的浏览器调试工具不能交叉使用
2.SPA
(1)概念
单页面应用程序(Single Page Application)简称SPA, 一个Web网站中只有唯一的一个 HTML 页面,所有的 功能与交互都在这唯一的一个页面内完成
特点:
- 所有功能局限于一个web页面中,仅在该web页面初始化时加载相应的资源(HTML,JS,CSS)
- 一旦页面加载完成了,SPA 不会因为用户的操作而进行页面的重新加载或跳转,而是利用JavaScript动态地变换HTML的内容,从而实现页面与用户的交互
(2)优缺点
优点:
- 良好的交互体验 (单页应用的内容的改变不需要重新加载整个页面; 获取数据通过Ajax异步获取; 没有页面之间跳转,不会出现“白屏现象”)
- 良好的前后端工作分离模式 (后端专注于提供API 接口,更易实现API接口的复用; 前端专注于页面的渲染,更利于前端工程化的发展)
- 减轻服务器的压力 (服务器只提供数据,不负责页面的合成与逻辑的处理, 吞吐能力会提高几倍)
缺点:
- 首屏加载慢 (可使用: 路由懒加载, 代码压缩, CDN 加速, 网络传输压缩)
- 不利于SEO (SSR服务器端渲染)
(3)快速创建vue的SPA项目
快速创建工程化的SPA项目方式 | vite | vue-cli |
---|---|---|
支持的vue版本 | 仅支持vue3.x | 支持2.x 和 3.x |
是否基于webpack | 否 | 是 |
运行速度 | 快 | 较慢 |
功能完整度 | 小而巧(逐渐完善) | 大而全 |
是否建议在企业级开发中使用 | 目前不建议 | 建议 |
3.vite
基于创建vite创建vue3.x
- 配置项目 npm init vite-app 项目名称
- 安装依赖包 npm i
- 运行项目 npm run dev
运行流程: 通过main.js把App.vue渲染到index.html的指定区域中
//main.js
// 1. 导入creatApp函数
import { createApp } from 'vue'
// 2. 导入待渲染的组件
import App from './App.vue'
import './index.css'
// 3. 调用函数 渲染模板结构至指定el区域
createApp(App).mount('#app')
4.template
渲染模板, 只起包裹作用
- 在vue 2.x的版本中, <template>节点内的DOM结构仅支持单个根节点
- 在 vue 3.x 的版本中,<template>中支持定义多个根节点
二.组件的基本使用
1.Class与Style绑定
动态绑定: 使用v-bind: ,结合三元表达式,动态绑定class属性的值和行内的style样式
数组语法绑定: 三元表达式的数组动态绑定 (导致模板结构臃肿)
对象语法绑定: 对象中以键值对形式,动态添加移除类名
2.props
自定义验证函数, 封装组件时,精准控制prop属性值
props:{ //自定义属性 父组件向子组件传值可用
propA:{ //自定义属性指向一个对象
validator(val){ //validator函数, 对propA属性值进行校验 形参接收属性值 返回true验证通过, false验证不通过
return ['success','fail'].indexOf(val) !== -1 //匹配字符串,必须是这两个,不然报错
}
}
},
3.计算属性
- 必须定义在 computed 节点中
- 必须是一个 function 函数
- 必须有return返回值, 侧重于得到一个计算的结果
- 必须当做普通属性使用
计算属性相比于方法: 会缓存计算结果,只有计算属性依赖项发生变化时,才重新进行计算, 性能更好
4.自定义事件
监听组件内的状态变化 (类似于vue2, 子组件向父组件传值)
- 为自定义组件封装的自定义事件,必须事先在emits节点中声明 e.g: emits:[ 'change']
- 通过 this.$emit('自定义事件的名称') 方法进行触发, 第2个参数形参可为自定义事件传参
- 使用自定义的组件时,可以通过 v-on (@) 的形式监听自定义事件
5.组件上的v-module
- v-model双向数据绑定指令,当需要维护组件内外数据的同步时,可在组件上使用 v-model 指令
- e.g: 外界数据的变化会自动同步到counter组件中, counter组件中数变化,也会自动同步到外界
6.侦听器
- watch节点下定义
- immediate:true: 侦听器立即被调用(默认,组件初次加载完后不会调用侦听器)
- deep: true: 监听对象属性值的变化 (watch侦听对象,无法监听到对象属性值的变化)
计算属性和侦听器对比:
- 计算属性侧重于监听多个值的变化,最终计算并返回一个新值
- 侦听器侧重于监听单个数据的变化,最终执行特定的业务处理,不需要有任何返回值
data(){
return{
info: { username : 'admin', password: ''}
}
},
watch:{
info:{ //监听info对象的变化 也可'info.username':{ }监听某个属性值的变化
async handler(newVal, oldVal){ //handler固定写法, 当username变化时,调用handler
const { data: res } = await axios.get('https://www.escook.cn/api/finduser/${newVal}') //解构出data, 并重命名为res
console.log(res); //Object { status: 0, message: "用户名可用!" }
},
deep: true, //监听对象时,使用deep对象,否则对象中的username等属性值无法被监听
immediate: true, //组件加载完毕后立即被调用一次当前的watch侦听器
}
}
7.生命周期
8.组件间数据共享
(1)父子及兄弟组件间
- 父->子共享数据: 自定义属性, 父v-bind属性绑定, 子props接收
- 子->父共享数据: 自定义事件
- 父<->子双向数据同步: v-module指令
//App.vue父组件 父子组件双向数据共享
<my-son1 v-model:num="count"></my-son1> <!-- 父子数据双向同步 -->
// Son1.vue 子组件
<p>Son1.vue------{{ num }}</p>
<button type="button" @click="add">+1</button>
props: ['num'],
emits: ['update: num'], //自定义事件
methods:{
add(){
this.$emit('update:num', this.num + 1)
}
},
(2) 兄弟组件共享数据
EventBus.js, 借助mitt第三方包创建eventBus对象,从而实现兄弟组件之间的数据共享
(3)后代关系组件间数据共享
父节点的组件向其子孙组件共享数据,组件之间的嵌套关系比较复杂, 使用provide(发送方)和inject(接收方)实现数据共享
(4)全局数据共享
- vuex 是终极的组件之间的数据共享方案, 实现大范围数据共享, 在企业级vue项目开发中,可让组件之间的数据共享变得高效,清晰,且易于维护
- store中存共享数据
9.全局配置axios
10.路由
- vue-router 3.x 只能结合 vue2 进行使用 https://router.vuejs.org/zh/
- vue-router 4.x 只能结合 vue3 进行使用 https://next.router.vuejs.org/
(1)vue-router4.x用法
- 在项目中安装vue-router (npm i vue-router@next -S)
- 定义路由组件
- 声明路由链接<router-link to=" ">和占位符<router-view>
- 创建路由模块
- 导入并挂载路由模块 ( main.js中app.use(router)挂载 )
(2)命名路由
- name属性为路由规则定义名称, name值不能重复,必须保证唯一性
实现声明式导航:
- <router-link>标签动态绑定to属性的值,并通过name属性指定要跳转到的路由规则,还可用params属性指定跳转期间要携带的路由参数
实现编程式导航:
- 调用push函数期间指定一个配置对象,name是要跳转到的路由规则,params是携带的路由参数
// 按需导入路由模块
import { createRouter, createWebHashHistory } from 'vue-router'
// 导入相关组件
import Home from './components/Start/Home.vue'
import Movie from './components/Start/Movie.vue'
// 创建路由实例对象
const router = createRouter({
// 指定路由工作模式 以哈希进行组件的切换
history: createWebHashHistory(),
// 路由高亮, 设置当前正在使用的组件的css样式, 若未设置,默认类名为router-link-active
linkActiveClass: 'active-router',
routes:[
{ path: '/' , redirect: '/home'}, //路由重定向
{ path: '/home', component: Home },
{ path: '/movie', component: Movie, redirect: '/tab1',children:[ //声明子路由, 可重定向打开即显示
{path: 'tab1', component: Tab1}
]},
]
})
// 声明全局路由导航守卫 使用路由规则前都会触发守卫,实行拦截
router.beforeEach(()=>{
console.log('1');
})
export default router
三.vue-cli
1.简介
- 俗称: vue 脚手架, 是 vue 官方提供的,快速生成vue工程化项目的工具 https://cli.vuejs.org/zh
- 特点: 开箱即用, 基于 webpack, 功能丰富且易于扩展, 支持创建vue2和vue3的项目
- 安装: npm i -g @vue/cli 查看版本: vue --version
2.创建项目
基于命令行: vue create 项目名称
基于可视化面板vue ui: 终端 vue ui
- 勾选需要安装的功能(Choose Vue Version,Babel,CSS 预处理器,使用配置文件)
- 勾选 vue 的版本和需要的预处理器
- 创建项目并自动安装依赖包
四.组件库
1.简介
- bootstrap只提供了纯粹的原材料(css 样式,HTML结构以及JS 特效),需要由开发者做进一步的组装和改造
- vue组件库是遵循vue语法, 高度定制的现成组件,开箱即用
最常用的vue组件库
PC 端
- View UI(http://v1.iviewui.com/)
-
vue2 的项目使用旧版的Element UI(https://element.eleme.cn/#/zh-CN)
-
vue3 的项目使用新版的Element Plus(https://element-plus.gitee.io/#/zh-CN)
移动端
- Mint UI(http://mint-ui.github.io/#!/zh-cn)
- Vant(https://vant-contrib.gitee.io/vant/#/zh-CN/)
2.引入element-ui
(1)完整引入
- 操作简单,但是会额外引入一些用不到的组件,导致项目体积过大 (参考官方文档)
(2)按需引入
操作相对复杂一些,但是只会引入用到的组件,能起到优化项目体积的目的
- 安装 npm i babel-plugin-component -D
- 修改根目录下的babel.config.js配置文件,新增plugins节点
- 按需引入部分组件, 在main.js中
五.拦截器
- Interceptors, 会在每次发起ajax请求和得到响应的时候自动被触发
- 应用场景: Token 身份认证, Loading 效果...
import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import { Loading } from 'element-plus'
import axios from 'axios'
axios.defaults.baseURL = 'https://www.escook.cn'
//声明变量,存储Loading组件的实例对象
let loadingInstance = null
// 配置请求拦截器
axios.interceptors.request.use(config => {
loadingInstance = Loading.service({ fullscreen: true}) //展示Loading效果
// 配置Token认证
config.headers.Authorization = 'xxx'
return config // 固定写法
})
// 配置响应拦截器
axios.interceptors.response.use( respose => {
loadingInstance = Loading.service({ fullscreen: false}) // 关闭loading效果
return respose
})
Vue.prototype.$http = axios
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')
六.proxy 跨域代理
- 把axios的请求根路径设置为 vue 项目的运行地址(接口请求不再跨域)
- vue项目发现请求的接口不存在,把请求转交给 proxy 代理
- 代理把请求根路径替换为 devServer.proxy 属性的值,发起真正的数据请求
- 代理把请求到的数据,转发给 axios
//vue.config.js中 配置proxy代理
module exports = {
devServer: {
proxy: 'https://www.escook.cn'
}
}
- devServer.proxy 提供的代理功能,仅在开发调试阶段生效
- 项目上线发布时,依旧需要API接口服务器开启CORS跨域资源共享