2.1 简介
官网文档:https://cn.vuejs.org/v2/guide/
Vue 是渐进式 javascript 框架: 让我们通过操作很少的 DOM,甚至不需要操作页面中任何 DOM 元素,就很容易的完成 数据和视图绑定、双向绑定 MVVM。使用 Vue 过程中页面中不需要再引入 Jquery 框架。特点:
- 易用 html css javascript
- 高效 开发前端页面 非常高效
- 灵活 开发灵活 多样性
MVVM(Model-View-ViewModel)是一种软件架构设计模式,MVVM 源自于经典的 MVC(Model-View-Controller)模式;MVVM 的核心是 ViewModel 层,负责转换 Model 中的数据对象来让数据变得更容易管理和使用,其作用如下:
- 该层向上与视图层进行双向数据绑定
- 向下与 Model 层通过接口请求进行数据交互
View
View 是视图层,也就是用户界面。前端主要由 HTML
和 CSS
来构建,为了更方便地展现 ViewModel
或者 Model
层的数据,已经产生了各种各样的前后端模板语言,比如 FreeMarker、Thymeleaf 等等
Model
Model 是指数据模型,泛指后端进行的各种业务逻辑处理和数据操控,主要围绕数据库系统展开。这里的难点主要在于需要和前端约定统一的 接口规则
ViewModel
ViewModel 是由前端开发人员组织生成和维护的视图数据层。在这一层,前端开发者对从后端获取的 Model 数据进行转换处理,做二次封装,以生成符合 View 层使用预期的视图数据模型。
2.2 实例
2.2.1 入门示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue 入门</title>
</head>
<body>
<div id="app">
<span> I am {{name}} ! </span>
<br>
<span>
{{ msg }} <!--{{}}:插值表达式-->
</span>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
const app = new Vue({
el : "#app", // element 用来给 Vue 实例定义一个作用范围
data : { // 用来给 Vue 定义一些相关数据
msg : "Hello Vue.js !",
name : "zhenyu"
}
});
</script>
</body>
</html>
- Vue 实例对象中
el
属性:代表 Vue 的作用范围,在 Vue 的作用范围内都可以使用 Vue 的语法。 - Vue 实例对象中
data
属性:用来给 Vue 实例绑定一些相关数据,绑定的数据可以通过{{ xx }}
在 Vue 作用范围内取出。 - 在使用
{{ xx }}
进行获取data
中数据时,可以在{{ }}
中书写表达式、运算符、调用相关方法以及逻辑运算等。 el
属性中可以书写任意的 CSS选择器[jquery选择器],但是在使用 Vue 开发推荐使用 id选择器。
2.3 基础语法
2.3.1 v-text:
v-text
:用来获取 data 中数据将数据以文本的形式渲染到指定标签内部,类似于 javascript 中 innerText
。
{{ xx }}
(插值表达式)和 v-text
获取数据的区别在于:
- 使用
v-text
取值会将标签中原有的数据覆盖,
插值表达式的形式不会覆盖标签原有的数据。 - 使用
v-text
可以避免在网络环境较差的情况下出现插值闪烁。(已修复)
2.3.2 v-html:
v-html
:用来获取 data 中数据将数据中含有的 html 标签先解析在渲染到指定标签的内部,类似于 javascript 中 innerHTML
。
2.3.3 v-on:
v-on
:事件绑定
v-on:click
可以简化成@click
- 事件函数可以简写,
dowork: function() {}
可以简写成dowork() {}
2.3.4 v-show:
v-show
:用来控制页面中某个标签元素是否展示,底层通过控制元素的 display
属性来进行标签的显示和不显示控制。
- 在
v-show
中可以直接书写boolean
值控制元素展示 - 在
v-show
中可以通过 变量 控制标签展示和隐藏。 - 在
v-show
中可以通过 boolean表达式 控制标签的展示和隐藏。
2.3.5 v-if:
v-if
:用来控制页面中的标签元素是否展示,底层通过对 dom 树节点进行添加和删除来控制展示和隐藏。
与 v-show
的用法一模一样,参考 v-show
即可。
2.3.6 v-bind:
v-bind
:用来绑定 标签的属性 从而通过 vue 动态修改标签的属性。
v-bind : 属性
可以简写成: 属性
2.3.7 v-for:
v-for
:用来对 对象 进行遍历的(JavaScript 中数组也是对象的一种)
- 在使用
v-for
的时候一定要注意加入:key
用来给 Vue 内部提供重用和排序的唯一 key - 遍历时可以获取 索引
index
、…
2.3.8 v-model:
v-model
:用来绑定 标签元素的值 与 vue实例对象中data数据 保持一致,从而实现 双向的数据绑定机制。
- 所谓双向绑定,就是表单中数据变化导致 vue 实例 data 数据变化,vue 实例中 data 数据的变化导致表单中数据变化。
2.3.9 记事本案例
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>记事本综合案例</title>
</head>
<body>
<div id="app">
<input type="text" v-model="msg">
<input type="button" value="添加到记事本" @click="save"><br><br>
【记事本内容】:
<ul v-for="item,index in lists">
<li>
{{ index + 1}} : {{ item }} <a href="javascript:;" @click="delRow(index)">删除</a>
</li>
</ul>
<br>
<span>总数量: {{ lists.length }} 条</span>
<input type="button" v-show="lists.length != 0" value="删除所有" @click="deleteAll">
</div>
<!--
1.完成记事本的查询所有思路:
1).将所有数据绑定为vue实例
2).遍历vue实例中数据到页面
2.添加
1).添加按钮绑定事件中
2).在事件中获取输入框中数据
3).将获取的数据放入到lists里面
1.完成记事本的查询所有思路:
1).将所有数据绑定为vue实例
2).遍历vue实例中数据到页面
2.添加
1).添加按钮绑定事件中
2).在事件中获取输入框中数据
3).将获取的数据放入到lists里面
3.删除
1).删除所有
2).总数量
-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
lists: ["这是一个记事本的小案例!"],
msg: ''
},
methods: {
save() {
this.lists.push(this.msg)
this.msg = ''
},
delRow(index) { // 删除一条记录
// 根据下标删除数组中某个元素
this.lists.splice(index)
},
deleteAll() { // 删除所有数据
this.lists = []
},
},
});
</script>
</body>
</html>
2.3.10 修饰符
(1)事件修饰符
修饰符作用:用来和事件连用,决定事件触发条件或者是阻止事件的触发机制。
常用的事件修饰符:
.stop
:用来阻止事件冒泡。.prevent
:用来阻止标签的默认行为。.capture
.self
:只触发自己标签的上特定动作的事件,不监听事件冒泡。.once
:让指定事件只触发一次。.passive
(2)按键修饰符
作用:用来与键盘中按键事件绑定在一起,用来修饰特定的按键事件的修饰符。
常用按键修饰符:@keyup.xxx="function "
2.4 Axios异步通信
中文网站:https://www.kancloud.cn/yunye/axios/234845
2.4.1 执行 GET
请求
// 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 可选地,上面的请求可以这样做
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
2.4.2 执行 POST
请求
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
2.4.3 执行多个并发请求
function getUserAccount() {
return axios.get('/user/12345');
}
function getUserPermissions() {
return axios.get('/user/12345/permissions');
}vue
axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function (acct, perms) {
// 两个请求现在都执行完成
}));
2.5 生命周期
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>vue生命周期函数</title>
</head>
<body>
<div id="app">
<span id="sp"> {{ msg }} </span>
<input type="button" value="改变data的值" @click="changeData">
</div>
<!-- 引入Vue -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
msg: "hello Vue.js!",
},
methods: {
changeData() {
// this.msg = "Vue.js niubility!";
this.msg = Math.random();
}
},
// ====================初始化阶段====================
// 1.生命周期中第一个函数,该函数在执行时Vue实例仅仅完成了自身事件的绑定和生命周期函数的初始化工作,Vue实例中还没有 Data el methods相关属性
beforeCreate() {
console.log("beforeCreate: " + this.msg);
},
// 2.生命周期中第二个函数,该函数在执行时Vue实例已经初始化了data属性和methods中相关方法
created() {
console.log("created:" + this.msg);
},
// 3.生命周期中第三个函数,该函数在执行时Vue将El中指定作用范围作为模板编译
beforeMount() {
console.log("beforeMount: " + document.getElementById("sp").innerText);
},
// 4.生命周期中第四个函数,该函数在执行过程中,已经将数据渲染到界面中并且已经更新页面
mounted() {
console.log("Mounted: " + document.getElementById("sp").innerText);
},
// ====================运行阶段====================
// 5.生命周期中第五个函数,该函数是data中数据发生变化时执行 这个事件执行时仅仅是Vue实例中data数据变化页面显示的依然是原始数据
beforeUpdate() {
console.log("beforeUpdate-vue: " + this.msg);
console.log("beforeUpdate-dom: " + document.getElementById("sp").innerText);
},
// 6.生命周期中第六个函数,该函数执行时data中数据发生变化,页面中数据也发生了变化 页面中数据已经和data中数据一致
updated() {
console.log("updated-vue: " + this.msg);
console.log("updated-dom: " + document.getElementById("sp").innerText);
},
// ====================销毁阶段====================
// 7.生命周期第七个函数,该函数执行时,Vue中所有数据 methods componet 都没销毁
beforeDestory() { },
// 8.生命周期的第八个函数,该函数执行时,Vue实例彻底销毁
destoryed() { }
});
</script>
</body>
</html>
2.6 组件
在实际开发中,并不会用以下方式开发组件,而是采用vue-cli
创建,vue
模板文件的方式开发,以下方法只是为了让大家理解什么是组件。组件是可复用的Vue
实例, 说白了就是一组可以重复使用的模板。
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>局部组件的开发</title>
</head>
<body>
<div id="app">
<login></login>
<login></login>
<login></login>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 定义变量用来保存模板配置对象
const login = {
template: '<div><h2>用户登录</h2></div>'
};
const app = new Vue({
el: "#app",
data: {},
methods: {},
components: { // 局部组件
login: login // 注册局部组件
}
});
</script>
</body>
</html>
2.7 计算属性
计算属性的重点突出在属性
两个字上(属性是名词),首先它是个属性
其次这个属性有计算
的能力(计算是动词),这里的计算
就是个函数,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销;
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
message:"pan"
},
methods:{
currentTime1:function(){
return Date.now();//返回一个时间戳
}
},
computed:{
currentTime2:function(){//计算属性:methods,computed方法名不能重名,重名之后,只会调用methods的方法
this.message;
return Date.now();//返回一个时间戳
}
}
});
</script>
2.8 路由
定义一个Content.vue
的组件
<template>
<div>
<h1>内容页</h1>
</div>
</template>
<script>
export default {
name:"Content"
}
</script>
Main.vue
组件
<template>
<div>
<h1>首页</h1>
</div>
</template>
<script>
export default {
name:"Main"
}
</script>
安装路由,在src目录下,新建一个文件夹:router
,专门存放路由,配置路由index.js,如下
import Vue from'vue'
//导入路由插件
import Router from 'vue-router'
//导入上面定义的组件
import Content from '../components/Content'
import Main from '../components/Main'
//安装路由
Vue.use(Router) ;
//配置路由
export default new Router({
routes:[
{
//路由路径
path:'/content',
//路由名称
name:'content',
//跳转到组件
component:Content
},{
//路由路径
path:'/main',
//路由名称
name:'main',
//跳转到组件
component:Mian
}
]
});
在main.js
中配置路由
import Vue from 'vue'
import App from './App'
//导入上面创建的路由配置目录
import router from './router'//自动扫描里面的路由配置
//来关闭生产模式下给出的提示
Vue.config.productionTip = false;
new Vue({
el:"#app",
//配置路由
router,
components:{App},
template:'<App/>'
});
3.Vue CLI
3.1 简介
Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统。使用 Vue 脚手架之后我们开发的页面将是一个完整系统(项目)。官方网站:https://cli.vuejs.org/zh/guide/
Vue CLI 中项目开发方式:一切皆组件!
VueCLI 开发方式是在项目中开发一个一个组件对应一个业务功能模块,日后可以将多个组件组合到一起形成一个前端系统。
日后在使用 Vue CLI 进行开发时不再书写html,编写的是一个个组件(.vue文件),打包时 Vue CLI 会将组件编译成运行的 html 文件。
3.2 第一个 Vue 脚手架项目
3.2.1 命令创建项目
(1)使用以下命令来创建一个新项目:
vue create hello-world
(2)我们选择 手动配置:用方向键 ↑ ↓ 操控选项,Enter 确定;
Please pick a preset: (Use arrow keys)
> default (babel, eslint) # 默认配置
Manually select features # 手动配置
123
(3)选择配置,勾选如下即可:方向键 ↑ ↓ 操作,按空格选中,Enter 确定;
Vue CLI v4.4.6
Please pick a preset: Manually select features
Check the features needed for your project:
(*) Babel
( ) TypeScript
( ) Progressive Web App (PWA) Support
(*) Router
(*) Vuex
(*) CSS Pre-processors
(*) Linter / Formatter
( ) Unit Testing
>( ) E2E Testing
123456789101112
(4)首先检查刚才选择的配置;
然后问我们是否使用 history mode,其实就是页面路由含不含有 #
;这里我们选择 Y
Check the features needed for your project: Babel, Router, Vuex, CSS Pre-processors, Linter
Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n)
y
123
(5)选择CSS预编译器,这里我们选择Less;
Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys)
> Sass/SCSS (with dart-sass)
Sass/SCSS (with node-sass)
Less
Stylus
12345
(6)选择 ESLint 代码校验规则,
提供一个插件化的 javascript 代码检测工具,这里我们选择 ESLint + Prettier;
Pick a linter / formatter config:
ESLint with error prevention only
ESLint + Airbnb config
ESLint + Standard config
> ESLint + Prettier
12345
(7)选择什么时候进行代码校验,Lint on save:保存就检查,
Lint and fix on commit:fix 或者 commit 的时候检查,这里我们选择第一个;
Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
>(*) Lint on save
( ) Lint and fix on commit
123
(8)选择把配置保存到哪个文件中,
In dedicated config files 存放到独立文件中,In package.json 存放到 package.json 中,
这里我们选择放到 package.json 中;
Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
In dedicated config files
> In package.json
123
(9)问我们是否保存刚才的配置,以后的文件可以直接使用,选择 N。
Save this as a preset for future projects? (y/N)
N
12
(10)使用如下命令运行项目:
cd hello-world # 首先进入项目根路径
npm run serve # 运行项目
(11)浏览器输入如下路径来访问项目:
http://localhost:8080
3.2.2 图形化界面创建项目
使用图形化界面创建和管理项目:
vue ui
node_modules
:用于存放我们项目的各种依赖;public
:用于存放静态资源(不会变动的);public/index.html
:模板文件,作用是生成项目的入口文件。
浏览器访问项目的时候就会默认打开的是生成好的 index.html。
src
:是存放各种 .vue 文件的地方。src/assets
:用于存放着各种静态文件(可能会变动),比如图片。src/components
:存放公共组件(可复用),比如 header.vue、footer.vue 等。src/router/index.js
:vue-router 路由文件。
需要引入 src/views 文件夹下的 .vue,配置 path、name、component。src/store/index.js
:是 vuex 的文件,主要用于项目里边的一些状态保存。
比如 state、mutations、actions、getters、modules。src/views
,存放页面组件(不可复用),比如 Login.vue,Home.vue。src/App.vue
:App.vue 是项目的主组件;
App.vue 中使用 router-link 引入其他模块,所有的页面都是在 App.vue 下切换的。src/main.js
:入口文件,主要作用是初始化 vue 实例,同时可以在此文件中引用某些组件库或者全局挂载一些变量。
.gitignore
:配置 git 上传想要忽略的文件格式。babel.config.js
:一个工具链,主要用于在当前和较旧的浏览器或环境中将 ES6 的代码转换向后兼容(低版本ES)。package.json
:模块基本信息项目开发所需要的模块,版本,项目名称。package-lock.json
:是在 npm install 时候生成的一份文件,用于记录当前状态下实际安装的各个 npm package 的具体来源和版本号
3.2.3 vue-cli 中使用 Axios
(1)安装 axios
npm install axios --save-dev
(2)配置文件 main.js 中引入 axios:
import axios from 'axios';
Vue.prototype.$http=axios;
(3)使用 axios:
this.$http.get("url").then((res)=>{});
this.$http.post("url").then((res)=>{});
3.2.4 Vue 脚手架项目部署到 springboot 项目
打包完后,如何将项目部署到 SpringBoot 项目上呢?
将打包好的 dist
目录放到 SpringBoot 项目的 static
目录下;
由于我在配置文件中配置了项目路径:(没有访问路径则不需要修改)
server.servlet.context-path=/vue
所以要修改一下 index.html 中引入资源文件的路径;
通过以下路径访问部署的前端页面:
http://localhost:8989/vue/dist/index.html
4.Element UI
4.1介绍与安装
4.1.1 介绍
官网:https://element.eleme.io/#/zh-CN
官方定义:网站快速成型工具 和 桌面端组件库;Element UI 中提供的全部都是封装好组件。
4.1.2 安装
- 首先通过 Vue脚手架 创建项目:
vue create hello-element
1
- 在 Vue 脚手架项目中安装 Element UI:
npm i element-ui -S
1
- 指定项目中使用 Element UI,在 index.js 中添加以下代码:`
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI); // 在vue脚手架中使用elementui
4.1.2 使用
每个组件都有 属性、事件、方法。事件和方法的区别在于:事件是去调用自己写的函数,方法相当于它给你写好的函数,你去调用;
掌握 属性、事件、方法 的用法后,所有组件的使用基本都一样。
- 大部分组件都是以
el-组件名
开头,比如el-button
是按钮;
<el-button>默认按钮</el-button>
1
- Element UI 中所有组件的 属性(Attributes) 全部写在组件标签上;
<el-button type="primary" 属性名=属性值>默认按钮</el-button>
1
- 事件(Events) 也是直接写在对应的组件标签上,使用 Vue 中绑定事件方式
@change="aa"
;
<el-radio v-model="label" @change="aa" name="sex" label="男">男</el-radio>
<el-radio v-model="label" @change="aa" name="sex" border size="small" label="女">女</el-radio>
<script>
export default {
name: "Radio",
data(){
return{
label:'男'
}
},
methods:{
aa(){ //定义的事件处理函数
console.log(this.label);
}
}
}
</script>
123456789101112131415161718
- 组件的 方法(Methods):
在对应的组件中加入ref="组件别名"
;
通过this.$refs.组件别名.方法名()
调用方法;
<h1>方法的使用</h1>
<el-input v-model="username" ref="inputs"></el-input>
<el-button @click="focusInputs">focus方法</el-button>
<el-button @click="blurInputs">blur方法</el-button>
<script>
export default {
name: "Input",
data() {
return{}
},
methods:{
// 调用focus方法
focusInputs(){
this.$refs.inputs.focus();
},
// 调用失去焦点方法
blurInputs(){
this.$refs.inputs.blur();
}
}
}
</script>