【Vue】学习路线图(VIP珍藏版)
MVVMMVVM(Model-View-ViewModel)是一种软件设计模式,由微软WPF(用于替代WinForm,以前就是用这个技术开发桌面应用程序的)和Silverlight(类似于Java Applet,简单点说就是在浏览器上运行WPF)的架构师Ken Cooper和Ted Peters开发,是一种简化用户界面的事件驱动编程方式。由John Gossman(同样也是WPF和Sliverli
爆肝两天,整理了下Vue的常用内容,
穿插开发过程中遇到的问题与总结,
后期不定期更新[开发遇到的问题与小结]到本文章中,
欢迎各位大佬指正~
目录
HTML (HyperText Markup Language)
⑧.env.development、.env.production 配置文件
v-model 指令在表单控件元素上创建双向数据绑定。编辑输入框
HTML、CSS和JavaScript基础知识
- 学习HTML标记语言的基本结构和常用标签,它提供了网页的结构。
- 掌握CSS样式的基本概念,包括选择器、盒模型和布局等。
- 理解JavaScript的基本语法、数据类型、变量、函数和条件语句等。
学习HTML、CSS和JavaScript是学习Vue的前提,下面是关于这些内容的详细信息:
HTML标记语言
HTML (HyperText Markup Language)
定义与用途:
HTML 是构建和设计网页内容的标准标记语言。它不仅定义了网页的结构,还能够通过链接实现资源之间的关联,这是其 "HyperText" 部分的核心功能。
基础学习:
掌握 HTML 是理解网页构造的基础。通过学习如 <html>, <head>, <body>, <div>, <p>, 和 <img> 等标签,你可以创建基本的网页结构。
标签与属性:
每个 HTML 标签可能有多个属性,它们提供了额外的信息和功能。例如,<img src="image.jpg" alt="描述"> 中的 src 和 alt 都是 <img> 标签的属性。
布局技巧:
学习如何使用 HTML 标签进行网页布局是重要的。传统布局使用表格,而现代布局倾向于使用 <div> 和 CSS。
HTML5: 最新版本的 HTML
语义化标签
HTML5 引入了更多语义化标签,如 <article>, <section>, <header>, <footer>, 和 <nav> 等,这些标签为网页内容提供了明确的结构和含义,有助于搜索引擎优化(SEO)和辅助技术。
新特性
HTML5 包含新的表单控制元素(如 <input type="email">),媒体播放的 <audio> 和 <video> 标签,以及用于高级功能的 JavaScript API(如地理位置、拖放 API 等)。
head 元素
<head> 部分包含了网页的元数据,如 <title> 标签定义网页标题,<meta> 标签控制网页的字符集和视口设置,以及 <link> 和 <script> 标签用于引入外部的 CSS 和 JavaScript 文件。
CSS样式
-
定义与用途: CSS 是一种强大的样式表语言,用于增强 HTML 文档的表现形式。它允许开发者为网页元素指定颜色、字体、间距、布局等多种视觉属性。
-
核心概念: 掌握 CSS 的基础知识包括理解选择器(用于指定要样式化的 HTML 元素),盒模型(决定内容的布局和间隙),以及多种布局技术(用于组织页面结构)。
- 选择器: 包括基本的元素选择器、类选择器和 ID 选择器,它们定义了哪些元素应用特定的样式。
- 盒模型: 包含了元素内容(content)、内边距(padding)、边框(border)和外边距(margin)的概念。
- 布局: 包括传统的浮动(floats)和定位(positioning),以及现代的网格(grid)和弹性盒(flexbox)布局。
-
学习资源:
- CSS 参考手册: 提供全面的 CSS 属性和概念解释,是学习和实践中的重要资源。
- 教程文章: 网络上有丰富的教程文章,它们提供了从基础到高级的 CSS 知识点。
-
新特性: CSS3 引入了许多创新的特性,如动画、过渡、变换和圆角等,使得页面效果更加丰富和动态。
-
布局教程:
- Flexbox: 一种高效的布局方式,用于在一维空间内分配和对齐元素。
- Grid 布局: 提供了在二维空间内控制布局的强大能力,使复杂布局的实现变得简单。
-
性能优化:
- 重绘 (Repaints) 和 重排 (Reflows): 在样式变更时,浏览器可能需要重新渲染页面的部分或全部。理解这些过程对于编写高性能的 CSS 代码至关重要。
JavaScript编程语言
JavaScript是一种用于构建交互式网页和Web应用程序的脚本语言。
JavaScript: 动态网页与应用程序的灵魂
-
定义与用途: JavaScript 是一种高级的、解释执行的编程语言,广泛应用于网页交互设计和构建功能丰富的 Web 应用程序。它允许开发者实现客户端脚本,以提供动态的用户界面和响应用户操作。
-
编程基础: 学习 JavaScript 涵盖了编程的基本概念,包括但不限于:
- 变量: 存储数据值的容器,可用于数值、文本(字符串)、布尔值等数据类型。
- 数据类型: 包括基本类型(如字符串、数字、布尔值)和复杂类型(如对象和数组)。
- 函数: 定义可重复使用的代码块,用于执行特定任务。
- 条件语句: 如
if
语句,用于基于不同条件执行不同代码块。
-
核心概念:
- 基本语法: 掌握 JavaScript 的语法规则,包括变量声明、操作符、控制结构等。
- DOM 操作: 学习如何使用 JavaScript 操作文档对象模型(DOM),以动态修改页面内容和结构。
- 事件处理: 理解如何响应用户动作,如点击、滚动等事件。
- AJAX: 使用异步 JavaScript 和 XML (AJAX) 技术从服务器获取数据而无需重新加载页面。
-
进阶知识:
- 闭包: 函数和其周围状态(词法环境)的组合,使得函数可以访问外部作用域中的变量。
- 作用域和
this
上下文: 理解函数和变量的作用域,以及this
关键字在不同上下文中的行为。 - 原始值和引用值: 区分 JavaScript 中的原始数据类型和引用数据类型的不同。
- 变量和函数提升 (Hoisting): 理解变量声明和函数声明在代码执行前如何被移至作用域顶部。
-
设计模式与原型: 掌握 JavaScript 设计模式、原型链和继承机制,以编写更加高效和可维护的代码。
-
现代 JavaScript:
- ES6+ 新特性: 学习包括箭头函数、模板字面量、解构赋值、类和模块等在内的现代 JavaScript 特性。
- 异步编程: 掌握 Promise、async/await 等异步编程技术,优化代码的异步行为和性能。
- 模块: 使用模块化技术组织和重用代码,增强代码的可读性和维护性。
-
调试技巧: 学习使用浏览器的开发者工具进行 JavaScript 代码调试,以快速定位和解决问题。
Vue概述
什么是MVVM
MVVM(Model-View-ViewModel)是一种软件设计模式,由微软WPF(用于替代WinForm,以前就是用这个技术开发桌面应用程序的)和Silverlight(类似于Java Applet,简单点说就是在浏览器上运行WPF)的架构师Ken Cooper和Ted Peters开发,是一种简化用户界面的事件驱动编程方式。由John Gossman(同样也是WPF和Sliverlight的架构师)与2005年在他的博客上发表。
MVVM源自于经典的MVC(Model-View-Controller)模式。MVVM的核心是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用。其作用如下:
该层向上与视图层进行双向数据绑定
向下与Model层通过接口请求进行数据交互
MVVM已经相当成熟了,主要运用但不仅仅在网络应用程序开发中。当下流行的MVVM框架有Vue.js,Anfular JS
为什么要使用MVVM
MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大好处
低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
可复用:可以把一些视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑。
独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewMode),设计人员可以专注于页面设计。
可测试:界面素来是比较难以测试的,而现在测试可以针对ViewModel来写。
MVVM组成部分
(1)View
View是视图层, 也就是用户界面。前端主要由HTH L和csS来构建, 为了更方便地展现vi eu to del或者Hodel层的数据, 已经产生了各种各样的前后端模板语言, 比如FreeMarker,Thyme leaf等等, 各大MV VM框架如Vue.js.Angular JS, EJS等也都有自己用来构建用户界面的内置模板语言。
(2)Model
Model是指数据模型, 泛指后端进行的各种业务逻辑处理和数据操控, 主要围绕数据库系统展开。这里的难点主要在于需要和前端约定统一的接口规则
(3)ViewModel
ViewModel是由前端开发人员组织生成和维护的视图数据层。在这一层, 前端开发者对从后端获取的Model数据进行转换处理, 做二次封装, 以生成符合View层使用预期的视图数据模型。
需要注意的是View Model所封装出来的数据模型包括视图的状态和行为两部分, 而Model层的数据模型是只包含状态的
比如页面的这一块展示什么,那一块展示什么这些都属于视图状态(展示)
页面加载进来时发生什么,点击这一块发生什么,这一块滚动时发生什么这些都属于视图行为(交互)
视图状态和行为都封装在了View Model里。这样的封装使得View Model可以完整地去描述View层。由于实现了双向绑定, View Model的内容会实时展现在View层, 这是激动人心的, 因为前端开发者再也不必低效又麻烦地通过操纵DOM去更新视图。
MVVM框架已经把最脏最累的一块做好了, 我们开发者只需要处理和维护View Model, 更新数据视图就会自动得到相应更新,真正实现事件驱动编程。
View层展现的不是Model层的数据, 而是ViewModel的数据, 由ViewModel负责与Model层交互, 这就完全解耦了View层和Model层, 这个解耦是至关重要的, 它是前后端分离方案实施的重要一环
Vue
Vue(读音/vju/, 类似于view) 是一套用于构建用户界面的渐进式框架, 发布于2014年2月。与其它大型框架不同的是, Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层, 不仅易于上手, 还便于与第三方库(如:vue-router,vue-resource,vue x) 或既有项目整合
(1)MVVM模式的实现者
Model:模型层, 在这里表示JavaScript对象
View:视图层, 在这里表示DOM(HTML操作的元素)
ViewModel:连接视图和数据的中间件, Vue.js就是MVVM中的View Model层的实现者
在MVVM架构中, 是不允许数据和视图直接通信的, 只能通过ViewModel来通信, 而View Model就是定义了一个Observer观察者
ViewModel能够观察到数据的变化, 并对视图对应的内容进行更新
ViewModel能够监听到视图的变化, 并能够通知数据发生改变
至此, 我们可以大致了解, Vue.js就是一个MVVM的实现者, 他的核心就是实现了DOM监听与数据绑定
(2)为什么使用Vue.js
轻量级, 体积小是一个重要指标。Vue.js压缩后有只有20多kb(Angular压缩后56kb+,React压缩后44kb+)
移动优先。更适合移动端, 比如移动端的Touch事件
易上手,学习曲线平稳,文档齐全
吸取了Angular(模块化) 和React(虚拟DOM) 的长处, 并拥有自己独特的功能,如:计算属性
开源,社区活跃度高
与JavaScript的区别
原生js的做法(编程范式:命令式编程)
1.创建div元素,设置id属性
2.定义一个变量message
3.将message放在div中显示
4.修改数据
5.将修改的数据再次替换到div中
vue做法(声明式编程)将数据交给vue管理
<div id="app">
{{ message }}
</div>
let app = new Vue({//let(变量)/const(常量)
el: '#app',//用于挂载要管理的数据
data: {//定义数据
message: 'Hello Vue!'
}
})
创建一个Vue程序
创建一个.html文件
通过以下方式引入Vue
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
或者
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
声明式渲染
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:
<div id="app">
{{ message }}
</div>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
我们已经成功创建了一个 Vue 应用!看起来这跟渲染一个字符串模板非常类似,但是 Vue 在背后做了大量工作。现在数据和 DOM 已经被建立了关联,所有东西都是响应式的。
打开你的浏览器的 JavaScript 控制台 (就在这个页面打开),并修改 app.message 的值,你将看到上例相应地更新。
注意:我们不再和 HTML 直接交互了。一个 Vue 应用会将其挂载到一个 DOM 元素上 (对于这个例子是 #app) 然后对其进行完全控制。那个 HTML 是我们的入口,但其余都会发生在新创建的 Vue 实例内部。
Vue的生命周期
Vue.js基础
Vue.js介绍
了解Vue.js的起源、特点和优势,以及其在现代前端开发中的应用。参考以上Vue概述。
Vue CLI
学习使用Vue CLI脚手架工具初始化和管理Vue项目,快速搭建开发环境。参考以上Vue概述。
Vue项目结构
项目结构Demo截图
项目结构各项简介
├── build --------------------------------- 项目构建(webpack)相关配置文件,配置参数什么的,一般不用动
│ ├── build.js --------------------------webpack打包配置文件
│ ├── check-versions.js ------------------------------ 检查npm,nodejs版本
│ ├── dev-client.js ---------------------------------- 设置环境
│ ├── dev-server.js ---------------------------------- 创建express服务器,配置中间件,启动可热重载的服务器,用于开发项目
│ ├── utils.js --------------------------------------- 配置资源路径,配置css加载器
│ ├── vue-loader.conf.js ----------------------------- 配置css加载器等
│ ├── webpack.base.conf.js --------------------------- webpack基本配置
│ ├── webpack.dev.conf.js ---------------------------- 用于开发的webpack设置
│ ├── webpack.prod.conf.js --------------------------- 用于打包的webpack设置
├── config ---------------------------------- 配置目录,包括端口号等。我们初学可以使用默认的。
│ ├── dev.env.js -------------------------- 开发环境变量
│ ├── index.js ---------------------------- 项目配置文件
│ ├── prod.env.js ------------------------- 生产环境变量
│ ├── test.env.js ------------------------- 测试环境变量
├── node_modules ---------------------------- npm 加载的项目依赖模块
├── src ------------------------------------- 我们要开发的目录,基本上要做的事情都在这个目录里。
│ ├── assets ------------------------------ 静态文件,放置一些图片,如logo等
│ ├── components -------------------------- 组件目录,存放组件文件,可以不用。
│ ├── main.js ----------------------------- 主js
│ ├── App.vue ----------------------------- 项目入口组件,我们也可以直接将组件写这里,而不使用 components 目录。
│ ├── router ------------------------------ 路由
├── static ---------------------------- 静态资源目录,如图片、字体等。
├── index.html ------------------------------ 首页入口文件,你可以添加一些 meta 信息或统计代码啥的。
├── package.json ---------------------------- node配置文件,记载着一些命令和依赖还有简要的项目描述信息
├── .README.md------------------------------- 项目的说明文档,markdown 格式。想怎么写怎么写,不会写就参照github上star多的项目,看人家怎么写的
├── .xxxx文件:这些是一些配置文件,包括语法配置,git配置等
│ ├── .babelrc--------------------------------- babel配置文件
│ ├── .editorconfig---------------------------- 编辑器配置
│ ├── .eslintignore------------------------------- 配置需要或略的路径,一般build、config、dist、test等目录都会配置忽略
│ ├── .eslintrc.js ------------------------------- 配置代码格式风格检查规则
│ ├── .gitignore------------------------------- 配置git可忽略的文件
│ ├── .postcssrc.js ------------------------------- css转换工具
Vue访问渲染原理
在webpack的配置文件里,设置了main.js是入口文件,我们的项目默认访问index.html,
这个文件里面<div id="app"></div>和App.vue组件里面的容器完美的重合了,也就是把组件挂载到了index页面,然后我们只需要去建设其他组件就好了,
在App组件中我们也可以引入,注册,应用其他组件,可以通过路由将其他组件渲染在App组件,这样我们就只需要去关注每个组件的功能完善。
就是说vue的默认页面是index.html,index中的<div id="app"></div>挂载了App.vue这个大组件,然后所有的其他子组件(hello.vue等)都归属在App.vue这个主组件下。
Vue主要文件解析
①src——[项目核心文件]
在vue-cli的项目中,其中src文件夹是必须要掌握的,因为基本上要做的事情都在这个目录里。
②index.html——[主页]
index.html如其他html一样,但一般只定义一个空的根节点,在main.js里面定义的实例将挂载在根节点下,内容都通过vue组件来填充
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vuedemo</title>
</head>
<body>
<!-- 定义的vue实例将挂载在#app节点下 -->
<div id="app"></div>
</body>
</html>
一个vue页面通常由三部分组成:模板(template)、js(script)、样式(style)
<!-- 模板 -->
<template>
<div id="app">
<img src="./assets/logo.png">
<router-view></router-view>
</div>
</template>
<!-- script -->
<script>
export default {
name: 'app'
}
</script>
<!-- 样式 -->
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
【template】
其中模板只能包含一个父节点,也就是说顶层的div只能有一个(例如上面代码,父节点为#app的div,其没有兄弟节点)
<router-view></router-view>是子路由视图,后面的路由页面都显示在此处
打一个比喻吧,<router-view>类似于一个插槽,跳转某个路由时,该路由下的页面就插在这个插槽中渲染显示
【script】
vue通常用es6来写,用export default导出,其下面可以包含数据data,生命周期(mounted等),方法(methods)等,具体语法请看vue.js文档。
【style】
样式通过style标签包裹,默认是影响全局的,如需定义作用域只在该组件下起作用,需在标签上加scoped.
如要引入外部css文件,首先需给项目安装css-loader依赖包,打开cmd,进入项目目录,输入npm install css-loader,回车。
安装完成后,就可以在style标签下import所需的css文件,例如:
<style>
import './assets/css/public.css'
</style>
③main.js——[入口文件]
main.js主要是引入vue框架,根组件及路由设置,并且定义vue实例,下面的 components:{App}
就是引入的根组件App.vue
后期还可以引入插件,当然首先得安装插件。
/*引入vue框架*/
import Vue from 'vue'
/*引入根组件*/
import App from './App'
/*引入路由设置*/
import router from './router'
/*关闭生产模式下给出的提示*/
Vue.config.productionTip = false
/*定义实例*/
new Vue({
el: '#app',
router,
template: '<App/>',
components: { App }
})
④router——[路由配置]
vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用。vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。
router文件夹下,有一个index.js,即为路由配置文件。
/*引入vue框架*/
import Vue from 'vue'
/*引入路由依赖*/
import Router from 'vue-router'
/*引入页面组件,命名为Hello*/
import Hello from '@/components/Hello'
/*使用路由依赖*/
Vue.use(Router)
/*定义路由*/
export default new Router({
routes: [
{
path: '/',
name: 'Hello',
component: Hello
}
]
})
这里定义了路径为’/'的路由,该路由对应的页面是Hello组件,所以当我们在浏览器url访问http://localhost:8080/#/时就渲染的Hello组件
类似的,我们可以设置多个路由,‘/index’,'/list’之类的,当然首先得引入该组件,再为该组件设置路由。
⑤其他配置文件
主要包括webpack的配置,项目配置,项目依赖等等。
详情可参考以下文章:
⑥vue 模板文件
这是我自己做的一个vue模板文件,符合Eslint规则
<!-- -->
<template>
<div/>
</template>
<script>
// 这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
// 例如:import 《组件名称》 from '《组件路径》'
export default {
// import引入的组件需要注入到对象中才能使用
components: {},
data() {
// 这里存放数据
return {
}
},
// 监听属性 类似于data概念
computed: {},
// 监控data中的数据变化
watch: {},
// 生命周期 - 创建完成(可以访问当前this实例)
created() {
},
// 生命周期 - 挂载完成(可以访问DOM元素)
mounted() {
},
beforeCreate() {}, // 生命周期 - 创建之前
created() {}, // 生命周期 - 创建之后
beforeMount() {}, // 生命周期 - 挂载之前
mounted() {}, //生命周期 - 挂载之后
beforeUpdate() {}, // 生命周期 - 更新之前
updated() {}, // 生命周期 - 更新之后
beforeDestroy() {}, // 生命周期 - 销毁之前
destroyed() {}, // 生命周期 - 销毁完成
activated() {}, // 如果页面有keep-alive缓存功能,这个函数会触发
// 方法集合
methods: {
}
}
</script>
<style lang='less' scoped>
//@import url(); 引入公共css类
</style>
vue-cli给创建vue项目提供了很大的便利。但是同时大量的第三方库的使用,会让打包后的js变的很大,所以还是要熟悉配置,熟悉第三方插件的使用,才可以开发更高效的开发web应用。vue-cli给创建vue项目提供了很大的便利。但是同时大量的第三方库的使用,会让打包后的js变的很大,所以还是要熟悉配置,熟悉第三方插件的使用,才可以开发更高效的开发web应用。
Vue其他文件解析
① .browserslistrc
该文件的作用是根据提供的目标浏览器的环境,来智能添加 css 前缀,js 的 polyfill 垫片,来兼容旧版本浏览器。避免不必要的兼容代码,以提高代码的编译质量。
默认创建的项目中,.browserslistrc文件内容如下:
> 1%
last 2 versions
not dead
分别代表1.全球超过 1%人使用的浏览器;2.所有浏览器兼容到最后两个版本,再以前的就不兼容;3.不兼容已经在市面下架“死去”的浏览器。以下是更多相关的配置和介绍:
例子 | 说明 |
> 1% | 全球超过 1%人使用的浏览器 |
> 5% in US | 指定国家使用率覆盖 |
last 2 versions | 所有浏览器兼容到最后两个版本根据 CanIUse.com 追踪的版本 |
Firefox ESR | 火狐最新版本 |
Firefox > 20 | 指定浏览器的版本范围 |
not ie <=8 | 方向排除部分版本 |
Firefox 12.1 | 指定浏览器的兼容到指定版本 |
unreleased versions | 所有浏览器的 beta 测试版本 |
unreleased Chrome versions | 指定浏览器的测试版本 |
since 2013 | 2013 年之后发布的所有版本 |
② .eslintrc.js
这个文件主要用于配置项目的 eslint 校验,对于一个团队来说,每个人有每个人写代码的风格和习惯,有人喜欢结尾加分号,有人不加,有人习惯使用双引号,有人习惯单引号,当然这些不足以影响项目的运行,但是 eslint 还可以配置更加重要的规范,来统一代码风格和预防一些代码隐患。所以这个文件相对团队开发来说是比较重要的。
.eslintrc.js文件默认导出一个对象,以下是创建 vue 项目后 eslintrc 文件的默认内容,结尾处会提供一个更详细的 eslint 配置文件。
module.exports = {
// 默认情况下,ESLint 会在所有父级目录里寻找配置文件,一直到根目录。ESLint 一旦发现配置文件中有 "root": true,它就会停止在父级目录中寻找。
root: true,
// env表示一个环境,预定义了一组全局变量
env: {
node: true // 定义了Node.js 全局变量和 Node.js 作用域。
},
// extends 一个配置文件可以被基础配置中的已启用的规则继承,如下设置继承了数组中的三项规则。其中值为 "eslint:recommended" 的 extends 属性会启用一系列eslint核心规则。
extends: ['plugin:vue/essential', 'eslint:recommended', '@vue/prettier'],
// ESLint 允许你指定你想要支持的 JavaScript 语言选项。默认情况下,ESLint 支持 ECMAScript 5 语法。你可以覆盖该设置,以启用对 ECMAScript 其它版本和 JSX 的支持。
parserOptions: {
parser: 'babel-eslint'
},
// rules 表示eslint校验规则
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
}
}
rules 配置规则格式
规则格式是<规则名称>: <告警级别>,告警级别分为三种:
“0"表示忽略问题,等同于"off”;
“1"表示给出警告,等同于"warn”;
“2"表示直接报错,等同于"error”。
更多的 ESLint 配置可以前往 ESLint 中文网 查看
③ gitignore
该文件正如其名字的意思,告知 git 那些文件或文件夹不需要添加到版本管理中。内容如下:
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
④ README.md
这个文件就是项目的介绍文件,使用 markdown 语法。
不清楚markdown语法的可以访问markdown基本语法
⑤ babel.config.js
Babel 是一个 JavaScript 编译器,可以对 JavaScript 文件进行转码,类似的有 ES6 转为 ES5 兼容不同的浏览器。
babel.config.js是 babel 的配置文件,presets字段设定转码规则,此处 @vue/cli-plugin-babel/preset就是规则。
module.exports = {
presets: ['@vue/cli-plugin-babel/preset']
}
了解更多的Babel相关配置可以访问Babel 配置文件
⑥ package.json
package.json文件提供了很多项目相关的信息,主要有这个项目所需要的各种模块;以及项目的配置信息(比如名称、版本、许可证等元数据);还可以配置一些简化script执行脚本。项目中json文件是不能添加注释的,需要删除相关注释噢
{
"name": "vue-project", // 项目的名称
"version": "0.1.0", // 项目的版本号 大版本号.小版本号.修订版本号[.日期版本号]
"private": true, // 是否对外开放,private为true表示不对外开放
"scripts": {
// script配置脚本对象,表示npm run XXX
"serve": "vue-cli-service serve", // 配置serve脚本,表示npm run serve 等同于 vue-cli-service serve 命令
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
// 依赖的相关信息,这里主要是生产和开发依赖,一般用npm install XXX --save 安装的依赖就会添加到这里
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
},
"devDependencies": {
// 开发依赖的相关信息,这里的主要是开发过程的依赖,生产环境中不会存在,一般用 npm install XXX --save-dev 安装的依赖会添加到这里
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/eslint-config-prettier": "^6.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^6.2.2",
"lint-staged": "^9.5.0",
"node-sass": "^4.12.0",
"prettier": "^2.2.1",
"sass-loader": "^8.0.2",
"vue-template-compiler": "^2.6.11"
}
}
除了上述vue-cli创建项目后默认生成的文件外,我们在开发过程中还需要很多配置文件,且都是在根目录中自己创建的。下面介绍几个相关文件
⑦vue.config.js
这个文件表示 vue 的配置文件,像一些简单的前端服务运行的端口号,是否自动打开,代理地址等。下面是一些简单的配置
const path = require('path') // 导入Node的path模块
// 解析函数,在配置引入别名时用到
function resolve(dir) {
return path.join(__dirname, dir)
}
// vue.config.js的主体配置
module.exports = {
publicPath: '/', // 部署应用包时的基本 URL。用法和 webpack 本身的 output.publicPath 一致。
outputDir: 'dist', // 当运行 vue-cli-service build 时生成的生产环境构建文件的目录。
assetsDir: 'assets', // 放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录。
css: {
// 对css的一些配置
extract: true, // 是否将组件中的 CSS 提取至一个独立的 CSS 文件中 (而不是动态注入到 JavaScript 中的 inline 代码)。
sourceMap: false // 是否为 CSS 开启 source map。设置为 true 之后可能会影响构建的性能。
},
lintOnSave: process.env.NODE_ENV === 'development', // 是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码。这个值会在 @vue/cli-plugin-eslint 被安装之后生效。
devServer: {
// 服务相关的设置
host: '127.0.0.1', // 指定一个主机名
port: 8000, // 指定一个端口号
open: true, // 运行成功后是否自动打开页面
proxy: {
// 代理相关。如果你的前端应用和后端 API 服务器没有运行在同一个主机上,你需要在开发环境下将 API 请求代理到 API 服务器
'/api': {
// 对请求接口中出现的api进行代理
target: process.env.VUE_APP_PROXY_URL, // 代理的目标地址,这个取值在后面的文件会讲到
changeOrigin: true, // 是否改变域名,
ws: false, // 是否开启webSocket
pathRewrite: {
// 路径重写,如果默认不重写路径,那么`/api/users`会被代理到`target路径/api/users`
'^/api': '' // 对api进行路径重写,重写后,那么`/api/users`会被代理到`target路径/users`
}
}
}
},
// webpack相关的配置,可以设置plugins和别名解析等
configureWebpack: {
// 解析设置
resolve: {
// 别名配置,用来创建 import 或 require 的别名,来确保模块引入变得更简单。
alias: {
// 用'@'表示src的路径, @/views/Home.vue 等同于 src/views/Home.vue.
'@': resolve('src'),
// 同理,用@components 表示 src/components目录
'@components': resolve('src/components'),
'@assets': resolve('src/assets')
}
},
// 配置webpack的plugins
plugins: []
},
// 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
productionSourceMap: false
}
更多vue的配置可以访问 vue 配置参考
⑧.env.development、.env.production 配置文件
这里可以自己创建以上配置文件,用于配置不同环境下的环境变量,其中
.env.development表示开发环境的环境变量
.env.production表示生产环境的环境变量
.env.mock表示 mock 运行状态下的环境变量
这些环境变量可以在全局使用,使用方法就是process.env.XXXX。其中 xxxx 表示变量名
由于上面在vue.config.js配置文件中proxy代理配置的属性target的值使用了process.env.VUE_APP_PROXY_URL变量。所以我在env.development文件里定义如下变量:
VUE_APP_PROXY_ROOT = 'http://192.168.2.25:6060/'
于是在开发过程中,向 /api/user 地址发送请求就等同于向 http://192.168.2.25:6060/user 地址发送请求
⑨.prettierrc文件
Prettier是一个代码格式化工具,可以在开发过程中,使代码格式化成你想要的风格和规范。
开发前端的过程中,我们要求开发人员都在VSCode中装入Prettier插件,方便格式化。与 ESLint 一样,为了统一代码风格和规范,所以 Prettier 也是在团队开发中重要的一员。
.prettierrc文件就是配置使用 Prettier 格式化代码的方式(注意该文件中的注释需要删除后才会生效)
{
"eslintIntegration": true // eslint集成 "stylelintIntegration": true, // 样式嵌入 "singleQuote": true, // 是否使用单引号 "semi": false, // 结尾是否保留分号,设置为false表示结尾不会有分号 "trailingComma": "none", // 对象、数组等,最后一个是否保留逗号,设置为none表示不保留逗号, es5表示保留es5的结尾逗号 "arrowParens": "avoid", // 箭头函数中只有一个参数是否保留括号,aviod表示不保留括号,always表示保留括号 "bracketSpacing": true, // 对象中的空格 默认true "useTabs": false, // 使用tab缩进,默认false "tabWidth": 2 // tab缩进大小,2个空格
}
更多prettier的配置内容请访问Prettier 配置
Vue实例
学习创建Vue实例、理解Vue实例的生命周期钩子函数和数据绑定。
【Vue】created、mounted、updated详解
模板语法
掌握Vue的模板语法,了解如何在模板中使用指令、表达式和过滤器等。
Vue基础语法
Vue指令
指令 (Directives) 是带有 v- 前缀的特殊 attribute。指令 attribute 的值预期是单个 JavaScript 表达式 (v-for 是例外情况)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。以下是一些最常用的 Vue 指令:
1. v-bind
动态地绑定一个或多个特性,或一个组件 prop 到表达式。
<!-- 绑定一个属性 -->
<img v-bind:src="imageSrc">
<!-- 缩写 -->
<img :src="imageSrc">
2. v-model
在表单控件或者组件上创建双向数据绑定。
<input v-model="message">
<!-- 在组件上 -->
<custom-input v-model="message"></custom-input>
3. v-for
基于源数据多次渲染元素或模板块。
<ul>
<li v-for="item in items" :key="item.id">
{{ item.text }}
</li>
</ul>
4. v-on
监听 DOM 事件,并在触发时执行一些 JavaScript 代码。
<button v-on:click="doSomething">Click me</button>
<!-- 缩写 -->
<button @click="doSomething">Click me</button>
5. v-if
条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。
<p v-if="seen">Now you see me</p>
6. v-else
表示 `v-if` 的“else 块”,必须紧跟在带 `v-if` 或者 `v-else-if` 的元素之后。
<p v-if="user.loggedIn">Welcome back!</p>
<p v-else>Please log in.</p>
7. v-else-if
表示 `v-if` 的“else if 块”,必须紧跟在带 `v-if` 或者 `v-else-if` 的元素之后。
<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else-if="type === 'C'">C</div>
<div v-else>Not A/B/C</div>
8. v-show
根据表达式之真假值,切换元素的 `display` CSS 属性。与 `v-if` 不同的是,带有 `v-show` 的元素始终会被渲染并保留在 DOM 中,`v-show` 只是简单地切换元素的 CSS 属性 `display`。
<p v-show="isVisible">You can see me</p>
9. v-pre
跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。
<p v-pre>{{ this will not be compiled }}</p>
10. v-cloak
这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 `[v-cloak] { display: none }` 一起用时,这个指令可以隐藏未编译的 Mustache 语法直到实例准备完毕。
<div v-cloak>{{ message }}</div>
11. v-once
渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。
<span v-once>This will never change: {{ message }}</span>
这些指令可以极大地提高你的开发效率,让你能够以声明式的方式处理 DOM 和组件实例的各种动态行为。在 Vue 3 中,这些指令仍然是核心功能的一部分,并且还引入了一些新的指令,比如 `v-model` 在自定义组件上的使用变得更加灵活。
计算属性
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如:
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 message 的翻转字符串。当你想要在模板中的多处包含此翻转字符串时,就会更加难以处理。
所以,对于任何复杂逻辑,你都应当使用计算属性。
监听属性
Vue.js 监听属性 watch,我们可以通过 watch 来响应数据的变化。
以下实例进行千米与米之间的换算:
<div id = "computed_props">
千米 : <input type = "text" v-model = "kilometers">
米 : <input type = "text" v-model = "meters">
</div>
<p id="info"></p>
<script type = "text/javascript">
var vm = new Vue({
el: '#computed_props',
data: {
kilometers : 0,
meters:0
},
methods: {
},
computed :{
},
watch : {
kilometers:function(val) {
this.kilometers = val;
this.meters = this.kilometers * 1000
},
meters : function (val) {
this.kilometers = val/ 1000;
this.meters = val;
}
}
});
// $watch 是一个实例方法
vm.$watch('kilometers', function (newValue, oldValue) {
// 这个回调将在 vm.kilometers 改变后调用
document.getElementById ("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue;
})
</script>
上述代码中我们创建了两个输入框,data 属性中, kilometers 和 meters 初始值都为 0。watch 对象创建了 data 对象的两个监控方法: kilometers 和 meters。
当我们再输入框输入数据时,watch 会实时监听数据变化并改变自身的值。
条件判断
v-if
条件判断使用 v-if 指令:
<!-- 在元素 和 template 中使用 v-if 指令: -->
<div id="app">
<p v-if="seen">现在你看到我了</p>
<template v-if="ok">
<h1>Algorithm</h1>
<p>学的不仅是技术,更是梦想!</p>
<p>哈哈哈!!!</p>
</template>
</div>
<script>
new Vue({
el: '#app',
data: {
seen: true,
ok: true
}
})
</script>
这里, v-if 指令将根据表达式 seen 的值(true 或 false )来决定是否插入 p 元素。
v-else
可以用 v-else 指令给 v-if 添加一个 “else” 块:
<!-- 随机生成一个数字,判断是否大于0.5,然后输出对应信息: -->
<div id="app">
<div v-if="Math.random() > 0.5">
Sorry
</div>
<div v-else>
Not sorry
</div>
</div>
<script>
new Vue({
el: '#app'
})
</script>
v-else-if
v-else-if用作 v-if 的 else-if 块。可以链式的多次使用:
<!-- 判断 type 变量的值: -->
<div id="app">
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
type: 'C'
}
})
</script>
v-else 、v-else-if 必须跟在 v-if 或者 v-else-if之后。
v-show
可以使用 v-show 指令来根据条件展示元素:
<h1 v-show="ok">Hello!</h1>
循环遍历
循环使用 v-for 指令。
v-for 指令需要以 site in sites 形式的特殊语法, sites 是源数据数组并且 site 是数组元素迭代的别名。
v-for 可以绑定数据到数组来渲染一个列表:
<div id="app">
<ol>
<li v-for="site in sites">
{{ site.name }}
</li>
</ol>
</div>
<script>
new Vue({
el: '#app',
data: {
sites: [
{ name: 'csdn' },
{ name: 'Google' },
{ name: 'Taobao' }
]
}
})
</script>
模板中使用 v-for:
<ul>
<template v-for="site in sites">
<li>{{ site.name }}</li>
<li>--------------</li>
</template>
</ul>
v-for 迭代对象
v-for 可以通过一个对象的属性来迭代数据:
<div id="app">
<ul>
<li v-for="value in object">
{{ value }}
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
object: {
name: 'Algorithm',
url: 'http://www.baidu.com',
slogan: '学的不仅是技术,更是梦想!'
}
}
})
</script>
你也可以提供第二个的参数为键名:
<div id="app">
<ul>
<li v-for="(value, key) in object">
{{ key }} : {{ value }}
</li>
</ul>
</div>
第三个参数为索引:
<div id="app">
<ul>
<li v-for="(value, key, index) in object">
{{ index }}. {{ key }} : {{ value }}
</li>
</ul>
</div>
v-for 迭代整数
<div id="app">
<ul>
<li v-for="n in 10">
{{ n }}
</li>
</ul>
</div>
表单
v-model 指令在表单控件元素上创建双向数据绑定。
输入框
<div id="app">
<p>input 元素:</p>
<input v-model="message" placeholder="编辑我……">
<p>消息是: {{ message }}</p>
<p>textarea 元素:</p>
<p style="white-space: pre">{{ message2 }}</p>
<textarea v-model="message2" placeholder="多行文本输入……"></textarea>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'CSDN',
message2: 'https://blog.csdn.net/'
}
})
</script>
复选框
<div id="app">
<p>单个复选框:</p>
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
<p>多个复选框:</p>
<input type="checkbox" id="CSDN" value="Runoob" v-model="checkedNames">
<label for="Algorithm">Algorithm</label>
<input type="checkbox" id="google" value="Google" v-model="checkedNames">
<label for="google">Google</label>
<input type="checkbox" id="taobao" value="Taobao" v-model="checkedNames">
<label for="taobao">taobao</label>
<br>
<span>选择的值为: {{ checkedNames }}</span>
</div>
<script>
new Vue({
el: '#app',
data: {
checked : false,
checkedNames: []
}
})
</script>
单选按钮
<div id="app">
<input type="radio" id="CSDN" value="CSDN" v-model="picked">
<label for="Algorithm">Algorithm</label>
<br>
<input type="radio" id="google" value="Google" v-model="picked">
<label for="google">Google</label>
<br>
<span>选中值为: {{ picked }}</span>
</div>
<script>
new Vue({
el: '#app',
data: {
picked : 'CSDN'
}
})
</script>
select 列表
<div id="app">
<select v-model="selected" name="fruit">
<option value="">选择一个网站</option>
<option value="https://blog.csdn.net/">CSDN</option>
<option value="www.google.com">Google</option>
</select>
<div id="output">
选择的网站是: {{selected}}
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
selected: ''
}
})
</script>
Vue组件化开发
组件基础
学习组件的概念和组件化开发的优势,了解如何创建和使用组件,高频使用的功能可以进行组件封装,进行复用,提高开发效率,例如文件上传,图片上传与显示,甚至列表页或者详情页等等,下面对列表页的部分代码做了介绍
【Vue】中el-table数据项扩展各种类型总结(持续更新)
组件通信
学习父子组件之间的通信方式,包括Props和事件的使用,对于组件的封装是十分必要的。
插槽
了解插槽的概念和用法,实现组件的内容分发和复用。
当涉及到Vue.js中的插槽(slot)时,它是一种用于实现组件内容分发和复用的机制。插槽允许你在组件中定义一些可变的内容,并在使用组件时填充这些内容。
以下是一个使用插槽的简单示例:
<!-- 父组件 -->
<template>
<div>
<h1>父组件</h1>
<child-component>
<p>这是插槽的内容</p>
</child-component>
</div>
</template>
<!-- 子组件 -->
<template>
<div>
<h2>子组件</h2>
<slot></slot>
</div>
</template>
在上面的例子中,父组件中包含了一个子组件`<child-component>`,并在子组件的标签内定义了一个`<p>`标签作为插槽的内容。子组件中使用了`<slot></slot>`标签来表示插槽的位置。
当父组件渲染时,插槽中的内容会被插入到子组件的插槽位置,最终呈现在页面上。这样,你就可以在父组件中动态地定义子组件的内容,实现了组件的内容分发和复用。
除了默认插槽,Vue还提供了具名插槽和作用域插槽的概念,用于更灵活地处理组件内容的分发和复用。具名插槽允许你在一个组件中定义多个插槽,而作用域插槽允许你在插槽中访问父组件的数据和方法。
以下是一个使用具名插槽和作用域插槽的示例:
<!-- 父组件 -->
<template>
<div>
<h1>父组件</h1>
<child-component>
<template v-slot:header>
<h2>这是头部插槽的内容</h2>
</template>
<template v-slot:footer="slotProps">
<p>这是尾部插槽的内容</p>
<p>父组件的数据:{{ slotProps.data }}</p>
</template>
</child-component>
</div>
</template>
<!-- 子组件 -->
<template>
<div>
<h2>子组件</h2>
<slot name="header"></slot>
<slot name="footer" :data="message"></slot>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello, Vue!'
};
}
};
</script>
在上面的例子中,父组件中使用了具名插槽和作用域插槽。通过`v-slot`指令,我们可以为每个插槽指定一个名称,并在子组件中使用相同的名称来匹配插槽。
在作用域插槽中,我们可以使用`slotProps`来访问父组件的数据和方法。在示例中,父组件的数据`message`被传递到了子组件的尾部插槽中,并在插槽内使用`slotProps.data`来访问。
这只是插槽的一个简单示例,你可以根据需要在组件中使用不同类型的插槽来实现更复杂的组件内容分发和复用。
动态组件
学习如何使用动态组件实现根据条件渲染不同的组件。
使用动态组件可以根据条件渲染不同的组件,这在某些情况下非常有用。以下是一个使用动态组件的示例:
<template>
<div>
<button @click="toggleComponent">切换组件</button>
<component :is="currentComponent"></component>
</div>
</template>
<script>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';
export default {
data() {
return {
currentComponent: 'ComponentA'
};
},
methods: {
toggleComponent() {
if (this.currentComponent === 'ComponentA') {
this.currentComponent = 'ComponentB';
} else {
this.currentComponent = 'ComponentA';
}
}
},
components: {
ComponentA,
ComponentB
}
};
</script>
在上面的示例中,我们有两个组件:`ComponentA`和`ComponentB`。在父组件中,我们使用了一个按钮来切换当前组件的显示。
通过`<component>`标签,我们可以使用`:is`属性来动态绑定当前组件的名称。初始时,我们将`currentComponent`设置为`ComponentA`,因此`ComponentA`将被渲染为当前组件。
当点击按钮时,`toggleComponent`方法会根据当前组件的名称切换到另一个组件。如果当前组件是`ComponentA`,则切换到`ComponentB`;如果当前组件是`ComponentB`,则切换到`ComponentA`。
这样,通过动态绑定组件的名称,我们可以根据条件渲染不同的组件,实现动态组件的效果。
你可以根据实际需求和组件的复杂度,使用动态组件来实现更复杂的功能和交互。
Vue路由和状态管理
Vue Router
学习使用Vue Router进行单页面应用的路由管理,包括路由配置、导航守卫和动态路由等。
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。以下是 Vue Router 的一些基础使用方法,包括路由配置、导航守卫和动态路由的示例。
安装 Vue Router
如果你正在使用 npm 或 yarn,你可以通过以下命令来安装 Vue Router:
```bash
npm install vue-router
# 或者
yarn add vue-router
```
路由配置
要使用 Vue Router,首先需要定义路由配置。每个路由映射一个组件。
// 引入Vue和VueRouter
import Vue from 'vue';
import VueRouter from 'vue-router';
// 引入组件
import Home from './components/Home.vue';
import About from './components/About.vue';
import User from './components/User.vue';
// 告诉Vue使用VueRouter
Vue.use(VueRouter);
// 创建路由实例并配置路由映射
const router = new VueRouter({
mode: 'history', // 使用HTML5 History模式
routes: [
{ path: '/', component: Home },
{ path: '/about', component: About },
{ path: '/user/:id', component: User } // 动态路由
]
});
// 创建和挂载根实例
const app = new Vue({
router
}).$mount('#app');
导航守卫
导航守卫允许你在路由发生真正的改变之前进行一些操作,比如权限验证、日志记录等。
以下是全局前置守卫的示例:
// 你可以使用 router.beforeEach 注册一个全局前置守卫
router.beforeEach((to, from, next) => {
// 假设我们有一个登录状态的标识
const isAuthenticated = false; // 这里应该是一个真实的检查
if (to.name !== 'Login' && !isAuthenticated) {
next({ name: 'Login' }); // 如果用户未认证,则重定向到登录页面
} else {
next(); // 确保一定要调用 next()
}
});
动态路由
动态路由允许你定义带变量的路径,例如用户的 ID。当一个路径匹配到一个动态段时,其值会被设置到 `$route.params` 中。
// 给路由定义动态段
const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]
});
// 组件内部,你可以通过 this.$route.params.id 访问到动态段的值
const User = {
template: '<div>User {{ $route.params.id }}</div>'
};
Vue组件中使用路由
在 Vue 组件中,你可以使用 `this.$router` 访问路由实例,使用 `this.$route` 访问当前路由。
<template>
<div>
<h1>User {{ $route.params.id }}</h1>
<button @click="goBack">Go Back</button>
</div>
</template>
<script>
export default {
methods: {
goBack() {
this.$router.go(-1); // 使用路由实例的方法回到上一页
}
}
};
</script>
请注意,以上代码示例中的路由配置、组件和模板都是基础的,实际应用中你可能需要结合 Vuex 进行状态管理,以及使用更复杂的路由嵌套、路由元信息等高级功能。
Vuex:
了解如何使用Vuex进行状态管理,包括状态的定义、修改和访问等。
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 的核心概念包括 state、getters、mutations 和 actions。
安装 Vuex
使用 npm 或 yarn 安装 Vuex:
npm install vuex
# 或者
yarn add vuex
创建一个 Vuex Store
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
// 创建一个新的 store 实例
const store = new Vuex.Store({
state: {
// 状态
count: 0
},
mutations: {
// 更改状态的方法
increment(state) {
state.count++;
}
},
actions: {
// 提交 mutation,可以包含异步操作
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment');
}, 1000);
}
},
getters: {
// 类似于计算属性,根据 state 计算新数据
doubleCount: state => {
return state.count * 2;
}
}
});
export default store;
在 Vue 组件中使用 Vuex Store
<template>
<div>
<p>{{ count }}</p>
<p>{{ doubleCount }}</p>
<button @click="increment">Increment</button>
<button @click="incrementAsync">Increment Async</button>
</div>
</template>
<script>
export default {
computed: {
// 使用 mapState 辅助函数来映射 state
...Vuex.mapState(['count']),
// 使用 getters
...Vuex.mapGetters(['doubleCount'])
},
methods: {
// 使用 mapMutations 辅助函数来映射 mutations
...Vuex.mapMutations(['increment']),
// 使用 mapActions 辅助函数来映射 actions
...Vuex.mapActions(['incrementAsync'])
}
};
</script>
模块化的 Vuex Store
对于大型应用,我们可能需要将 Vuex store 分割成模块(module)。
const moduleA = {
state: () => ({
count: 0
}),
mutations: {
increment(state) {
// 这里的 `state` 对象是模块的局部状态
state.count++;
}
},
getters: {
doubleCount(state) {
return state.count * 2;
}
},
actions: {
incrementIfOddOnRootSum({ state, commit, rootState }) {
if ((state.count + rootState.count) % 2 === 1) {
commit('increment');
}
}
}
}
const store = new Vuex.Store({
modules: {
a: moduleA
}
})
在模块内部,你可以通过 `rootState` 和 `rootGetters` 参数来访问根节点的状态和 getter。
请注意,以上代码仅为展示 Vuex 的基本用法。在实际开发中,你可能需要使用更多高级特性,如插件、严格模式等。此外,对于大型应用,建议将 store 分割成模块,并且可能需要结合 webpack 的代码分割功能来进行懒加载。
进阶特性
自定义指令
学习如何创建和使用自定义指令,扩展Vue的功能
在 Vue 中,除了默认提供的指令(如 `v-model` 和 `v-show`)外,我们还可以自定义指令来扩展 Vue 的功能。自定义指令可以用来直接操作 DOM。
创建自定义指令
自定义指令包含一组生命周期的钩子函数,如 `bind`、`inserted`、`update`、`componentUpdated` 和 `unbind`。
以下是一个简单的自定义指令示例,该指令的功能是当元素被绑定时,设置其文本颜色。
// 注册一个全局自定义指令 `v-color`
Vue.directive('color', {
// 当被绑定的元素插入到 DOM 中时...
inserted: function (el, binding) {
// 聚焦元素
el.style.color = binding.value;
}
});
使用自定义指令
在组件或 HTML 模板中,可以像使用普通指令一样使用自定义指令:
<template>
<p v-color="'red'">This text will be red.</p>
</template>
局部指令
除了全局注册指令,你也可以在组件中局部注册指令:
export default {
directives: {
color: {
inserted: function (el, binding) {
el.style.color = binding.value;
}
}
}
}
在这个组件的模板中,你也可以使用 `v-color` 指令:
<template>
<p v-color="'green'">This text will be green.</p>
</template>
动态指令参数
自定义指令也可以接受动态的参数,这样可以使得指令更加灵活:
Vue.directive('color', {
inserted: function (el, binding) {
let color = 'black'; // 默认颜色
if (binding.arg === 'bg') {
// 参数为 'bg' 时,设置背景颜色
color = binding.value || color;
el.style.backgroundColor = color;
} else {
// 否则设置文本颜色
color = binding.value || color;
el.style.color = color;
}
}
});
使用这个指令:
<template>
<p v-color="'blue'">This text will be blue.</p>
<p v-color:bg="'yellow'">This background will be yellow.</p>
</template>
钩子函数参数
钩子函数被调用时,会接收以下参数:
- `el`: 指令所绑定的元素,可以用来直接操作 DOM。
- `binding`: 一个对象,包含以下属性:
- `name`: 指令名,不包括 `v-` 前缀。
- `value`: 指令的绑定值,例如:`v-color="'red'"` 中的 `'red'`。
- `oldValue`: 指令绑定的前一个值,仅在 `update` 和 `componentUpdated` 钩子中可用。
- `expression`: 字符串形式的指令表达式。
- `arg`: 传给指令的参数,可选。
- `modifiers`: 一个包含修饰符的对象。
自定义指令提供了一种强大的方式来直接操作 DOM,并且可以在多个组件之间复用。正确使用自定义指令可以让你的 Vue 应用更加灵活和强大。
混入(Mixins)
了解如何使用混入将公共逻辑和功能注入到多个组件中。
在 Vue 中,混入(Mixins)是一种灵活的方式,用于创建可重用的功能。混入对象可以包含任何组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入组件本身的选项。
全局混入
全局混入会影响到每一个之后创建的 Vue 实例。使用全局混入时要非常谨慎,因为它会影响到每个组件实例,包括第三方组件。
// 定义一个混入对象
Vue.mixin({
created() {
console.log('Global mixin - created hook');
}
});
// 每个 Vue 实例(包括根实例和所有组件)都会在创建时输出日志
局部混入
局部混入只影响使用该混入的组件,这是推荐的方式,因为它的作用范围是可控的。
// 定义一个混入对象
const myMixin = {
data() {
return {
mixinData: 'I come from the mixin!'
};
},
created() {
console.log('Component created from mixin!');
},
methods: {
foo() {
console.log('foo from mixin');
},
conflicting() {
console.log('from mixin');
}
}
};
// 使用混入的组件
const Component = Vue.extend({
mixins: [myMixin],
created() {
console.log('Component created hook');
},
methods: {
bar() {
console.log('bar from component');
},
conflicting() {
console.log('from component');
}
}
});
// 当组件和混入对象含有同名选项时,这些选项将以恰当的方式合并。
// 例如,同名钩子函数将合并为一个数组,因此都将被调用。
// 另外,混入对象的钩子将在组件自身钩子之前调用。
// 同名方法将以组件自身的方法为优先。
使用混入的组件
<template>
<div>
<p>{{ mixinData }}</p>
<button @click="foo">Call foo</button>
<button @click="bar">Call bar</button>
<button @click="conflicting">Call conflicting</button>
</div>
</template>
<script>
export default {
mixins: [myMixin],
methods: {
bar() {
console.log('bar from component');
},
conflicting() {
console.log('from component');
}
}
};
</script>
在这个例子中,当你点击 "Call foo" 按钮时,会调用混入的 `foo` 方法;点击 "Call bar" 时,会调用组件的 `bar` 方法;点击 "Call conflicting" 时,由于方法名冲突,组件的 `conflicting` 方法会覆盖混入的方法,因此会调用组件的 `conflicting` 方法。
混入是一个强大的特性,但也需要小心使用,以避免产生难以理解的代码。当你发现多个组件使用了相同的功能时,混入可以是一个组织代码的好方式。
渲染函数
学习使用渲染函数来动态生成组件的DOM结构。
在 Vue.js 中,渲染函数提供了一种更接近编译器的方式来生成虚拟 DOM。虽然大多数情况下你可能会使用模板来创建你的 Vue 应用的 HTML,但在某些情况下,你可能需要完全控制更新和渲染过程,这时渲染函数就非常有用。
渲染函数通常会使用 `createElement` 方法,这个方法是渲染函数的第一个参数,通常被简写为 `h`。下面是一个使用渲染函数的基本例子:
Vue.component('my-component', {
props: ['message'],
render(h) {
// 创建一个 <div> 并返回
return h('div', this.message);
}
});
在上面的代码中,组件 `my-component` 接收一个 `message` 属性,并使用渲染函数来创建一个包含该消息的 `<div>` 元素。
渲染函数的 `createElement` 方法接受三个参数:
1. 字符串(标签名)、组件选项对象,或者一个异步组件的函数。
2. 一个包含模板相关属性的数据对象,这样你可以在 `createElement` 方法中设置如 `class`、`style`、`attrs`、`props` 等。
3. 子虚拟节点(VNodes),由 `createElement()` 生成,或者使用字符串来获取“文本虚拟节点”。
使用渲染函数创建一个带子元素的组件
Vue.component('my-button', {
render(h) {
// 创建一个带有子元素的 <button>
return h('button', [
'Click me ',
h('strong', 'now')
]);
}
});
在这个例子中,`my-button` 组件将渲染为一个按钮,按钮内有文本 "Click me " 和一个加粗的 "now"。
使用渲染函数接收插槽内容
Vue.component('my-layout', {
render(h) {
// 创建一个布局组件,它的内容是传递给它的插槽内容
return h('div', [
this.$slots.header,
this.$slots.default,
this.$slots.footer
]);
}
});
在这个例子中,`my-layout` 组件将渲染为一个 `<div>`,并将其子元素分配到对应的插槽中。
使用渲染函数接收子组件和属性
Vue.component('my-special-list', {
render(h) {
const children = this.items.map((item) =>
h('my-list-item', {
props: { item: item }
})
);
return h('ul', children);
},
props: {
items: Array
}
});
Vue.component('my-list-item', {
render(h) {
return h('li', this.item.text);
},
props: {
item: Object
}
});
在这个例子中,`my-special-list` 组件接收一个 `items` 数组作为属性,并为每个 `item` 创建一个 `my-list-item` 组件,最后渲染为一个 `<ul>` 列表。
渲染函数给予你完全的编程能力来创建虚拟 DOM。它们特别适用于那些需要动态生成大量元素或复杂组件结构的场景。然而,渲染函数也更难以编写和理解,因此在大多数情况下,建议优先使用模板。
Vue与后端交互
Vue Resource或Axios
学习使用Vue Resource或Axios等工具进行AJAX请求,与后端进行数据交互。
Vue.js 不包括发起 AJAX 请求的内置功能。相反,它需要使用第三方库。Vue Resource 曾经是 Vue 社区推荐的 AJAX 库,但自从 Vue 2.0 之后,官方就不再更新和维护 Vue Resource,并推荐使用 Axios。
Axios 是一个基于 Promise 的 HTTP 客户端,可以在浏览器和 node.js 中使用。它是一个非常流行的库,可以很容易地与 Vue.js 集成。
首先,你需要安装 Axios。如果你使用 npm 或 yarn,你可以通过以下命令安装 Axios:
```sh
npm install axios
```
或者
```sh
yarn add axios
```
安装完成后,你可以在你的 Vue 组件中引入并使用 Axios。下面是一些基本的用例:
在 Vue 组件中使用 Axios 发送 GET 请求
<template>
<div>
<h1>Posts</h1>
<ul>
<li v-for="post in posts" :key="post.id">
{{ post.title }}
</li>
</ul>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
posts: []
};
},
created() {
axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => {
this.posts = response.data;
})
.catch(error => {
console.log(error);
});
}
};
</script>
在这个例子中,当组件被创建时,会发起一个 GET 请求到 `jsonplaceholder.typicode.com` 上的假数据 API,获取文章列表,并将其存储在组件的 `posts` 数据属性中。
在 Vue 组件中使用 Axios 发送 POST 请求
<template>
<div>
<button @click="createPost">Create Post</button>
</div>
</template>
<script>
import axios from 'axios';
export default {
methods: {
createPost() {
const postData = {
title: 'foo',
body: 'bar',
userId: 1
};
axios.post('https://jsonplaceholder.typicode.com/posts', postData)
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
});
}
}
};
</script>
在这个例子中,当用户点击按钮时,会触发 `createPost` 方法,该方法将发送一个 POST 请求到 `jsonplaceholder.typicode.com` 上的假数据 API,创建一个新的文章。
处理异步请求和响应
因为 Axios 返回的是 Promise 对象,你可以使用 `async/await` 语法来处理异步请求和响应,使你的代码更加简洁和易读。
export default {
data() {
return {
posts: []
};
},
async created() {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
this.posts = response.data;
} catch (error) {
console.log(error);
}
}
};
在这个例子中,我们使用了 `async/await` 来处理异步的 GET 请求。
使用 Axios 进行 AJAX 请求是一个简单而强大的方法,它可以帮助你的 Vue 应用程序与后端服务进行通信。记住处理好错误和异常情况,确保你的应用程序在请求失败时能够优雅地处理。
Vue与后端框架集成
了解如何与后端框架(如Node.js、Express、Django等)进行集成开发,实现前后端的协作。
Vue.js 是一个前端框架,主要用于构建用户界面和单页应用程序。而 Node.js、Express、Django 等是用于构建服务器端应用程序的后端技术。将 Vue.js 与这些后端框架集成,可以构建完整的全栈应用程序。
以下是一些基本的集成方法和代码示例:
Vue.js 与 Node.js/Express 集成
通常,你会创建一个 API 服务器,使用 Express 处理 HTTP 请求和响应。Vue.js 应用可以作为一个单独的客户端应用存在,或者可以由 Express 服务器直接提供。
1. Express 作为 API 服务器
你可以创建一个 Express 应用来作为你的 API 服务器,如下所示:
// server.js
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
app.get('/api/posts', (req, res) => {
// 假设这里从数据库获取数据
res.json([
{ id: 1, title: 'Express with Vue' },
{ id: 2, title: 'Fullstack development' }
]);
});
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
然后在 Vue.js 应用中,你可以使用 Axios 来请求这个 API:
// Vue component
<template>
<div>
<ul>
<li v-for="post in posts" :key="post.id">
{{ post.title }}
</li>
</ul>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
posts: []
};
},
created() {
axios.get('/api/posts')
.then(response => {
this.posts = response.data;
})
.catch(error => {
console.error(error);
});
}
};
</script>
2. Express 提供 Vue.js 应用
如果你想要 Express 服务器提供 Vue.js 应用,你需要构建 Vue.js 应用并将构建产物放在 Express 可以访问的地方:
// server.js
const express = require('express');
const app = express();
const port = 3000;
const path = require('path');
// 静态文件服务,假设 'dist' 是 Vue 应用的构建目录
app.use(express.static(path.join(__dirname, 'dist')));
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
Vue.js 与 Django 集成
Django 是一个高级的 Python Web 框架,它鼓励快速开发和干净、实用的设计。集成 Vue.js 和 Django 通常意味着将 Vue.js 作为前端,Django 作为后端 API 服务器。
Django 提供 RESTful API
首先,你需要使用 Django Rest Framework 创建一个 API。
# views.py
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
然后在 Vue.js 应用中,你可以使用 Axios 来请求这个 API:
// Vue component
<template>
<div>
<ul>
<li v-for="post in posts" :key="post.id">
{{ post.title }}
</li>
</ul>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
posts: []
};
},
created() {
axios.get('/api/posts/')
.then(response => {
this.posts = response.data;
})
.catch(error => {
console.error(error);
});
}
};
</script>
Django 提供 Vue.js 静态文件
如果你想要 Django 服务 Vue.js 的静态文件,你需要将 Vue.js 应用构建为静态文件,并将它们放在 Django 的静态文件目录中。
# settings.py
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "frontend/dist/static"),
]
# urls.py
from django.views.generic import TemplateView
urlpatterns = [
# ... 其他 URL 配置 ...
path('', TemplateView.as_view(template_name='index.html')),
]
在这个配置中,`frontend/dist` 是 Vue 应用构建后的目录。
集成 Vue.js 与后端框架通常涉及到设置合适的 CORS 策略,确保前后端之间的请求能够正确处理。此外,你可能还需要配置环境变量、数据库连接以及其他后端服务。这些示例提供了一个基础的起点,但是在实际的项目中,你可能需要根据具体的需求和环境进行适当的调整。
Vue生态系统
Vue DevTools
了解如何使用Vue DevTools进行Vue应用的调试和性能优化。
Vue DevTools 是一个浏览器扩展,用于调试 Vue.js 应用程序。它允许你检查和编辑 Vue 组件的数据和属性,跟踪自定义事件,调试 Vuex 的状态管理等。这个工具对于开发和调试 Vue 应用是非常有用的。
安装 Vue DevTools
1. 对于 Chrome 和 Firefox,你可以在各自的浏览器扩展商店中搜索 "Vue DevTools" 并安装。
2. 对于其他支持 Chrome 扩展的浏览器,比如新版 Microsoft Edge,你也可以从 Chrome Web Store 安装。
使用 Vue DevTools
安装完毕后,打开你的 Vue 应用程序,在浏览器中按 `F12` 打开开发者工具,你会看到一个新的 "Vue" 标签页。如果你的应用是使用 Vue 构建的,这个标签页会被激活,你可以开始使用 DevTools 了。
以下是一些使用 Vue DevTools 的基本步骤和代码示例:
1. 检查组件和它们的状态
你可以在 Vue DevTools 的组件树中查看所有组件的层级结构。点击任何一个组件,你可以查看和编辑它的 `data`、`props`、`computed properties` 和 `methods`。
2. 调试 Vuex
如果你的应用使用 Vuex 进行状态管理,Vue DevTools 会有一个 "Vuex" 标签页。你可以查看整个状态树,触发 actions,以及回滚和时间旅行调试。
3. 性能优化
Vue DevTools 的 "Performance" 标签页允许你记录和查看组件的渲染性能。你可以看到哪些组件渲染花费了多少时间,这对于识别性能瓶颈非常有用。
4. 事件监听
"Events" 标签页可以显示所有由 `$emit` 触发的事件。这对于调试复杂的组件交互非常有用。
5. 路由调试
如果你使用 Vue Router,"Routing" 标签页可以帮助你查看当前路由的状态,以及历史路由变化。
代码示例
Vue DevTools 主要用于调试和检查,而不是直接在代码中使用。不过,你可以在代码中使用特定的 DevTools 钩子来增强调试体验。例如,你可以在组件中添加 `devtools` 钩子:
export default {
data() {
return {
message: 'Hello Vue!'
};
},
devtools: {
hooks: {
'componentUpdated': (e) => {
console.log('组件更新了!', e);
}
}
}
};
这段代码并不是 Vue DevTools 的标准用法,但它展示了你可以如何在组件内部与 DevTools 交互,如果 DevTools API 允许的话。
注意事项
- - 确保你使用的是与你的 Vue 版本兼容的 Vue DevTools 版本。
- - 在生产环境中,Vue DevTools 默认是禁用的。你可以在 Vue 应用初始化时通过设置 `Vue.config.devtools = true` 来启用它,但请注意这可能会暴露应用的内部状态。
- - 使用 Vue DevTools 时,要注意不要在公共环境下暴露敏感信息。
Vue DevTools 是一个强大的工具,它可以极大地提高开发效率和应用性能。通过实时检查和编辑组件状态,你可以快速定位和解决问题。
Vue Test Utils
学习使用Vue Test Utils进行单元测试和组件测试,提高代码质量和可维护性。
Vue Test Utils 是 Vue.js 官方提供的一个库,它允许你以一种简便的方式对 Vue 组件进行单元测试。Vue Test Utils 提供了操作 Vue 组件的 API,可以挂载组件、设置 props、注入依赖、触发事件等。
安装 Vue Test Utils
首先,你需要安装 Vue Test Utils 和一个测试运行器(比如 Jest 或 Mocha)。
使用 npm 安装 Jest 和 Vue Test Utils:
npm install --save-dev @vue/test-utils jest
或者使用 yarn:
yarn add --dev @vue/test-utils jest
配置 Jest
在项目根目录下创建一个 `jest.config.js` 文件来配置 Jest:
module.exports = {
// 告诉 Jest 处理 `*.vue` 文件
moduleFileExtensions: [
'js',
'json',
// 告诉 Jest 处理 `*.vue` 文件
'vue'
],
transform: {
// 用 `vue-jest` 处理 `*.vue` 文件
'.*\\.(vue)$': 'vue-jest',
// 用 `babel-jest` 处理 js
'.*\\.(js)$': 'babel-jest'
}
};
编写测试
假设你有一个简单的 Vue 组件 `MessageComponent.vue`:
<template>
<div>
{{ message }}
</div>
</template>
<script>
export default {
props: ['message']
};
</script>
你可以编写一个测试来验证组件是否正确渲染了传入的 props:
import { shallowMount } from '@vue/test-utils';
import MessageComponent from '@/components/MessageComponent.vue';
describe('MessageComponent', () => {
it('renders props.message when passed', () => {
const message = 'new message';
const wrapper = shallowMount(MessageComponent, {
propsData: { message }
});
expect(wrapper.text()).toMatch(message);
});
});
在这个测试中,`shallowMount` 是用来挂载组件的,但它不会渲染子组件,这通常在单元测试中是理想的行为,因为你通常只关心测试单个组件的行为。
运行测试
在你的 `package.json` 中添加一个脚本来运行 Jest:
"scripts": {
"test": "jest"
}
然后在命令行中运行:
npm test
或者如果你使用 yarn:
yarn test
这将运行你的测试,并且你应该看到 `MessageComponent` 的测试通过了。
注意事项
- 单元测试应该是独立的,专注于单一的功能点。
- 使用 mock 来隔离测试,避免对外部服务的依赖。
- 测试时要考虑组件的各种状态,包括边界条件。
- Vue Test Utils 还提供了许多其他的 API,比如 `find`、`emitted` 等,可以帮助你编写更详细的测试。
通过单元测试,你可以确保你的组件按预期工作,并且当你修改代码时,可以迅速发现问题。这是保持代码质量和可维护性的重要手段。
在每个阶段,你可以使用官方文档、教程、书籍、在线资源和实践项目来加深对Vue.js的理解和应用。同时,积极参与Vue社区,与其他开发者交流和分享经验,拓宽自己的视野和技能。
有用请点赞,养成良好习惯!
疑问、交流、鼓励请留言!
更多推荐
所有评论(0)