Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
准备 vue-cli
使用 Vue 你可以通过 webpack 打包,也可以通过专用的 vue-cli 快速构建项目。如果想要使用 webpack 完全自定义配置可以参考>>> 关于 WebPack 你需要知道的一些事。
这里采用 vue-cli ,在开始前你需要知道:vue-cli 基于 webpack 和 webpack-dev-server ,并且配置好了基本的打包规则,它可以帮你用配置好的模板迅速搭建起一个项目工程来,避免了自己配置 webpack.config.js 的麻烦。
创建项目
注意使用 vue create 创建项目时,程序会让你选择是使用默认方案创建还是自定义创建
- Default : 采用默认方案自动创建项目,可能会安装一下自己用不到的内容
- Manually select features : 采用自定义方案手动创建项目,需要自己根据提示一步步配置
创建完成后,项目目录大概如下图所示:
注意:与 webpack 不同的是,使用 vue-cli 创建的项目默认会生成一个 public 文件夹,该文件夹下的文件会在打包后直接复制到输出文件夹中,同时里面的 index.html 即是使用 webpack.config.js 文件中 HtmlWebpackPlugin 插件里配置的 html 文件
···
vue ui // 浏览器打开图形交互界面创建或管理项目,更直观
···
创建方式与命令行方式几乎没有差别,还可以管理项目。
插件
插件面板用于安装一些扩展 CLI 命令的插件,这些插件多为一些部署模板,用于快速安装并部署项目所需的依赖。你也可以自定义一些自己的模板方案>>>插件开发指南
- @vue/cli-service :启动一个基于 webpack-dev-serve 的开发服务器并附带开箱即用的模块热加载,package.json 中的 serve、 build、lint 命令均源于此,是众多命令运行的基础。
- @vue/cli-plugin-babel :快速安装并配置 babel 依赖。
- @vue/cli-plugin-eslint :快速安装并配置 eslint 依赖。
使用 vue ui 打开图形界面管理项目时,上方还会提示未安装 vuex 与 vue-router,通过此处安装的话会先安装一下两个插件:
- @vue/cli-plugin-router :根据模板快速安装并配置 vue-router 依赖。
- @vue/cli-plugin-vuex :根据模板快速安装并配置 vuex 依赖。
默认 add 命令安装 CLI 插件后会自动运行生成器,安装并配置 vuex 及 vue-router。
由于 vue add 或 vue invoke 可能会修改项目文件,为了避免错误,建议运行前先提交下项目。
注意:这些插件也可以通过 npm 命令安装及卸载。
依赖
其他非 vue-cli 的插件直接通过 npm 命令安装卸载即可。
- core-js :JavaScript的模块化标准库,使用 ES3 语法兼容高版本语法,确保项目兼容性。
- vue :前端三大框架,快速开发。
- babel-eslint :基于 ESLint 对非 ES 标准的 Babel 代码规范。可以通过 .eslintrc 或 package.json 中的 eslintConfig 字段来配置。
- eslint :协同开发,代码规范,只针对已发布的 ES 标准,可以通过 .eslintrc 或 package.json 中的 eslintConfig 字段来配置。
- esling-plugin-vue :使用 ESLint 检查 .vue 文件以及 .js 文件中 <template> 和 <script> 的代码.
- vue-template-compiler :预编译 vue ,大多时候与 vue-loader 一起用,需要与 vue 版本一致。
项目配置面板可自定义配置各工具参数,比如这里的 Vue CLI 及 ESLint ,当然你也可以通过对应的配置文件进行配置。
任务面板显示当前的任务配置及运行情况:
- serve :开发环境,实时编译和热更新,对应 package.json 中的 “serve”: “vue-cli-service serve”,
- build :生产环境,编译并压缩代码,对应 package.json 中的 “build”: “vue-cli-service build”,
- lint :检查并修复文件中的代码错误,对应 package.json 中的 “lint”: “vue-cli-service lint”,
- inspect :序列化 webpack 配置文件并显示出来,注意它不是真实存在的 webpack.config.js ,需要自定义 webpack 配置需要修改 vue.config.js 中的 configureWebpack 项
默认通过 vue create 命令创建的项目可以直接跑起来了。更多配置参考>>> vue.config.js
基础
一般项目中会使用 vue-router 管理路由,vuex 管理状态。默认 vue create 时没有安装这两个依赖,所以这里需要安装下。安装完成后查看 main.js 中的代码如下:
- store :状态管理,引入的 vuex
- router :路由管理,引入的 vue-router
- render :渲染函数,通过 JavaScript 代码直接渲染 DOM
- $mount :挂载实例,将实例化后的 DOM 对象挂载到 #app 上,等同于 el 配置项
基础的模板包含 <template>、<script>、<style> 三部分。
template
模板结构,这里面的代码渲染后用于前端显示。
命令
- v-text : 解析文本,更新元素的 textContent
- {{ 文本内容 }} :解析文本,更新部分的 textContent
- v-html :解析 HTML 代码,更新元素的 innerHTML
- v-show :切换元素的 display
- v-if :条件渲染 DOM ,可与 v-else , v-else-if 配合使用
- v-for :遍历元素,注意 key
- v-on :绑定事件
- v-bind :绑定属性,可以是自定义属性,注意动态组件切换添加 is
- v-module :双向绑定,仅适用于 input 、 select 、 textarea
- v-pre : 跳过当前元素的编译
- v-once :当前元素只渲染一次
- ref :注册引用信息,通过 this.$refs 调用
内置组件
- slot : 插槽,<slot> 元素自身将被组件标签内部代码替换
- transition :为单个元素/组件添加过渡效果
- transition-group :为多个元素/组件添加过渡效果
- component :渲染一个“元组件”为动态组件。依 is 的值,来决定哪个组件被渲染
- keep-alive :缓存动态组件
script
模板行为,处理数据或动作效果的代码放这里。
- components :注册组件
- props :接收父组件数据
- data :数据对象,用于数据绑定
- methods :函数方法,根据需求处理组件中的数据
- computed :计算属性,计算需要的值
- watch :监听数据变化并自动执行方法
- 生命周期 :beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、actived、deactivated、beforeDestroy、destroyed、errorCaptured
style
模板样式,注意使用 scoped 属性防止样式污染。
更多使用参考 >>> 官网教程
路由管理
vue-router 是 Vue.js 官方的路由管理器。所谓路由,就是点击链接页面导航到哪里去。
基础
script 标签引入
npm 包管理工具安装
通过 npm install vue-router 命令安装路由,需要自行配置。
通过 vue add router 安装,程序会自动安装一个 @vue/cli-plugin-router 插件,然后自动下载 vue-router 并自动配置。默认创建的 router 文件夹下生成的路由配置文件如下:
但是我们一般不这么使用,为了程序更好地拓展及后期维护,一般针对 views 下的每个视窗创建独立的路由文件并分别管理即嵌套路由。
Router 与 View 一一对应
统一入口文件
独立视窗路由
基本参数
路由中可配置的参数有:
- path :字符串,路由的跳转路径
- name :字符串,路由的名称,用于命名路由,通过名称来标识路由
- alias :字符串或数组,路由的别名,将其他路径指向该路由视图
- redirect :字符串,路由重定向,将当前路由地址重定向到一个新的路由地址
- component :路由指向的组件视图
- props:布尔、对象或函数,使用 props 将组件和路由解耦,实现动态路由,并传递一定参数
导航守卫
导航守卫是路由跳转过程中不同时机触发的一些钩子函数。
- beforeEach :全局前置守卫
- beforeResolve :全局解析守卫,与 beforeEach 类似,区别是:在导航被确认前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用
- afterEach :全局后置钩子
- beforeEnter :路由独享的守卫
- beforeRouteEnter :组件内的守卫,导航进入该组件的对应路由前调用
- beforeRouteUpdate :组件内的守卫,在该组件的当前路由改变前调用
- beforeRouteLeave :组件内的守卫,导航离开该组件的对应路由前调用
状态管理
对于应用中使用到的公共变量,我们可以通过 vuex 进行状态管理。
每一个 Vuex 应用的核心就是 store(仓库)。store 基本上就是一个容器,它包含着你的应用中大部分的状态。
基础知识
配置选项
- state :store 的状态属性,类似于 vue 中的 data ,具体组件通过 mapState 引用
- getters :store 的计算属性,类似于 vue 中的 computed ,具体组件通过 mapGetters 引用
- mutations :store 的方法属性,类似于 vue 中的 methods ,具体组件通过 mapMutations 引用,更改 state 的唯一方法是提交 mutation
- actions :store 的方法属性,类似于 mutations ,具体组件通过 mapActions 引用,主要用于异步操作
- modules :用于分割子模块(module)。每个模块拥有自己的 state、mutation、action、getter,方便管理
- namespaced :是否启用命名空间,分模块管理状态时建议启用,避免各模块中变量名冲突,在组件中引用时需带上模块名
- strict :是否启用严格模式,严格模式下,任何 mutation 处理函数以外修改 Vuex state 都会抛出错误
- plugins :一个数组,包含应用在 store 上的插件方法
- devtools :为某个特定的 Vuex 实例打开或关闭 devtools
实例属性
- state :Object,只读,根状态属性
- getters :Object,只读,暴露出注册的 getter
实例方法
- commit :提交 mutation
- dispatch :分发 action
- replaceState :替换 store 的根状态,仅用状态合并或时光旅行调试
- watch :响应式地侦听 fn 的返回值,当值改变时调用回调函数
- subscribe :订阅 store 的 mutation
- subscribeAction :订阅 store 的 action
- registerModule :注册一个动态模块
- unregisterModule :卸载一个动态模块
- hasModule :检查该模块的名字是否已经被注册
- hotUpdate :热替换新的 action 和 mutation
辅助函数
- mapState :将 state 映射为组件的计算属性
- mapGetters :将 getters 映射为组件的计算属性
- mapMutations :将 mutations 映射为组件的方法属性
- mapActions :将 actions 映射为组件的方法属性
- createNamespacedHelpers :创建基于命名空间的组件绑定辅助函数
实际应用
对于公共状态,如果项目比较大,为了方便管理,一般我们也建议分模块单独管理各自的状态,方便后期维护。
分模块管理公共状态
统一入口文件
独立状态管理
服务端渲染(SSR)
对于一个单页面应用(SPA:Single Page Application),服务端渲染(SSR:Server Side Render)相较于客户端渲染(CSR:Client Side Render)具有更快的首屏加载及更好的 SEO 等优势,但同时也伴随着开发条件限制、服务器压力增大等弊端。Vue.js 基于 node.js 可以通过 vue-server-renderer 实现服务端渲染的效果。因为即使不用服务端渲染也不影响前端显示效果,所以本文档暂不对 SSR 做深入探讨。
过渡/动画效果
在 CSS 中过渡(transition)与动画(animation)是有一定的差别的。过渡可以看作一些简单的动画,但只能设置起始关键帧间的动画效果,而动画则可以通过 @keyframe 定义关键帧逐帧设置动画效果;另外,过渡需要事件触发,而动画不需要。
Vue 中通过 transition 组件配置实现过渡和动画效果。
基础知识
transition 内置组件可定义组件/元素切换时的过渡效果,在进入/离开的过渡中,会有 6 个 class 切换:
- v-enter:定义进入过渡的开始状态
- v-enter-active:定义进入过渡生效时的状态
- v-enter-to:定义进入过渡的结束状态
- v-leave:定义离开过渡的开始状态
- v-leave-active:定义离开过渡生效时的状态
- v-leave-to:定义离开过渡的结束状态
注意:Vue 过渡效果是在使用 v-if 或 v-show 指令控制 DOM 元素显示隐藏时触发的。
transition 标签
使用 transition 标签包裹需要显示隐藏的元素,在其内部的内容根据设置可以实现过渡效果。
transition 配置项
上面代码中用到的 name 属性是最常用的配置项,主要用来避免在同一组件中避免各元素切换效果实现的冲突。包含 name 属性外的配置项还有:
- name:命名 transition,如果未命名则其过渡类名以 v- 开头,命名后以 diyName- 开头
- duration:自定义进入和移出的持续时间
- mode:过渡模式,out-in 或 in-out
- in-out:新元素先进行过渡,完成之后当前元素过渡离开。
- out-in:当前元素先进行过渡,完成之后新元素过渡进入。
- appear:设置节点在初始渲染的过渡
- enter-class:自定义进入前的过渡类名
- enter-active-class:自定义进入时的过渡类名
- enter-to-class:自定义进入后的过渡类名
- leave-class:自定义离开前的过渡类名
- leave-active-class:自定义离开时的过渡类名
- leave-to-class:自定义离开后的过渡类名
原生 CSS 过渡
diyName 是自定义的 transition 名称
原生 CSS 动画
cssAnimation 是自定义的 transition 名称,cssAnimationName 是自定义的动画名
第三方 CSS 库实现动画特效
可以设置 enter-class、enter-active-class、enter-to-class、leave-class、leave-active-class、leave-to-class 的类名为第三方 CSS 动画库(如 Animate.css)中的类名,以应用对应的动画效果。
JavaScript 钩子
除了使用 CSS 实现过渡及动画效果,还可以使用 JavaScript 实现更丰富的效果,可用的钩子有:
- before-enter:进入前,
function (el) {}
- enter:进入时,
function (el, done) {}
- after-enter:进入后,
function (el) {}
- enter-cancelled:进入被打断时,
function (el) {}
- before-leave:离开前,
function (el) {}
- leave:离开时,
function (el, done) {}
- after-leave:离开后,
function (el) {}
- leave-cancelled:离开被打断时,
function (el) {}
当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。
第三方 JS 库实现动画特效
可以是会用 JavaScript 自定义一些动画效果,也可以引入一些第三方 JS 库实现动画效果,比如这里引入 anime.js 实现动画效果。
HTML 结构
Script 内容
列表过渡(transition-group)
transition 只能对他所包裹的单个 DOM 对象实现过渡动画效果,如果要对一个 DOM 列表中的每个元素都应用过渡动画效果则需要使用 transition-group 组件。
组件间传值
父向子传值(props) & 子向父传值($emit)
项目中组件间传值一般会通过 store 进行状态管理,但是封装一些基础组件的时候可能需要使用 vue 原生的 props 与 $emit 实现组件间传值。
父组件相关代码(PassData.vue)
子组件相关代码(PassDataChild.vue)
provide / inject
props 与 $emit 一般用于父子组件间数据的通信,如果想要允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效,那么可能需要使用 provide / inject,注意:这俩选项需要一起使用。
- provide:提供其他组件要用的参数。
Object | () => Object
- inject:接收其他组件提供的参数。
Array | { [key: string]: string | Symbol | Object }
提供参数
接收参数
注意:provide 与 inject 均写到 export default {} 中即可。
配置文件 vue.config.js
类似于 webpack.config.js ,如果你在项目中使用了 vue-cli ,那么就需要对 vue.config.js 进行配置。
- publicPath:部署应用包时的基本 URL,与 webpack 的 output.publicPath 一致
- outputDir:当运行 vue-cli-service build 时生成的生产环境构建文件的目录,对应 webpack 的 output.path
- assetsDir:放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录
- indexPath:指定生成的 index.html 的输出路径 (相对于 outputDir),也可以是一个绝对路径
- filenameHashing:生成的静态资源文件名是否包含 hash 值
- pages: 在 multi-page 模式下构建应用。每个 page 对应一个入口文件
- lintOnSave:是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码
- runtimeCompiler:是否使用包含运行时编译器的 Vue 构建版本
- transpileDependencies:默认 babel-loader 会忽略所有 node_modules 中的文件。需要显式转译的可以在这个选项中列出来
- productionSourceMap:是否需要生产环境的 source map
- crossorigin:设置生成的 HTML 中 link 和 script 标签的 crossorigin 属性
- integrity:是否在生成的 HTML 中的 link 和 script 标签上启用子资源完整性(SRI)验证
- configureWebpack:如果是对象,则会通过 webpack-merge 合并到最终的配置中;如果是函数,则会接收被解析的配置作为参数
- chainWebpack:是一个函数,接收基于 webpack-chain 的 ChainableConfig 实例。允许对内部的 webpack 配置进行更细粒度的修改
- css:CSS 的相关配置
- css.requireModuleExtension:是否只有 *.module.[ext] 结尾的文件才会被视作 CSS Modules 模块
- css.extract:是否将组件中的 CSS 提取至一个独立的 CSS 文件中
- css.sourceMap:是否为 CSS 开启 source map
- css.loaderOptions:向 CSS 相关的 loader 传递选项,支持:css、postcss、sass、less、stylus
- devServer:对应 webpack-dev-server 的配置
- parallel:是否为 Babel 或 TypeScript 使用 thread-loader
- pwa:向 PWA 插件传递选项
- pluginOptions:这是一个不进行任何 schema 验证的对象,因此它可以用来传递任何第三方插件选项