前端技术栈学习:Vue2、Vue cli脚手架、ElementUI组件库、Axios
1 基本介绍
(1)Vue 是一个前端框架, 易于构建用户界面
(2)Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或项目整合
(3)支持和其它类库结合使用
(4)开发复杂的单页应用非常方便
(5)Vue 是 Vue.js 的简称
官网: https://cn.vuejs.org/
git 地址: https://github.com/vuejs
2 MVVM 机制示意图

解读 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上, 大 大提高开发效率
3 快速入门
官网文档:https://cn.vuejs.org/v2/guide/index.html
下载: https://cn.vuejs.org/v2/guide/installation.html

3.1 需求
- 初步体会 Vue.js 的数据绑定功能
- 体会 Vue.js 开发框架的主体结构
注意:为了让 IDEA 识别 Vue 代码,需要安装插件 Vue.js

3.2 代码实现
(1)创建新文件夹 D:\idea_java_projects\vue , 直接拖到 Idea 工具,使用 idea 打开
(2)将下载好的 vue.js 拷贝到 D:\idea_java_projects\vue\vue.js
(3)创建 D:\idea_java_projects\vue\vue_quick_start.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>vue快速入门</title>
</head>
<body>
<!--
1. div元素不是必须的,也可以是其它元素,比如span,但是约定都是将vue实例挂载到div
2. 因为div更加适合做布局
3. id 不是必须为app , 是程序员指定,一般我们就使用app
-->
<div id="app"><!--1. {{message}} : 插值表达式2. message 就是从model的data数据池来获取3. 当我们的代码执行时,会到data{} 数据池中去匹配数据, 如果匹配上, 就进行替换, 如果没有匹配上, 就输出空--><h1>欢迎你{{message}}-{{name}}</h1>
</div>
<!--引入vue.js-->
<script src="vue.js"></script>
<script>/*** 1. 创建Vue对象*/let vm = new Vue({el : "#app", // 将创建的vue实例挂载到 id=app 的div上data : { // data{}表示数据池,以k-v形式设置,根据需求设置message : "Hello-Vue",name : "小王"}})
</script>
</body>
</html>
(4)运行效果如下

3.3 注意事项和使用细节
(1)注意代码顺序,要求 div 在前,script 在后,否则无法绑定数据
(2)从案例可以体会声明式渲染:Vue.js 采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统, 做到数据和显示分离
(3)Vue 没有繁琐的 DOM 操作,如果使用 jQuery,我们需要先找到 div 节点,获取到 DOM 对象,然后进行节点操作, 显然 Vue 更加简洁
4 数据单向渲染
4.1 基本说明
(1)v-bind 指令可以完成基本数据渲染/绑定
(2)v-bind 简写形式就是一个冒号(:)
4.2 应用实例
4.2.1 需求分析
需求: 演示 v-bind 的使用, 可以绑定元素的属性
4.2.2 代码实现
(1)把准备好的 1.jpg 拷贝到 D:\idea_java_projects\vue\1.jpg
(2)创建 D:\idea_java_projects\vue\单向数据渲染.html
<!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="app"><h1>{{message}}</h1><!--1. 使用插值表达式引用 data数据池数据是在标签体内2. 如果是在标签/元素 的属性上去引用data数据池数据时,不能使用插值表达式3. 需要使用v-bind, 因为v-bind是vue来解析, 默认报红,但是不影响解析4. 如果不希望看到报红, 直接 alt+enter 引入 xmlns:v-bind--><img v-bind:src="img_src" v-bind:width="img_width"><!--v-bind 简写形式就是一个冒号(:)--><img :src="img_src" :width="img_width">
</div>
<script src="vue.js"></script>
<script>let vm = new Vue({el : "#app", // 将创建的vue实例挂载到 id=app 的div上data : { // data{}表示数据池,以k-v形式设置,根据需求设置message : "单向数据渲染测试",img_src : "1.jpg",img_width : "200px"}})
</script>
</body>
</html>
(3)效果如下

4.3 注意事项和使用细节
(1)插值表达式是用在标签体的
(2)如果给标签属性绑定值,则使用 v-bind 指令
5 数据双向绑定
5.1 基本说明
v-model 可以完成双向数据绑定
5.2 应用实例
5.2.1 需求分析
需求:在输入框中输入信息,会更新到相应绑定的位置
5.2.2 代码实现
(1)创建 D:\idea_java_projects\vue\双向数据渲染.html
<!DOCTYPE html>
<html lang="en" xmlns:v-model="http://www.w3.org/1999/xhtml">
<head><meta charset="UTF-8"><title>双向数据渲染</title>
</head>
<body>
<div id="app"><h1>{{message}}</h1><!--1. v-bind是数据单向渲染: data数据池绑定的数据变化,会影响view2. v-model="hobby.val" 是数据的双向渲染,(1)data数据池绑定的数据变化,会影响view 【底层的机制是 Data Bindings】(2)view 关联的的元素值变化, 会影响到data数据池的数据【底层机制是Dom Listeners】--><input type="text" v-model="hobby.val"><br/><br/><input type="text" :value="hobby.val"><br/><br/><p>你输入的爱好是: {{hobby.val}}</p>
</div>
<script src="vue.js"></script>
<script>let vm = new Vue({el : "#app", // 将创建的vue实例挂载到 id=app 的div上data : { // data{}表示数据池,以k-v形式设置,根据需求设置message : "输入爱好",hobby :{val : "购物"}}})
</script>
</body>
</html>
(2)完成测试

6 事件绑定
6.1 基本说明
(1)使用 v-on 进行事件处理,比如: v-on:click 表示处理鼠标点击事件,v-on:blur 表示失去焦点事件
(2)事件调用的方法定义在 vue 对象声明的 methods 节点中
(3)v-on:事件名 可以绑定指定事件
(4)官方文档:https://cn.vuejs.org/v2/guide/events.html
6.2 应用实例
6.2.1 需求分析
需求: 演示 Vue 事件绑定操作
6.2.2 代码实现
(1)创建 D:\idea_java_projects\vue\event.html
<!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"><h1>{{message}}</h1><!--1. v-on:click 表示我们要给button元素绑定一个点击的事件2. sayHi() 表示绑定的方法, 在方法池 methods{} 定义的3. 底层仍然是dom处理4. 如果方法不需要传递参数,可以省略()5. v-on:click可以简写成 @click, 但是需要浏览器支持--><button v-on:click = "sayHi()">点击输出</button><button v-on:click = "sayOk()">点击输出</button><button v-on:click = "sayHi">点击输出</button><button @click = "sayOk">点击输出</button>
</div>
<script src="vue.js"></script>
<script>// 创建的Vue实例可以不接收,也可以接收,方便我们调试信息let vm = new Vue({el : "#app",// el 接收element简写data : {message : "Vue事件处理案例"},// methods 是Vue的一个属性// 在{}中,可以写很多的方法,可以理解为方法池methods : {sayHi(){alert("hi")},sayOk(){alert("ok")}}})
</script>
</body>
</html>
6.2.3 注意事项和使用细节
(1)如果方法没有参数,可以省略()[需要浏览器支持]
(2)v-on 指令的简写形式 @ [需要浏览器支持]
7 修饰符
7.1 基本说明
(1)修饰符 (Modifiers) 是以(.)指明的后缀,指出某个指令以特殊方式绑定。
(2)例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()即阻 止事件原本的默认行为
(3)事件修饰符
- .stop 阻止事件继续传播
- .prevent 阻止标签默认行为
- .capture 使用事件捕获模式,即元素自身触发的事件先在此处处理,然后才交由内部元素进 行处理
- .self 只当在 event.target 是当前元素自身时触发处理函数
- .once 事件将只会触发一次
- .passive 告诉浏览器你不想阻止事件的默认行为
(4)键盘事件的修饰符
比如: 项目经常需要监听一些键盘事件来触发程序的执行,而 Vue 中允许在监听的时候添加键盘修饰符
<input v-on:keyup.13="submit">
绝大多数常用的按键码的别名:
.enter.tab.delete(捕获“删除”和“退格”键).esc.space.up.down.left.right
(5)v-model 的修饰符
比如: 自动过滤用户输入的首尾空格
<input v-model.trim="msg">
(6)官 方 文 档 : https://cn.vuejs.org/v2/guide/events.html#%E4%BA%8B%E4%BB%B6%E4%BF%AE%E9%A5%B0%E7%AC%A6
7.2 应用实例
需求:
(1)演示 v-on:submit.prevent 的使用, 如果没有输入名字,控制台输出 "请输入名字",否则输出 "提交表单"
(2)解惑, 为什么在开发中, 有时需要 , 让某个指令以特殊方式绑定, 比如表单提交
- 我们不希望将这个表单进行整体提交, 而是是 Ajax 的方式进行提交
- 因为表单整体提交会导致重载页面, 而 Ajax 方式可以有选择性提交数据,并且局部刷新
代码实现
(1) 创建 D:\idea_java_projects\vue\vue_modifier.html
<!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"><!--1. 修饰符用于指出一个指令应该以特殊方式绑定。2. v-on:submit.prevent的.prevent 修饰符表示阻止表单提交的默认行为--><form action="http://www.baidu.com" v-on:submit.prevent="onMySubmit">妖怪名: <input type="text" v-model="monster.name"><br/><br/><button type="submit">注册</button></form><p>服务返回的数据是{{count}}</p>
</div>
<script src="vue.js"></script>
<script>let vm = new Vue({el: '#app',data: {//数据池monster: {//monster数据(对象)的属性, 可以动态生成},count: 0},methods: {//方法池onMySubmit() {//console.log("我们自己的表单提交处理...");//"", null, undefined都是falseif(this.monster.name) {console.log("提交表单 name=", this.monster.name);//这里,程序员就可以根据自己的业务发出ajax请求到后端//得到数据后,在进行数据更新this.count = 666;} else {this.count = 0;console.log("请输入名字..");}}}})
</script>
</body>
</html>
(2)效果如下
不输入名字直接提交

输入名字再提交

8 条件渲染/控制: v-if v-show
8.1 基本说明
Vue 提供了 v-if 和 v-show 条件指令完成条件渲染/控制
(1)v-if 介绍
说明:0、null、undefined、""(空串) 、false 都认为是false
可以用 v-else-if 添加一个分支

(2)v-show
(3)官方文档:https://cn.vuejs.org/v2/guide/conditional.html
8.2 应用实例
8.2.1 需求分析
需求: 演示条件渲染使用(使用 v-if 和 v-show 实现)
8.2.2 代码实现
(1)创建 D:\idea_java_projects\vue\v_if.html ,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">是否同意条款<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>
(2)创建 D:\idea_java_projects\vue\v_show.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">是否同意条款<h1 v-show="sel">你同意条款</h1><h1 v-show="!sel">你不同意条款</h1>
</div>
<script src="vue.js"></script>
<script>let vm = new Vue({el : "#app",data : {sel : false}})
</script>
</body>
</html>
(3)实现效果如下

8.3 v-if 和 v-show 区别
(1)v-if 会确保在切换过程中,条件块内的事件监听器和子组件销毁和重建
(2)v-show 机制相对简单, 不管初始条件是什么,元素总是会被渲染,并且只是对 CSS 进行切换
(3)使用建议:如果要频繁地切换,建议使用 v-show ;如果运行时条件很少改变,使用 v-if 较好
9 列表渲染: v-for
9.1 基本说明
Vue 提供了 v-for 列表循环指令,官方文档:https://cn.vuejs.org/v2/guide/list.html
(1)对数组进行遍历
可以用第二个参数作为索引


(2) 用 v-for 来遍历一个对象的 property


还可以用第三个参数作为索引
9.2 应用实例
9.2.1 需求分析
需求: 演示列表渲染使用(v-for)
9.2.2 代码实现
(1) 创建 D:\idea_java_projects\vue\v_for.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>v-for 列表渲染</title>
</head>
<body>
<div id="app"><!--基本语法:<li v-for="变量 in 数字">{{ 变量 }}</li>--><h1>简单的列表渲染</h1><ul><li v-for="i in 3">{{i}}</li></ul><!--基本语法:<li v-for="(变量, 索引) in 值">{{ 变量 }} - {{ 索引 }}</li>--><h1>简单的列表渲染-带索引</h1><ul><li v-for="(i,index) in 3">{{i}}-{{index}}</li></ul><h1>遍历数据列表</h1><!-- 语法:<tr v-for="对象 in 对象数组"><td>{{对象的属性}}</td></tr>--><table width="400px" border="1px"><tr v-for="(monster,index) in monsters"><td>{{index}}</td><td>{{monster.id}}</td><td>{{monster.name}}</td><td>{{monster.age}}</td></tr></table>
</div>
<script src="vue.js"></script>
<script>new Vue({el: '#app',data: { //数据池monsters: [{id: 1, name: '牛魔王', age: 800},{id: 2, name: '黑山老妖', age: 900},{id: 3, name: '红孩儿', age: 200}]}})
</script>
</body>
</html>
(2)效果

10 组件化编程
10.1 基本说明
1. 在大型应用开发的时候,页面可以划分成很多部分,往往不同的页面,也会有相同的部 分。例如可能会有相同的头部导航。
2. 但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发(如图)

3. 上图解读
- 组件(Component) 是 Vue.js 最强大的功能之一
- 组件也是一个Vue实例,也包括∶ data、methods、生命周期函数等
- 组件渲染需要 html模板,所以增加了template 属性,值就是 HTML 模板
- 对于全局组件,任何vue 实例都可以直接在 HTML 中通过组件名称来使用该组件
- data 是一个函数,不再是一个对象, 这样每次引用组件都是独立的对象/数据
10.2 应用实例
10.2.1 需求分析
如下, 点击一个按钮, 可以显示点击的次数
现在需求是,有多个按钮,都要进行点击统计

10.2.2 实现方式1-普通方式
(1)创建 D:\idea_java_projects\vue\组件化编程1.html
<!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="click1()">点击次数= {{count}} 次【非组件化方式】</button><br/><br/><!--需求是,有多个按钮,都要进行点击统计1. 其实三个按钮界面其实一样, 但是目前我们都重新写了一次, 复用性低2. 点击各个按钮的业务都是对次数+1, 因此业务处理类似,但是也都重新写了一个方法, 复用性低3. 解决===> 组件化编程--><button v-on:click="click2()">点击次数= {{count2}} 次【非组件化方式】</button><br/><br/><button v-on:click="click3()">点击次数= {{count3}} 次【非组件化方式】</button><br/>
</div>
<script src="vue.js"></script>
<script>new Vue({el: "#app",data: {//data数据池count: 10,count2: 10,count3: 10},methods: {//methods属性, 可以定义相应的方法click1() {this.count++;},click2() {this.count2++;},click3() {this.count3++;}}})
</script>
</body>
</html>
(2)测试

10.2.3 实现方式 2-全局组件方式
(1) 创建 D:\idea_java_projects\vue\组件化编程2.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>组件化编程-全局组件</title>
</head>
<body>
<div id="app"><h1>组件化编程-全局组件</h1><!--使用全局组件--><counter></counter><br/><counter></counter><counter></counter><counter></counter><counter></counter>
</div><div id="app2"><h1>组件化编程-全局组件-app2</h1><!--使用全局组件--><counter></counter><counter></counter>
</div>
<script src="vue.js"></script>
<script>//1、定义一个全局组件, 名称为 counter//2. {} 表示就是我们的组件相关的内容//3. template 指定该组件的界面, 因为会引用到数据池的数据,所以需要是模板字符串//4. 要把组件视为一个Vue实例,也有自己的数据池和methods//5. 对于组件,我们的数据池的数据,是使用函数/方法返回[目的是为了保证每个组件的数据是独立], 不能使用原来的方式//6. 这时我们达到目前,界面通过template实现共享,业务处理也复用//7. 全局组件是属于所有vue实例,因此,可以在所有的vue实例使用Vue.component("counter", {template: `<button v-on:click="click()">点击次数= {{count}} 次【全局组件化】</button>`,data() {//这里需要注意,和原来的方式不一样!!!!return {count: 10}},methods: {click() {this.count++;}}})//创建Vue实例,必须有let vm = new Vue({el: "#app"//Vue实例的挂载点})let vm2 = new Vue({el: "#app2"//Vue实例的挂载点})</script>
</body>
</html>
(2)测试

10.2.4 实现方式 3-局部组件方式
(1) 创建 D:\idea_java_projects\vue\组件化编程3.html
说明:必须在vue实例中引入局部组件,才能使用该局部组件
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>组件化编程-局部组件</title>
</head>
<body>
<div id="app"><h1>组件化编程-局部组件</h1><!--使用局部组件 ,该组件是从挂载到app的vue中来的--><my_counter></my_counter><br/><my_counter></my_counter><br/><my_counter></my_counter><br/>
</div><div id="app2"><h1>组件化编程-局部组件-app2</h1><!--使用局部组件 --><wwj_counter></wwj_counter><br/><wwj_counter></wwj_counter><br/>
</div>
<script src="vue.js"></script>
<script>//定义一个组件, 组件的名称为 buttonCounter//扩展//1. 可以把常用的组件,定义在某个commons.js中 export//2. 如果某个页面需要使用, 直接importconst buttonCounter = {template: `<button v-on:click="click()">点击次数= {{count}} 次【局部组件化】</button>`,data() {//这里需要注意,和原来的方式不一样!!!!return {count: 10}},methods: {click() {this.count++;}}}//创建Vue实例,必须有let vm = new Vue({el: "#app",//Vue实例的挂载点components: { //引入/注册某个组件, 此时my_counter就是一个组件, 是一个局部组件,他的使用范围在当前vuemy_counter: buttonCounter}})let vm2 = new Vue({el: "#app2",//Vue实例的挂载点components :{//引入/注册组件buttonCounterwwj_counter: buttonCounter}})</script>
</body>
</html>
(2)测试

10.2.5 注意事项和使用细节
(1)如果方法体, 只有简单的语句,比如 count++, 那么可以进行简写, 在组件化编程1.html 演示, 比如
<!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="count++">点击次数= {{count}} 次</button><br/><br/><button v-on:click="count++">点击次数= {{count2}} 次</button><br/><br/></div>
<script src="vue.js"></script>
<script>new Vue({el: "#app",data: {//data数据池count: 10,},})
</script>
</body>
</html>
(2)局部组件定义需要放置在 new Vue() 前,否则组件注册会失败
10.3 组件化小结
- 组件也是一个 Vue 实例,因此它的定义是也存在∶ data、methods、生命周期函数等
- data 是一个函数,不再是一个对象, 这样每次引用组件都是独立的对象/数据
- 组件渲染需要 html 模板,所以增加了 template 属性,值就是 HTML 模板
11 生命周期和监听函数(钩子函数)
11.1 基本说明
(1)Vue 实例有一个完整的生命周期,也就是说从开始创建、初始化数据、编译模板、挂载 DOM、渲染-更新-渲染、卸载等一系列过程,我们称为 Vue 实例的生命周期
(2)钩子函数(监听函数): Vue 实例在完整的生命周期过程中(比如设置数据监听、编译模 板、将实例挂载到 DOM 、在数据变化时更新 DOM 等), 也会运行叫做生命周期钩子的函数
(3)钩子函数的 作用就是在某个阶段, 给程序员一个做某些处理的机会
11.2 Vue生命周期示意图

上图解读
(1) new Vue():new 了一个 Vue 的实例对象,此时就会进入组件的创建过程。
(2) Init Events & Lifecycle:初始化组件的事件和生命周期函数
(3) beforeCreate:组件创建之后遇到的第一个生命周期函数,这个阶段 data 和 methods 以及 dom 结构都未被初始化,也就是获取不到 data 的值,不能调用 methods 中的函数
(4) Init injections & reactivity:这个阶段中, 正在初始化 data 和 methods 中的方法
(5) created:这个阶段组件的 data 和 methods 中的方法已初始化结束,可以访问,但是 dom 结构未 初始化,页面未渲染
- 特别说明:在这个阶段,经常会发起 Ajax 请求,从后端获取到最新数据
(6) 编译模板结构(在内存)
(7) beforeMount:当模板在内存中编译完成,此时内存中的模板结构还未渲染至页面上,看不到真实的数据
(8) Create vm.$el and replace ‘el’ with it:这一步,在把内存中渲染好的模板结构替换至真实的 dom 结构也就是页面上
(9) mounted:此时,页面渲染好,用户看到的是真实的页面数据, 生命周期创建阶段完毕,进入到了运行中的阶段
(10) 生命周期运行中
10.1 beforeUpdate:当执行此函数,数据池的数据是新的,但是页面是旧的
10.2 Virtual DOM re-render and patch:根据最新的 data 数据,重新渲染内存中的模板结构,并把渲染好的模板结构,替换至页面 上
10.3 updated:页面已经完成了更新,此时,data 数据和页面的数据都是新的
(11) beforeDestroy:当执行此函数时,组件即将被销毁,但是还没有真正开始销毁,此时组件的 data、methods数据或方法 还可被调用
(12) Teardown……:注销组件和事件监听
11.3 应用实例
11.3.1 需求分析
需求:展示 VUE 实例生命周期和 钩子函数/监听函数/生命周期函数 执行时机
(1)重点研究几个重要的钩子函数 (beforeCreate, created, beforeMount, mounted, beforeUpdate, updated)
(2)验证在这几个钩子函数中, 数据模型/数据池是否加载/使用? 自定义方法是否加载/可用? html 模板是否加载/使用? html 模板是否完成渲染?
11.3.2 代码实现
(1)创建 D:\idea_java_projects\vue\Vue\生命周期和钩子函数.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div id="app"><span id="num">{{num}}</span><button @click="num++">赞</button><h2>{{name}},有{{num}}个人点赞</h2>
</div>
<script src="vue.js"></script>
<script>new Vue({el:"#app",data : {//数据池name : "小王",num : 0},methods: {show(){return this.name;},add(){this.num++;}},beforeCreate(){//生命周期函数-创建vue实例前调用console.log("=============beforeCreate==========");console.log("数据模型/数据池的数据是否加载/使用?[no]", this.name, " ", this.num);// 会报错:Error in beforeCreate hook: "TypeError: this.show is not a function"//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>
(2)测试

12 Vue2 脚手架模块化开发
12.1 为什么需要 Vue Cli 脚手架?
目前开发模式的问题
(1)开发效率低
(2)不够规范
(3)维护和升级, 可读性比较差
12.2 脚手架模块化开发--快速入门
12.2.1 需求分析
需求: 演示使用 Vue 脚手架进行模块化开发, 输入不同的 url, 切换不同页面.
Vue Cli 文档地址: https://cli.vuejs.org/zh/
12.2.2 环境配置,搭建项目
(1)搭建 Vue 脚手架工程,需要使用到 NPM(node package manager), npm 是随 nodejs 安装 的一款包管理工具, 类似 Maven。所以需要先安装 Nodejs
(2)为了更好兼容 ,这里安装 node.js10.16.3(因为这里 只是演示 Vue 脚手架工程),后面进行 Vue3 的脚手架工程搭建, 再对 Node 升级
(3)如果以前安装过 node.js , 为防止版本冲突,先卸载之, 如果你没安装 nodejs, 就不用管
卸载步骤如下
打开控制面板,点击卸载程序

搜索node,点击卸载 (这里需要一段时间,耐心等待)
再次测试,卸载成功

(4)下载 node.js10.16.3 地址: https://nodejs.org/en/blog/release/v10.16.3/
往下翻找到电脑相应的配置进行下载
(5)下载完成之后 , 双击进行安装,直接下一步即可(可根据自己来选择安装路径,路径不要有空格、中文、特殊字符)
(6)验证是否安装成功, 如果看不到, 退出 cmd, 重新开一个窗口测试即可

(7)先删除以前的 cli 版本<不论是之前未下载或没有下载>(cmd中执行下面命令)
npm uninstall vue-cli -g

(8)安装淘宝镜像-cnpm
npm install -g cnpm@7.1.1 --registry=https://registry.npm.taobao.org

说明npm 和 cnpm 的区别
- 两者之间只是 node 中包管理器的不同, 都可以使用
- npm 是 node 官方的包管理器。cnpm 是个中国版的 npm,是淘宝定制的 cnpm (gzip 压缩支持) 命令行工具代替默认的 npm
- 如果因为网络原因无法使用 npm 下载,那 cnpm 这个就派上用场了
- 小结: npm 和 cnpm 只是下载的地址不同,npm 是从国外下载东西,cnpm 是从国内 下载东西
安装成功之后需要给cnpm配置环境变量,找到cnpm.cmd,我的是在D:\software\nodejs\node_cache
接下来,配置环境变量:
1. 右键点击计算机图标,选择“属性”。
2. 在弹出的窗口中,点击“高级系统设置”。
3. 在“系统属性”对话框中,转到“高级”选项卡,然后点击“环境变量”按钮。
4. 在“环境变量”窗口中,找到“系统变量”部分的“Path”变量,然后点击“编辑”。
5. 在“编辑环境变量”对话框中,点击“新建”并添加`cnpm.cmd`所在目录的完整路径,例如`D:\software\nodejs\node_cache`。
6. 记得在每个路径之间用英文分号(`;`)隔开。如果你已经有其他路径,确保在新路径前加上分号。
7. 点击“确定”关闭所有对话框,完成环境变量的修改。
(9) 安装 webpack 和 webpack-cli
npm install webpack@4.41.2 webpack-cli -D

(10)安装vue脚手架
cnpm install -g @vue/cli@4.0.3

(11)确认 Vue-Cli 版本
vue -V

(12)创建目录 vue_project, 并 cmd 到该目录
(13)使用 webpack 创建 vue 脚手架项目 (如果出现了 downloading template....,
//安装一个全球插件
npm install -g @vue/cli-initvue init webpack vue_project_start


(14)运行我们的vue项目
cd vue_project_start
npm run dev

(15)浏览器: http://localhost:8080
12.2.3 使用IDEA 打开项目,运行项目
(1)使用 crtl+c 终止项目

(2)将 Vue 脚手架项目,直接拖到 IDEA,就可以打开
(3)配置 NPM





12.3 Vue 项目结构分析

12.4 Vue 请求页面执行流程
当我们输入 http://localhost:8080 , 你看到这个页面时怎么来的,这里涉及到如下文件
执行流程如下

12.5 路由切换-应用实例
(1)创建 vue_project\vue_project_quickstart\src\components\Yss.vue
<template>
<div><h1>{{mes}}</h1><table><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行第2列</td><td>第3行第3列</td></tr><tr><td rowspan="2">第4行第1列</td><td>第4行第2列</td><td>第4行第3列</td></tr><tr><td>红烧肉<img src="@/assets/2.png"></td><td>第5行第3列</td></tr></table>
</div>
</template><script>
export default {name: "Yss",data(){return {mes : "Welcome to Yss"}}
}
</script><!--css样式-->
<style scoped>
div {width: 900px;background-color: aliceblue;margin: 0 auto;
}
table,tr,td{border: 1px solid red;/*width: 600px;*/border-collapse:collapse;/*height: 50px;*/
}
table {margin: 0 auto;width: 600px;height: 380px;
}
h1 {color: red;
}
</style>
(2) 在 vue_project\vue_project_quickstart\src\router\index.js 添加路由
{path: '/yss',name: 'Yss',component : Yss
}
(3)把 vue_project\vue_project_quickstart\src\App.vue 默认logo注销

(4) 浏览器 http://localhost:8080/#/yss
13 ElementUI 使用
13.1 基本说明
(1)ElementUI 官网: https://element.eleme.cn/#/zh-CN
(2)一句话: ElementUI 是组件库,网站快速成型工具
(3)vue2 使用的是 ElementUI 组件库,vue3 使用的是 ElementPlus 组件库
13.2 应用实例-Vue 项目引入 ElementUI
13.2.1 需求分析
在 Vue2 项目中, 使用 ElementUI 组件
13.2.2 代码演示
(1)安装 element-ui 组件库, cmd 下进入到项目,指令 npm i element-ui@2.12.0 , 这里指定了版本

(2)修改 vue_project\vue_project_quickstart\src\main.js ,引入elementUI组件库
// 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.vue'
import router from './router/index.js'
// 引入elementUI组件库
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';//使用ElementUI插件
Vue.use(ElementUI);Vue.config.productionTip = false/* eslint-disable no-new */
new Vue({el: '#app',router: router, //指定routercomponents: {'App': App},template: '<App/>'
})
(3)修 改 vue_project\vue_project_quickstart\src\components\Yss.vue , 引 入 element-ui 按钮组件, 从文档拷贝即可


(3)页面效果
14 Axios
14.1 基本说明
(1)axios 是独立于 vue 的一个项目,不是 Vue 的一部分
(2)axios 通常和 Vue 一起使用,实现 Ajax 操作
(3)Axios 是一个基于 promise 的 HTTP 库
(4)学习文档:https://javasoho.com/axios/
14.2 Axios 库文件
(1)使用 axios 需要引入 axios 库文件
(2)可以直接引入
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
(3)也可以下载 axios.min.js ,在本地引入

下载方式:在页面 https://unpkg.com/axios/dist/axios.min.js 中右键另存为即可
14.3 Axios 应用实例
14.3.1 需求分析
14.3.2 代码实现
(1) 新建一个 javascript 项目

(2)在该项目下创建 data/response_data.json
{"success": true,"message": "成功","data": {"items": [{"name": "牛魔王","age": 800},{"name": "红孩儿","age": 500},{"name": "蜈蚣精","age": 200}]}
}
(3)将下面两个js文件复制到项目中(已附在文章顶部)
(4)创建 axios_quick_start.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>axios的应用实例</title>
</head>
<body>
<!--页面视图-->
<div id="app"><h1>{{msg}}</h1><table border="1" width="200"><tr><td>名字</td><td>年龄</td></tr><tr v-for="monster in monsterList"><td>{{monster.name}}</td><td>{{monster.age}}</td></tr></table>
</div>
<script src="vue.js"></script>
<script src="axios.min.js"></script>
<script>new Vue({el: "#app",data: {msg: "妖怪信息列表",monsterList: [] //表示妖怪的信息数组},methods: {//自定义方法list() {//发送ajax请求,获取数据 axios/*1. axios.get() 表示发出ajax请求2. http://localhost:63342/axios/data/response.data.json 表示请求的url要根据实际情况来填写3. axios发出ajax请求的基本语法axios.get(url).then(箭头函数).then(箭头函数)...catch(箭头函数)(1) 如果get请求成功就进入到第一个then()(2) 可以在第一个then()中继续发出axios的ajax请求(3) 如果有异常, 会进入到 catch(箭头函数)4. list在vue生命周期函数created() 中调用*/axios.get("http://localhost:63342/axios/data/response_data.json").then(responseData => {console.log("responseData= ", responseData)//使用JSON.stringify(json) 把json对象转成一个字符串,方便观察console.log("responseData= ", JSON.stringify(responseData));// console.log("responseData.data= ", responseData.data)// console.log("responseData.data.data= ", responseData.data.data)console.log("responseData.data.data.item= ", responseData.data.data.items)//将妖怪列表数组信息, 绑定到 data数据池的 monsterListthis.monsterList = responseData.data.data.items;}).catch(err => {console.log("异常=", err)})}},created() {this.list();}})
</script>
</body>
</html>
(5)测试
14.4 注意事项和细节说明
(1)将 JSON 对象转成字符串 JSON.stringify(response)
(2)格式化输出 JSON 字符串,方便观察分析。到 https://www.json.cn/
(3)发生多次 ajax 请求的方式和 promise 相同
相关文章:
前端技术栈学习:Vue2、Vue cli脚手架、ElementUI组件库、Axios
1 基本介绍 (1)Vue 是一个前端框架, 易于构建用户界面 (2)Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或项目整合 (3)支持和其它类库结合使用 (4&#…...
pycharm中取消Typo:In word ‘xxx‘提示(绿色波浪线提示)的方法
#事故现场 使用pycharm写python代码出现绿色波浪线的提示,并提示Typo:In word ‘xxx’,这是pycharm检测到单词拼写错误、不规范; 那如何取消这种提示呢? #解决方法 方法一:Settings → Editor → Inspections → P…...
js中的浅拷贝和深拷贝
浅拷贝Shallow Copy 浅拷贝只复制对象的顶层属性及其引用,而不复制这些引用所指向的对象。如果原始对象中的某个属性是一个对象或数组,那么浅拷贝后的对象将包含对这个内部对象或数组的引用,而不是这个对象或数组的一个新副本。 let obj1 …...
【Linux】常用基本命令
wget网址用于直接从网上下载某个文件到服务器,当然也可以直接从网上先把东西下到本地然后用filezilla这个软件来传输到服务器上。 当遇到不会的命令时候,可以使用man “不会的命令”来查看这个命令的详细信息。比如我想要看看ls这个命令的详细用法&…...
uniapp——上传图片获取到file对象而非临时地址——基础积累
最近在看uniapp的代码,遇到一个需求,就是要实现上传图片的功能 uniapp 官网地址:https://uniapp.dcloud.net.cn/ 上传图片有对应的API: uni.chooseImage方法:https://uniapp.dcloud.net.cn/api/media/image.html#choo…...
vue3 antdv RadioButton默认值选择问题处理
1、先上官方文档: Ant Design Vue — An enterprise-class UI components based on Ant Design and Vue.js 官方代码: <template><div><div><a-radio-group v-model:value"value1"><a-radio-button value"a…...
最佳实践,一款基于 Flutter 的桌面应用
前言 这篇文章介绍作为一名后端开发人员,快速的入门前端或者客户端一些相关的技术的心得。先来说说为什么作为一名后端开发人员也需要学习一些前端或者客户端相关的技术。通常来说,深耕一个领域没有错,因为社会常常就是这样分工的࿰…...
python第一个多进程爬虫
使用 multiprocessing 模块实现多进程爬取股票网址买卖数据的基本思路是: 定义爬虫函数,用于从一个或多个股票网址上抓取数据。创建多个进程,每个进程执行爬虫函数,可能针对不同的股票或不同的网页。使用 multiprocessing.Queue …...
在Ubuntu 18.04上安装和配置Ansible的方法
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 配置管理系统旨在简化对大量服务器的控制,适用于管理员和运维团队。它们允许您从一个中央位置以自动化的方式控制许多…...
【详细教程】如何使用YOLOv10进行图片与视频的目标检测
《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…...
LLM大语言模型-AI大模型全面介绍
简介: 大语言模型(LLM)是深度学习的产物,包含数十亿至数万亿参数,通过大规模数据训练,能处理多种自然语言任务。LLM基于Transformer架构,利用多头注意力机制处理长距离依赖,经过预训…...
瑜伽馆管理系统的设计
管理员账户功能包括:系统首页,个人中心,管理员管理,教练管理,用户管理,瑜伽管理,套餐管理,体测报告管理,基础数据管理 前台账户功能包括:系统首页࿰…...
JAVA【案例5-2】模拟默认密码自动生成
【模拟默认密码自动生成】 1、案例描述 本案例要求编写一个程序,模拟默认密码的自动生成策略,手动输入用户名,根据用户名自动生成默认密码。在生成密码时,将用户名反转即为默认的密码。 2、案例目的 (1)…...
小区业主管理系统
摘 要 随着城市化进程的加速和人口的不断增加,小区的数量也在不断增加。小区作为城市居民居住的主要场所,其管理工作也变得越来越重要。传统的小区业主管理方式存在诸多问题,如信息传递不畅、业务处理效率低下等。因此,开发一个高…...
vncsever ,window 远程ubuntu远程界面安装方式,VNC Viewer安装教程+ linux配置server 操作
linux 端安装 # 安装VNC 服务器软件 sudo apt install autocutsel # 剪切黏贴操作支持的包 sudo apt-get install tightvncserver # 安装的是 VNC 服务器软件,用于远程桌面访问 # 安装Xfce桌面环境 sudo apt-get install xfce4 xfce4-goodies #安装的是 XFCE 桌…...
java spring boot 单/多文件上传/下载
文章目录 使用版本文件上传服务端客户端(前端)方式一方式二 文件下载服务端客户端(前端) 代码仓库地址 使用版本 后端 spring-boot 3.3.0jdk17 前端 vue “^3.3.11”vite “^5.0.8”axios “^1.7.2” 文件上传 上传文件比较…...
C语言的内存函数
1. memcpy使⽤和模拟实现 1 void * memcpy ( void * destination, const void * source, size_t num ); • 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。 • 这个函数在遇到 \0 的时候并不会停下来。 • 如果source和destination有任…...
【网络通信】计算机网络安全技术总结
一、概述 在数字时代的浪潮下,计算机网络安全技术已成为保护数据完整性和安全性的基石。这项技术不仅是计算机科学的重要组成部分,也是应对各种网络威胁和挑战的关键手段。 二、核心技术和应用 2.1 加密技术 作为网络安全技术的核心,加密技…...
Redis-实战篇-什么是缓存-添加redis缓存
文章目录 1、什么是缓存2、添加商户缓存3、前端接口4、ShopController.java5、ShopServiceImpl.java6、RedisConstants.java7、查看Redis Desktop Manager 1、什么是缓存 缓存就是数据交换的缓冲区(称为Cache),是存贮数据的临时地方ÿ…...
《妃梦千年》第十一章:再遇故人
第十一章:再遇故人 宫中的局势暂时平静下来,但林清婉知道,危险随时可能卷土重来。她必须不断提升自己,才能在这复杂的环境中保护自己和皇上。一天,林清婉正在寝宫中读书,忽然收到了一封信。信中只有短短几…...
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
