文章目录
- 基本介绍
- Vue是什么?
- MVVM
- Vue的使用
- 快速入门
- 注意事项和使用细节
- Vue 数据绑定机制分析
- 数据单向渲染
- 注意事项和细节
- 双向数据绑定
- 事件绑定
- 示例:
- 注意事项和使用细节
- 课后作业1
- 课后作业2
- 修饰符
- 示例
- 条件渲染/控制: v-if v-show
- v-if VS v-show
- 课后作业
- 列表渲染: v-for
- 应用实例
- 课后练习
- 组件化编程
- 生命周期和监听函数(钩子函数)
- Vue2 脚手架模块化开发
- 为什么需要 Vue Cli 脚手架?
- Vue2配置教程&IDEA配置VUE
- Vue 项目结构分析
- 分析执行流程
- Element UI
- Element UI 配置
- Axios
- Axios 库文件
- 使用方式
- 示例
基本介绍
Vue是什么?
- Vue (读音 /vjuː/,类似于 view) 是一个前端框架, 易于构建用户界面
- Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或项目整合
- 支持和其它类库结合使用
- 开发复杂的单页应用非常方便
- Vue 是 Vue.js 的简称
官网: https://cn.vuejs.org/
git 地址: https://github.com/vuejs
MVVM
思想:
- M∶即 Model,模型,包括数据和一些基本操作
- V∶即View,视图,页面渲染结果
- VM∶即 View-Model,模型与视图间的双向操作(无需开发人员干涉)
- 在 MVVM之前,开发人员从后端获取需要的数据模型,然后要通过 DOM 操作 Model渲染到View 中。而后当用户操作视图,我们还需要通过 DOM获取 View 中的数据,然后同步到Model 中。
- 而 MVVM中的VM 要做的事情就是把DOM 操作完全封装起来,开发人员不用再关心Model 和View 之间是如何互相影响的
- 只要我们 Model 发生了改变,View上自然就会表现出来
- 当用户修改了View,Model 中的数据也会跟着改变。
- 结果:把开发人员从繁琐的 DOM操作中解放出来,把关注点放在如何操作 Model上, 大大提高开发效率
Vue的使用
下载下面的文件:vue.js
导入到当前项目路径下:
快速入门
使用插值表达式:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue快速入门</title>
</head>
<body>
<div id="app">
<h1>欢迎你,{{message}}, {{name}}</h1>
</div>
<script src="vue.js"></script>
<script>
<!--创建vue对象-->
let vm = new Vue({
el:"#app", <!--创建的vue实例挂载到id=app的div上, el是element的简写-->
data:{ <!--data{}表示数据池(model的数据), 有很多数据,以k-v形式设置-->
message:"helllo!!",
name:"彭于晏"
}
})
console.log("vm=>", vm);
console.log(vm.name);
</script>
</body>
</html>
注意事项和使用细节
- 注意代码顺序,要求 div 在前,script 在后,否则无法绑定数据
Vue 数据绑定机制分析
数据单向渲染
- v-bind 指令可以完成基本数据渲染/绑定
- v-bind 简写形式就是一个冒号(:)
- 大白话就是后端的改变可以直接改变前端。
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>单项数据渲染</title>
</head>
<body>
<div id="kkkb">
<h1>{{message}}</h1>
<!--1. 使用插值表达式引用data数据池数据是在标签体内-->
<!--2. 如果是在标签元素的属性上去引用data数据池数据时, 不能使用插值表达式.需要使用v-bind表达式.-->
<!--3. 写法为 v-bind:标签名,或者可以直接省略v-bind, 写成:标签名 -->
<img v-bind:src="img_src" v-bind:width="img_width">
<img :src="img_src" :width="img_width"> <!--可以省略v-bind,直接写:标签名 -->
</div>
<script src="vue.js"></script>
<script>
let vm = new Vue
({
el:"#kkkb", //#根据id选择是JQuery中的内容
data:{
message:"我朝!",
img_src:"1.jpg",
img_width:"200px"
}
})
</script>
</body>
</html>
注意事项和细节
- 插值表达式是用在标签体的
- 如果给标签属性绑定值,则使用 v-bind 指令
双向数据绑定
v-model 可以完成双向数据绑定
大白话就是前端的改变会影响后端,后端的改变也会影响前端。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>双向数据渲染饭</title>
</head>
<body>
<div id="afk">
<!--
1. v-bind 是数据单向渲染: data 数据池绑定的数据变化,会影响 view (后端影响前端)
2. v-model="hobby.val" 是数据的双向渲染,
(1)data 数据池绑定的数据变化,会影响 view 【底层的机制是 Data Bindings】
(2)view 关联的的元素值变化, 会影响到 data 数据池的数据【底层机制是 DomListeners】
-->
<h1>hi,输入你的爱好</h1>
<input type="text" v-model="hobby.val"><br/>
<input type="text" :value="hobby.val"><br/>
你输入的爱好是:{{hobby.val}}
</div>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el: "#afk",
data: {
hobby: {
val: "购物"
}
}
})
</script>
</body>
</html>
事件绑定
- 使用 v-on 进行事件处理,比如: v-on:click 表示处理鼠标点击事件
- 事件调用的方法定义在 vue 对象声明的 methods 节点中
- v-on:事件名 可以绑定指定事件
示例:
<!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">
<button v-on:click="sayHi()">点击输出</button> <!-- v-on:click="sayHi()" 表示给这个按钮绑定一个click事件, sayHi()表示这个事件绑定的方法-->
<button v-on:click="sayOK">点击输出</button> <!--如果没有参数,可以省略()-->
<button @click="sayOKK()">点击输出</button> <!-- v-on:可以省略成@ -->
<button v-on:click="sayOKKK()">点击输出</button>
</div>
<!--引入vue.js-->
<script src="vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
message:"Hello",
name:"wxy",
},
methods: { //表示methods属性, 后面对应的值是对象. 在这里可以写很多方法, 前面的data可以写很多属性.
sayHi() {
console.log("hi, 银角大王");
},
sayOK() {
console.log("hi, 金角大王");
},
sayOKK() {
console.log("hi, 第三个按钮");
},
sayOKKK() {
console.log("hi, 第四个按钮");
}
}
})
</script>
</body>
</html>
注意事项和使用细节
- 如果方法没有参数,可以省略()[需要浏览器支持]
- v-on 指令的简写形式 @ [需要浏览器支持]
课后作业1
<!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="lgq">
<h1>演示Vue事件绑定操作</h1>
<button @click="addOne">点击增加+1</button><br/>
<button @click="addTwo">点击增加+2</button><br/>
<button v-on:click="times += 3">点击增加+3 </button><br/> <!--可以直接写个表达式 times += 3-->
你的按钮被点击了{{times}}次
</div>
<script src="vue.js"></script>
<script>
new Vue({
el:"#lgq",
data:{
times:0,
},
methods:{
addOne(){
this.times += 1;
},
addTwo(){
this.times += 2;
}
}
})
</script>
</body>
</html>
课后作业2
<!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="lgq">
<h1>演示Vue事件绑定操作</h1>
书名:<input type="text" v-model=name><br/>
<button @click="show">点击显示输入框的内容</button>
</div>
<script src="vue.js"></script>
<script>
new Vue({
el:"#lgq",
data:{
name:"请输入书名"
},
methods:{
show(){
alert("您当前输入的书名是:" + this.name);
}
}
})
</script>
</body>
</html>
修饰符
- 修饰符 (Modifiers) 是以(.)指明的后缀,指出某个指令以特殊方式绑定。
- 例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()即阻
止事件原本的默认行为 - 事件修饰符
.stop 阻止事件继续传播
.prevent 阻止标签默认行为
.capture 使用事件捕获模式,即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理
.self 只当在 event.target 是当前元素自身时触发处理函数
.once 事件将只会触发一次
.passive 告诉浏览器你不想阻止事件的默认行为 - 键盘事件的修饰符
比如: 项目经常需要监听一些键盘事件来触发程序的执行,而 Vue 中允许在监听的时候添加关键修饰符
官方文档:
示例
需求: 演示 v-on:submit.prevent 的使用, 如果没有输入名字,控制台输出 “请输入名字”,否则输出 "提交表单
为什么在开发中, 有时需要 , 让某个指令以特殊方式绑定, 比如表单提交
- 我们不希望将这个表单进行整体提交, 而是是 Ajax 的方式进行提交
- 因为表单整体提交会导致重载页面, 而 Ajax 方式可以有选择性提交数据,并且局部刷新
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>事件修饰符的使用</title>
</head>
<body>
<div id="app">
<form action="https://www.baidu.com" v-on:submit.prevent="onMySubmit"> <!-- v-on 是对事件进行绑定 -->
<!-- v-on:submit.prevent表示按照自己的方式提交表单,不使用默认方式提交 -->
妖怪名
<input type="text" v-model="monster.name"><br/> <!--和属性monster的name双向绑定-->
<button type="submit">提交</button>
</form>
<h1>按键修饰符</h1>
<button v-on:click.once="clickOnce">仅点击第一次有用</button>
<br/><br/>
<h1>点击回车会有提示</h1>
<input type="text" v-on:keyup.enter="onInputSubmit">
<h1>自动去掉空格</h1>
<input type="text" v-model.trim="count"> <!-- v-model: 双向数据渲染-->
</div>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
count:0,
monster: {}
},
methods: {
onMySubmit() {
// "", null, undefined都表示为false
if (this.monster.name) {
alert("提交表单");
} else {
alert("请输入名字!");
}
},
clickOnce() {
alert("点击成功!");
},
onInputSubmit() {
alert("输入成功!");
}
}
})
</script>
</body>
</html>
条件渲染/控制: v-if v-show
v-if
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-if的使用</title>
</head>
<body>
<div id="app">
<input type="checkbox" v-model="sel">是否同意条款[v-if实现]
<h1 v-if="sel">你同意条款</h1>
<h1 v-else>你不同意条款</h1>
</div>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
sel:false,
}
})
</script>
</body>
</html>
v-show
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-show的使用</title>
</head>
<body>
<div id="app">
<input type="checkbox" v-model="sel">是否同意条款[v-show实现]
<h1 v-if="sel">你同意条款</h1>
<h1 v-else="!sel">你不同意条款</h1>
</div>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
sel:false,
}
})
</script>
</body>
</html>
v-if VS v-show
v-if 会确保在切换过程中,条件块内的事件监听器和子组件销毁和重建。
v-show 机制相对简单, 不管初始条件是什么,元素总是会被渲染,并且只是对 CSS 进行切换
课后作业
1、如图,当用户输入成绩时, 可以输出对应的级别
- 90 分以上, 显示优秀
- 70 分以上, 显示良好
- 60 分以上, 显示及格
- 低于 60 分, 显示不及格
- 如果用户输入的成绩大于 100, 就修正成 100, 如果用户输入的成绩小于 0, 就修正成0
<!DOCTYPE html>
<html lang="en" xmlns:v-if="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>显示成绩</title>
</head>
<body>
<div id="app">
输入成绩1-100:
<input type="text" v-model="score" v-on:blur="check"><br/> <!--要实现判断大于100时变成100, 小于0时变成0,需要进行事件绑定:v-on:blur="check"-->
你当前的成绩是:{{score}}
<p v-show="score>100">成绩不合法</p>
<p v-show="score<=100&&score>90">优秀</p>
<p v-show="score<=90&&score>70">良好</p>
<p v-show="score<=70&&score>=60">及格</p>
<p v-show="score<60">不及格</p>
</div>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
score: 0,
},
methods:{
check(){
if(this.score > 100) {
this.score=100;
}
if(this.score < 0 ){
this.score = 0;
}
}
}
})
</script>
</body>
</html>
列表渲染: v-for
官方文档:https://cn.vuejs.org/v2/guide/list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>遍历数组</title>
</head>
<body>
<h1>使用v-for遍历数组</h1>
<ul id="app">
<li v-for="item in items">
{{item.message}}
</li>
<br/><br/>
<li v-for="(item, index) in items">
{{index}} - {{item.message}}
</li>
</ul>
<h1>使用v-for遍历一个对象的property</h1>
<ul id="v-for-property">
<li v-for="(value, name) in object">
{{name}} : {{value}}
</li>
</ul>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
items:[
{message:'foo'},
{message:'bar'}
]
}
})
let vm1 = new Vue({
el:"#v-for-property",
data:{
object:{
title:"How to do lists in Vue",
author:"Jane Doe",
publishedAt:'2001-2-2',
}
}
})
</script>
</body>
</html>
应用实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>遍历数组</title>
</head>
<body>
<ul id="app">
<h1>简单的列表渲染</h1>
<li v-for="item in items">
{{item}}
</li>
<h1>带索引的列表渲染</h1>
<br/><br/>
<li v-for="(item, index) in items">
{{index}} - {{item }}
</li>
<h1>列表渲染table</h1>
<table width="400px" border="1px">
<th>下标</th>
<th>id</th>
<th>name</th>
<th>age</th>
<tr v-for="(monster,index) in monsters">
<td>{{index}}</td>
<td>{{monster.id}}</td>
<td>{{monster.name}}</td>
<td>{{monster.age}}</td>
</tr>
</table>
</ul>
<ul id="v-for-property">
<li v-for="(value, name) in object">
{{name}} : {{value}}
</li>
</ul>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
items: [
1, 2, 3
],
monsters: [
{id: 1, name: '牛魔王', age: 800},
{id: 2, name: '黑山老妖', age: 900},
{id: 3, name: '红孩儿', age: 200}
]
}
})
</script>
</body>
</html>
课后练习
1、如图, 显示成绩及格的学生列表
- 将学生对象, 存放在数组中
- 遍历显示所有学生, 只显示成绩及格的学员
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>遍历数组</title>
</head>
<body>
<!--显示及格的学生的信息-->
<ul id="app">
<h1>列表渲染table</h1>
<table width="400px" border="1px">
<th>下标</th>
<th>id</th>
<th>name</th>
<th>age</th>
<th>score</th>
<tr v-if="student.score>=60" v-for="(student,index) in students" > <!--成绩大于等于60-->
<td>{{index}}</td>
<td>{{student.id}}</td>
<td>{{student.name}}</td>
<td>{{student.age}}</td>
<td>{{student.score}}</td>
</tr>
</table>
</ul>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
students: [
{id: 1, name: 'jack', age: 8, score:90},
{id: 2, name: 'tom', age: 9, score:70},
{id: 3, name: 'mary', age: 7, score:50}
]
}
})
</script>
</body>
</html>
组件化编程
- 在大型应用开发的时候,页面可以划分成很多部分,往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。
- 但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发(如图)
- 组件(Component) 是 Vue.js 最强大的功能之一(可以提高复用性[1.界面2.业务处理])
- 组件也是一个Vue实例,也包括∶ data、methods、生命周期函数等
- 组件渲染需要 html模板,所以增加了template 属性,值就是 HTML 模板
- 对于全局组件,任何vue 实例都可以直接在 HTML 中通过组件名称来使用组件
- data 是一个函数,不再是一个对象, 这样每次引用组件都是独立的对象/数据
组件化编程-全局组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用全局组件</title>
</head>
<body>
<div id="app">
<!-- 使用全局组件-->
<counter></counter><br/>
<counter></counter>
</div>
<script src="vue.js"></script>
<script>
/*
* 1. 定义一个全局组件, 名称为counter
* 2. {} 表示的是我们组件的相关的内容
* 3. template 指定该组件的界面, 因为会引用到数据池的数据,所以需要使用模板字符串
* 4. 这里要把组件视为一个Vue实例, 也有自己的数据池和methods
* 5. 对于组件, 数据池的数据,是使用函数/方法返回return的[目的是为了保证每个组件的数据是独立的],不能使用原来的方式.
* 6. 全局组件属于所有的vue实例, 因此可以在所有的vue实例中使用
* */
Vue.component("counter", {
template: `<button v-on:click="click()">点击次数={{count}}</button>>`,
data() {
return {
count: 0,
}
},
methods: {
click() {
this.count++;
}
}
})
// 创建vue实例, 必须有
let vm = new Vue({
el:"#app",
})
</script>
</body>
</html>
组件化变成——局部组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用局部组件</title>
</head>
<body>
<div id="app">
<!-- 使用局部组件-->
好处:
1. 可以把常用的组件定义在某个commons.js中,然后export.
2. 如果某个页面需要使用, 直接import即可
<my_counter></my_counter>
<my_counter></my_counter>
<my_counter></my_counter>
</div>
<script src="vue.js"></script>
<script>
// 使用 const 定义局部组件
const buttonCounter = {
template: `<button v-on:click="click()">点击次数={{count}}</button>>`,
data() {
return {
count: 0,
}
},
methods: {
click() {
this.count++;
}
}
}
// 创建vue实例, 必须有
let vm = new Vue({
el: "#app",
components: { //引入/注册某个组件, 此时 my_counter 就是一个组件, 是一个局部组件,他的使用范围在当前 vue
'my_counter': buttonCounter,
}
})
</script>
</body>
</html>
生命周期和监听函数(钩子函数)
- Vue 实例有一个完整的生命周期,也就是说从开始创建、初始化数据、编译模板、挂载
DOM、渲染-更新-渲染、卸载等一系列过程,我们称为 Vue 实例的生命周期 - 钩子函数(监听函数): Vue 实例在完整的生命周期过程中(比如设置数据监听、编译模板、将实例挂载到 DOM 、在数据变化时更新 DOM 等), 也会运行叫做生命周期钩子的函数
- 钩子函数的 作用就是在某个阶段, 给程序员一个做某些处理的机会
Vue 实 例 的 生 命 周 期 示 意 图 , 地址:
- new Vue()
new 了一个 Vue 的实例对象,此时就会进入组件的创建过程。 - Init Events & Lifecycle
初始化组件的事件和生命周期函数 - beforeCreate
组件创建之后遇到的第一个生命周期函数,这个阶段 data 和 methods 以及 dom 结构都未被初始化,也就是获取不到 data 的值,不能调用 methods 中的函数 - Init injections & reactivity
这个阶段中, 正在初始化 data 和 methods 中的方法 - created
这个阶段组件的 data 和 methods 中的方法已初始化结束,可以访问,但是 dom 结构未初始化,页面未渲染
老师说明:在这个阶段,经常会发起 Ajax 请求
- 编译模板结构(在内存)
- beforeMount
当模板在内存中编译完成,此时内存中的模板结构还未渲染至页面上,看不到真实的数据 - Create vm.$el and replace ‘el’ with it
这一步,再在把内存中渲染好的模板结构替换至真实的 dom 结构也就是页面上 - mounted
此时,页面渲染好,用户看到的是真实的页面数据, 生命周期创建阶段完毕,进入到了运
行中的阶段 - 生命周期运行中
10.1 beforeUpdate
当执行此函数,数据池的数据新的,但是页面是旧的
10.2 Virtual DOM re-render and patch
根据最新的 data 数据,重新渲染内存中的模板结构,并把渲染好的模板结构,替换至页面上
updated
页面已经完成了更新,此时,data 数据和页面的数据都是新的
- beforeDestroy
当执行此函数时,组件即将被销毁,但是还没有真正开始销毁,此时组件的 data、methods数据或方法 还可被调用
- Teardown…… 注销组件和事件监听
- destroyed
组件已经完成了销毁
几 个 重 要 的 钩 子 函 数 (beforeCreate, created, beforeMount, mounted,
beforeUpdate, updated)
在这几个钩子函数中, 数据模型是否加载/使用? 自定义方法是否加载/可用? html 模
板是否加载/使用? html 模板是否完成渲染?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--这里可以视为用户看到的页面-对应前面讲解的页面dom-->
<div id="app">
<span id="num">{{num}}</span>
<button @click="num++">赞!</button>
<h2>{{name}},有{{num}}次点赞</h2>
</div>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {//数据池
name: "kristina",
num: 0
},
methods: {
show() {
return this.name;
},
add() {
this.num++;
}
},
beforeCreate() {//生命周期函数-创建vue实例前
console.log("=============beforeCreate==========");
console.log("数据模型/数据池的数据是否加载/使用?[no]", this.name, " ", this.num);
//console.log("自定义方法是否加载/使用?[no]", this.show());
console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
console.log("用户页面dom是否被渲染?[no]", document.getElementById("num").innerText);
},
created() {//生命周期函数-创建vue实例
console.log("=============created==========");
console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
console.log("自定义方法是否加载/使用?[yes]", this.show());
console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
console.log("用户页面dom是否被渲染?[no]", document.getElementById("num").innerText);
//可以发出Ajax
//接收返回的数据
//再次去更新data数据池的数据
//编译内存模板结构
//.....
},
beforeMount() {//生命周期函数-挂载前
console.log("=============beforeMount==========");
console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
console.log("自定义方法是否加载/使用?[yes]", this.show());
console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
console.log("用户页面dom是否被渲染?[no]", document.getElementById("num").innerText);
},
mounted() {//生命周期函数-挂载后
console.log("=============mounted==========");
console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
console.log("自定义方法是否加载/使用?[yes]", this.show());
console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
console.log("用户页面dom是否被渲染?[yes]", document.getElementById("num").innerText);
},
beforeUpdate() {//生命周期函数-数据池数据更新前
console.log("=============beforeUpdate==========");
console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
console.log("自定义方法是否加载/使用?[yes]", this.show());
console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
console.log("用户页面dom数据是否被更新?[no]", document.getElementById("num").innerText);
//验证数据==>修正
// if(this.num < 10 ) {
// this.num = 8;
// }
},
updated() {//生命周期函数-数据池数据更新后
console.log("=============updated==========");
console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
console.log("自定义方法是否加载/使用?[yes]", this.show());
console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
console.log("用户页面dom数据是否被更新?[yes]", document.getElementById("num").innerText);
}
})
</script>
</body>
</html>
Vue2 脚手架模块化开发
为什么需要 Vue Cli 脚手架?
目前开发模式的问题
- 开发效率低
- 不够规范
- 维护和升级, 可读性比较差
Vue Cli 文档地址: https://cli.vuejs.org/zh/
- 搭建 Vue 脚手架工程,需要使用到 NPM(node package manager), npm 是随 nodejs 安装
的一款包管理工具, 类似 Maven。所以我们需要先安装 Nodejs
Vue2配置教程&IDEA配置VUE
Vue 项目结构分析
分析执行流程
整个页面渲染过程中,main.js 是中心,也是连接各个组件,路由器的关键。
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App' //完整写法是 import App from './App.vue'
import router from './router'//完整写法是 import router from './router/index.js'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app', //这里的#app 是挂到 index.html 的 <div id="app"></div>
router, //完整写法是 router: router, 第二个 router 是 import router[这里] from './router'
components: {App }, //完整写法是 components: { 'App':App } 因为名字相同可以省略 'App'
template: '<App/>' //这里的 '<App/>' 的 App 就是上面 components 引入的组件的名字
})
Element UI
Element UI的使用,需要什么模板就去官网找什么模板就可以。
ElementUI 官网:
一句话: ElementUI 是组件库,网站快速成型工具
Element UI 配置
- 安装 element-ui 组件库, cmd 下进入到项目,指令 npm i element-ui@2.12.0(这里遇到一个小坑,之前安装的是2.15版本,但是显示不了Element-UI的表格。需要卸载原来的版本,然后再下载该版本。)。
关于为什么要在项目路径下执行指令:
3. 修改项目目录下的\src\main.js, 添加如下的语句:
import ElementUI from 'element-ui
import 'element-ui/lib/theme-chalk/index.css';
// 使用ElementUI插件。
Vue.use(ElementUI);
要求效果:
Code:
<template>
<div>
<h1>{{ msg }}</h1>
<el-row>
<el-button>默认按钮</el-button>
<el-button type="primary">主要按钮</el-button>
<el-button type="success">成功按钮</el-button>
<el-button type="info">信息按钮</el-button>
<el-button type="warning">警告按钮</el-button>
<el-button type="danger">危险按钮</el-button>
</el-row>
<el-input-number v-model="num" @change="handleChange" :min="1" :max="10" label="feaf饿啊分"></el-input-number>
<table align="center">
<tr>
<td>第1行第1列</td>
<td>第1行第2列</td>
<td>第1行第3列</td>
</tr>
<tr>
<td rowspan="2">第2行第1列</td>
<td>第2行第2列</td>
<td>第2行第3列</td>
</tr>
<tr>
<td>第3行第1列</td>
<td>第3行第2列</td>
</tr>
<tr>
<td rowspan="2">第4行第1列</td>
<td>第4行第2列</td>
<td>第4行第3列</td>
</tr>
<tr>
<td>红烧肉 <img src="../assets/img.png" width="100"></td>
<td>第5行第3列</td>
</tr>
</table>
<br/>
<el-table
:data="tableData"
stripe
style="width: 80%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: "Table",
data() {
return {
msg: "Welcome to Table",
num: 1,
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
},
methods: {
handleChange(value) {
console.log(value);
}
}
}
</script>
<style scoped>
div {
width: 900px;
background-color: aliceblue;
margin: 0 auto;
}
h1 {
color: red;
}
table, tr, td {
border: 1px solid red;
//边界的宽度 width: 600px; border-collapse: collapse; //合并边界 height: 50px;
}
</style>
做出树形控件
<template>
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
</template>
<script>
export default {
data() {
return {
data: [{
label: '家用电器',
children: [{
label: '电视',
children: [{
label: '全屏电视',
},
{
label: '教育电视'
}]
},
{
label: '空调',
children: [{
label:'格力空调',
},
{
label: '美的空调',
}]
}]
}, {
label: '手机',
children: [{
label: 'iPhone',
children: [{
label: 'iphone 15',
},
{
label: 'iphone 14'
}]
},
{
label: '华为',
children: [{
label:'mate 60 pro',
},
{
label: 'P50',
}]
}]
}, {
label: '电脑',
children: [{
label: '玩家国度',
children: [{
label: 'ROG',
},
{
label: '败家之眼'
}]
},
{
label: '联想',
children: [{
label:'Y9000P',
},
{
label: 'Y7000P',
}]
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
};
},
methods: {
handleNodeClick(data) {
console.log(data);
}
}
}
</script>
<style scoped>
</style>
Axios
- axios 是独立于 vue 的一个项目,不是 Vue 的一部分
- axios 通常和 Vue 一起使用,实现 Ajax 操作
- Axios 是一个基于 promise 的 HTTP 库
- 学习文档
Axios 库文件
1、使用 axios 需要引入 axios 库文件
2、可以直接引入
3、也可以下载 axios.min.js ,在本地引入
使用方式
/*
1. axios.get() 表示发出ajax请求
2. ()中的表示请求的url
3. axios发出ajax请求的基本语法:
axios.get(url).then(箭头函数).then(箭头函数)...catch(箭头函数)
(1) 如果get请求成功就进入到第一个then
(2) 可以再在第一个then()中继续发出axios的ajax请求
(3) 如果有异常,会进入到catch
4. list()方法在生命周期函数created()中调用.*/
axios.get("url")
.then(箭头函数)
.then(箭头函数)
...
.catch(err =>{
// 处理异常
})
示例
需求: 在 Vue 项目中使用 Axios, 从服务器获取 json 数据, 显示在页面
本地资源:
展现效果:
用到了生命周期函数、axios、vue
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="script/axios.min.js"></script>
<script src="script/vue.js"></script>
</head>
<body>
<div id="app">
<h1>{{msg}}</h1>
<table border="1px" width="800px">
<tr>
<th>name</th>
<th>age</th>
</tr>
<tr v-for="monster in monsterList" align="center">
<td>{{monster.name}}</td>
<td>{{monster.age}}</td>
</tr>
</table>
</div>
<script>
new Vue({
el: "#app",
data: {
monsterList: [],
msg:"妖怪信息列表"
},
methods: {
// 定义方法
list() {
/*
1. axios.get() 表示发出ajax请求
2. ()中的表示请求的url
3. axios发出ajax请求的基本语法:
axios.get(url).then(箭头函数).then(箭头函数)...catch(箭头函数)
(1) 如果get请求成功就进入到第一个then
(2) 可以再在第一个then()中继续发出axios的ajax请求
(3) 如果有异常,会进入到catch
4. list()方法在生命周期函数created()中调用.
* 1. 使用 axios 发送 ajax 请求
* 2. 语 法 格 式 axios. 请 求 方 式 ( 请 求 路 径 ).then( 箭 头 函数).catch(箭头函数)
* 3. 请求成功,执行 then 的函数, response 就是返回的数据, 名字有程序员确定
* 4. 请求失败, 执行 catch 的函数
* 5. this.monsterList = response.data.data.items 把 返 回 的data.items 赋给 monsterList
* 6. 这里的 http://127.0.0.1:63342/axios/response.data.json 路径需要根据实际的端口和资源名来修改
*/
axios.get("http://localhost:63342/axios/data/response.data.json") // 读取本地的资源
.then((responseData) =>{ // 只有一个参数, (responseData)可以省略括号
console.log(responseData.data.data.items)
//上面显示的数据是个对象形式,比较乱.
// 可以使用JSON.stringify(json) 把json对象转成一个字符串
console.log(JSON.stringify(responseData.data.data.items))
// 将妖怪信息数组 绑定到data数据池的monsterList
this.monsterList = responseData.data.data.items;
// 可以使用return axios.get()再次发出ajax请求
// return axios.get("url"), 然后再用then写请求成功后的操作...
}).catch(err => {
console.log("异常=" + err);
})
}
},
// created()是生命周期函数,不能在methods中写, 这是自己定义的方法
// 使用生命周期函数,在方法和数据都加载好后调用list()方法
created(){
this.list()
}
})
</script>
</body>
</html>