Vue学习
一、介绍
Vue官方文档:https://cn.vuejs.org/v2/guide/
Vue 是一个采用 MVVM 架构, 通过数据驱动视图的形式来构建用户界面的渐进式框架
“渐进式” 的意思就是从少到多, 从弱到强,需要什么用什么
MVVM
MVVM最早由微软提出来,它借鉴了MVC思想,在前端页面中,把Model(数据)用纯JavaScript对象表示,View负责显示,两者做到了最大限度的分离,把Model和View关联起来的就是ViewModel。
ViewModel负责把Model的数据同步到View显示出来,还负责把View的修改同步回Model。View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理
我们并不关心DOM的结构,而是关心数据如何存储。最简单的数据存储方式是使用js对象:
1 |
|
MVVM的设计思想:关注Model的变化,让MVVM框架去自动更新DOM的状态,从而不需要操作繁琐的DOM
虚拟化DOM
在对数据进行操作后并不会将现数据完全覆盖掉原数据,而是放在虚拟DOM中,通过Diff算法与原数据进行比较,得出应施加到真实 DOM 上的改动
客户端路由
Vue-router 是 Vue.js 官方的路由插件,与 Vue.js 深度集成,用于构建单页面应用。Vue 单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来,传统的页面是通过超链接实现页面的切换和跳转的。Vue是单页面应用,使页面局部刷新,不用每次跳转页面都要请求所有数据和dom
组件化开发
前端的业务逻辑也变的非常复杂,再不是传统意义上的一个文件夹放 html、一个文件夹放js、一个文件夹放css就能搞定的。所以我们要分模块。
一个页面可能会有很多模块需要编写,比如导航栏、侧边栏、底部栏,vue将一个网页拆分成单个组件,每个组件都包含属于自己的html、css和js,哪个页面需要就去调用对应的组件
数据代理
vue数据代理: data对象的所有属性的操作(读/写)由vm对象来代理操作
原理:
- 通过Object.defineProperty(vm, key, {})给vm添加与data对象的属性对应的属性
- 所有添加的属性都包含get/set方法
- 在get/set方法中去操作data中对应的属性
获得data中的对象其实是调用了get方法
生命周期
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
beforeCreate() 实例将要创建
created() 实例创建完成之后
beforeMount() 实例将要挂载
mounted() 实例被挂载后调用。Vue完成模板的解析并把真实的DOM元素放入页面后调用mounted
beforeUpdate 将要更新
updated() 更新完成
beforeDestroy() 将要销毁
destroyed() 销毁完成
二、指令
v-bind:
单向绑定,可以用于响应式地更新 HTML attribute。能够接收一个“参数”,在指令名称之后以冒号表示。
在这里 href
是参数,告知 v-bind
指令将该元素的 href
attribute 与表达式 url
的值绑定。
也可以使用其他的参数名
插值语法用于标签体中的内容,指令语法(以v-开头)管理标签(标签属性、标签体内容、绑定事件) 比如 href=”xxx”
1 |
|
v-model
双向绑定,该指令只能用于表单类元素中
v-model:value=”name” 可简写为 v-model=”name”,因为v-model默认收集的就是value值
1 |
|
v-on
v-on绑定事件监听,可简写为@
1 |
|
v-if
条件渲染
1 |
|
v-show
当值为false时v-if会移除该元素,而v-show会显示该元素,但是使用 display:none隐藏
1 |
|
比如我们有一个编辑员工信息的框,如果员工离职,则需要输入离职日期,在职则不需要输入离职日期(隐藏离职日期框),这时候就要使用v-if,因为v-show仅仅使日期框隐藏,但日期框还是会被渲染,其规则还是存在
v-for
用于展示列表数据
v-for=”(i,index) in list” :key=”i.id” key唯一标识
可循环数组、对象、字符串、指定次数
1 |
|
v-text
三、组件介绍
vue.js和vue框架
vue.js只是vue框架里面的其中一个文件,如果只是在单个页面中使用vue,可以看成和JQ一样,简化dom操作
以前的项目是jsp+java,jsp嵌入后端项目中。而现在是前后端分离,页面脱离jsp变为html,但随着前端开发越来越复制,因此就有了遵循模块化的设计。前端项目的代码结构和分层的与后端的框架差不多,再也不是以前那种直接在一个 js 文件里从上到下一顺儿写下来的样子
vue-cli:Vue的脚手架工具,通过它来创建大的项目环境,可以选择需要使用的工具。用于自动生成Vue项目的目录及文件
vue-router: Vue提供的前端路由工具,利用其我们实现页面的路由控制,局部刷新及按需加载,构建单页应用,实现前后端分离。
vuex:Vue提供的状态管理工具,用于统一管理我们项目中各种数据的交互和重用,存储我们需要用到数据对象。
npm:node.js的包管理工具,用于同一管理我们前端项目中需要用到的包、插件、工具、命令等,便于开发和维护,配置文件是package.json。
webpack:一款强大的文件打包工具,可以将我们的前端项目文件同一打包压缩至js中,并且可以通过vue-loader等加载器实现语法转化与加载。
四、npm命令解释
1.说明
i
是install
的简写-g
是全局安装,不带-g
会安装在项目目录,但不会写入package.json,带-g
安装在磁盘下-S
与--save
的简写,安装包信息会写入dependencies
中。常用这个
下载第三方插件的时候使用–save,会在package.json配置依赖,方便他人使用我们项目时下载所需依赖-D
与--save-dev
的简写,安装包写入devDependencies
中
2.dependencies 与 devDependencies
- dependencies 生产阶段的依赖,也就是项目部署服务器运行时的依赖
- devDependencies (develop)开发阶段的依赖,就是我们在开发过程中需要的依赖,只在开发阶段起作用的
例:开发阶段中编写代码使用的eslint检查代码规范,但在项目上线后,就不需要了,这样就属于devDependencies
如果使用 Element-UI,由于发布到生产后还是依赖 Element-UI,这就可以安装到 dependencies
3.cnpm
npm默认去外网中找依赖,速度很慢,所以需要镜像
1 |
|
3.总结
npm下载的依赖即可在磁盘也可在项目目录,像vue-cli、hexo、cnpm这些构造项目前使用的工具使用**-g,vue、router、vuex项目中使用的模块使用–save**
使用原则:运行时需要用到的模块使用–save,否则使用–save-dev。
devDependencies 属性下的模块是我们在开发时需要用的,比如项目中使用的 gulp ,压缩css、js的模块。这些模块在我们的项目部署后是不需要的,所以我们可以使用 -save-dev 的形式安装。
使用**–save、–save-dev**会在package.json将模块依赖写入,运行 npm install 初始化项目时,会将模块下载到项目目录下。
五、vue-cli安装
创建Vue项目前需要已经安装了node.js
1.安装vue-cli、 @vue/cli
1 |
|
2.创建项目
注意选择一个工作目录
1 |
|
提示
1 |
|
因为我们安装的脚手架是2.9.6版本。2.9.6 创建项目是用 vue init webpack my-project
3.0以上 初始化项目是用 vue create my-project解决方法:
1.使用2.9.6版本的命令vue init webpack my-project
2.卸载2.9.6版本,安装3.0版本
1 |
|
3.选择preset
继续创建项目,会被提示选取一个 preset(可以理解是一个安装模板),默认选择Vue2版本,这里是Vue的版本,和vue-cli插件的版本不是同一个,脚手架只是一个工具,版本的不同只是带来命令格式的不同,而vue版本的不同会导致不同项目的兼容,比如有些第三方插件基于vue2创建,如果使用的是vue3就不能够使用
我们选择第三个 自定义,看一下都会安装哪些东西
光标移动,空格选中
这就是脚手架的好处,它把搭建项目所需的东西都集成了,我们可以选择需要的
choose vue version:选择vue版本
Babel :将高级版本ES转换为浏览器识别的JS语法,ES6->ES5
TypeScript: JS的超集,提供了JS面向对象支持
Progressive Web App (PWA) Support PWA Support:使应用向原生APP
Router :路由、请求所对应的地址
Vuex: 数据状态管理器、用于多页面传参
CSS Pre-processors: CSS预处理,将高级CSS语法转换为浏览器识别CSS语法
Linter / Formatter :代码检查工具,语法检测,严格,项目开发推荐
Unit Testing :单元测试
E2E Testing :端端测试
4.一些配置
5.创建完成
六、vue-cli使用
1.结构分析
node_modules:安装的所有工具
package.json:node环境下都有这个文件,用于包管理。我们之前安装的第三方依赖的名字和版本号都在这里面显示,如果项目是别人的,要先进行
npm install
安装依赖- name - 包名
- version - 包的版本号
- description - 包的描述
- dependencies - 依赖包列表。如果依赖包没有安装,npm 会自动将依赖包安装在 node_module 目录下
- repository - 包代码存放的地方的类型,可以是 git 或 svn,git 可在 Github 上
public:indexl.html文件 ,文件入口
src:放置组件和入口文件
- assets:静态资源
- components:可复用的组件,单个模块级别的组件,比如导航栏
- router:路由,用于页面跳转,把准备好路由组件注册到路由里
- views:存放编写的页面,单个页面级别的组件
- store:存放公共变量
- main.js:项目的入口,项目中的所有页面都会加载main.js,是初始化vue实例并使用需要的插件
- App.vue:是我们的主组件,页面入口文件,所有页面都是在App.vue下进行切换的。也是整个项目的关键,App.vue负责构建定义及页面组件归集。
vue.config.js:vue-cli3 脚手架搭建完成后,项目目录中没有 vue.config.js 文件,需要手动创建。
项目运行后会加载public/index.html,因为脚手架配置了main.js,所以main.js实例化App.vue,App.vue中有两个路由链接。进入route/index.js可以看到两个路由链接的源来自view/Home.vue和About.vue,Home.vue使用了组件components/HelloWorld.vue
2.main.js
main.js编写脚本,App.vue编写页面
1 |
|
3.命令
在README.md文件中有运行项目所需的常用命令
1 |
|
npm run dev和npm run serve的不同
打开package.json,在scripts中可以看到key:value
当我们运行npm run serve时其实运行的命令是vue-cli-service serve,如果要使用dev,将serve改为dev即可
npm run dev 是 vue-cli2 npm run serve 是 vue-cli3
1 |
|
七、ESLint
如果我们在创建项目时使用了ESLint,当运行时代码不符合ESLint规范时就会报错,但是并不会提示具体报错的位置和信息
VsCode插件中安装ESLint,就可以自动检测不符合规范的代码。但是这样需要我们手动一个一个修复,网上有很多教程但是太复杂了。而我们的需求是:当我们进行格式化文档(shift+alt+F)的时候可以自动帮我们修复格式不正确的代码
打开设置,搜索ESLint,勾选 启用ESLint作为格式化程序
这样当我们进行格式化时会出现选项,选择ESLint即可
八、axios
1.安装
1 |
|
2.引用
在main.js文件中引入
如果要全局使用axios就需要在main.js中设置成全局的,然后再组件中通过this调用
1 |
|
3.使用
第一种
1 |
|
第二种
1 |
|
九、vue-router
1.基本路由
创建路由配置项
如果没有加路由的组件,第一步应该是创建组件
在router/index.js
1 |
|
引入
在main.js
第一步引入的是路由插件,这一步加入我们暴露的router
1 |
|
router-link标签
创建:第一步配置了路由,路径和组件之间的映射;
注册:第二步在App中加入了路由,即vue知道了我们的路由配置;
使用:第三步可以使用我们的路由配置了,配置路由链接(相当于a链接)和需要展示组件的区域
在导航栏中(App.vue)
1 |
|
2.嵌套(多级)路由
Home组件原本只有文本内容,显示需要显示两个导航链接news、message
新建两个组件news和message并配置好暴露的名称
编写路由规则children属性
1
2
3
4
5
6
7
8
9
10
11
12
13{
path: '/about',
name: 'About',
component: Home,
children: [
{
// 一级路由需要加/,其他不需要,会自动加上
path: 'news',
component: News
}, {
path: 'message',
component: Message
}]}在父组件Home中使用 二级路由使用:父路径+子路径
1
2<router-link to="/home/news">News</router-link> |
<router-link to="/home/message">Message</router-link>
十、vue-element-admin框架
1.登录接口请求详解
页面:用户单击登录,通过store转发到user的login方法
store/user:共享数据。login方法调用api/user下的login方法
api/user:请求处理。login方法下的url为/uesr/login,mock进行拦截
mock:模拟数据。mock中有/user/login,匹配到api的/user/login,创建token名为XXX-token和code并返回。code值可以在request.js中查看
store中返回token,因为request封装了axios,会根据返回的code判断是否成功,成功调用utils/auth将token存储cookie中,失败则给出错误提示
我们通过用户名获得对应的token,该token是唯一标示用户身份的一个key,再通过token获得对应的用户信息,其中只有token存储在本地
permission会先从 cookie 中查看是否存有 token,没有就执行登录流程,如果有token,就会把这个 token 返给后端user/info接口去拉取user_info。
login返回数据格式
1 |
|
info返回数据格式
1 |
|
logout返回数据格式
1 |
|
2.更改为自己后台接口
更改前端接口
- .env.development:VUE_APP_BASE_AP更改为自己后台的接口
- vue.config.js:注释掉before: require(‘./mock/mock-server.js’),before属性是引入mock.js用前端产生假数据来进行前后交互
- @api中url更改为后台提供的api
后台提供api并返回相应的格式
1 |
|
这个是假登录,不会判断输入信息的正确性,如果需要自定义账户,采用下面这种
创建一个user.properties,自定义用户信息
1 |
|
创建一个User类,加载指定的配置文件,将用户信息存入其中
1 |
|
登录,将入参用户名和密码与配置文件数据进行对比,成功返回一个token,值为 用户名-token
1 |
|
获得用户信息,根据入参token判断是否与配置文件数据相同
1 |
|
3.跨域问题
产生 跨域的主要问题是 协议、域名、端口号 三者有一点不同就会产生跨域问题
- 全局配置
在后台项目中添加配置文件CORSConfig.java
1 |
|
- 局部配置
在需要使用跨域的接口、方法中使用注解@CrossOrigin(origins = “http://localhost:9527”)。参数可省
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!