一、简介
易学易用
- 基于标准HTML、CSS和JavaScript构建,提供容易上手的API和一流的文档
性能出色
- 经过编译器优化、完全响应式的渲染系统、几乎不需要手动优化
灵活多变
- 丰富的、可渐进式集成的生态系统、可以根据应用规模再库和框架间切换自如
Vue是一个框架,也是一个生态、其功能覆盖了大部分前端开发常见的需求,但Web世界是十分多样化的,不同的开发者在Web上构建的东西可能在形式和规模上会有很大的不同。考虑到这一点,Vue的设计非常注重灵活性和“可以被逐步集成”这个特点,根据你的需求场景,你可以用不同的方式使用Vue
二、开发者
尤雨溪
2013年 受到Angular框架的启发,尤雨溪开发出了一款轻量框架 --- Seed。同年12月,Seed更名未Vue,版本号 0.6.0
2014年 Vue正式对外发布,版本号 0.8.0 Taylor otwell 在 Twitter 上发表动态,说自己正在学习Vue
2015年 10月27日,正式发布Vue1.0.0 Evangelion (新世纪福音战士)
2016年 10月1日,正式发布Vue2.0.0 Ghost in the Shell (攻壳机动队)
2020年 9月18日,正式发布Vue3.0.0 One Piece(海贼王)
后起之秀,生态完善,已然成为国内前端工程师必备技能
三、Vue特点
- 采用组件化模式,提供代码复用率,且让代码更好维护
- 声明式编码,让编码人员无需直接操作Dom,提供开发效率
- 使用虚拟Dom+优秀的Diff算法,尽量复用Dom节点
四、学习Vue之前要掌握的JavaScript基础知识
- ES6语法规范
- ES6模块化
- 包管理器
- 原型、原型链
- 数组常用方法
- axios
- promise
- ....
五、搭建Vue开发环境
1、直接使用<script>引用
直接下载并用<script>标签引用,Vue会被注册为一个全局变量
<!-- 引用Vue -->
<script src="../js/vue.js" ></script>
1.1、测试Vue
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 引用Vue -->
<script src="../js/vue.js" ></script>
</head>
<body>
</body>
</html>
运行页面后会遇到以下俩问题:
问题1:下载Vue DevTools扩展以获得更好的开发体验:
-
- 需要下载一个插件 vue_dev_tools.crx
-
- 进入GitHub
-
- 下载 插件
直接下载本地的 插件 -
问题2:正在以开发模式运行Vue。在部署生产时,一定要打开生产模式
-
- 在部署的时候需要更换一下Vue的文件,vue.min.js
- 通过代码进行关闭
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 引用Vue -->
<script src="../js/vue.js" ></script>
</head>
<body>
<script>
Vue.config.productionTip = false;
</script>
</body>
</html>
2、Vue应用
小案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 引用Vue -->
<script type="text/javascript" src="../js/vue.js" ></script>
</head>
<body>
<!--准备一个容器-->
<div id="main">
<h1>Hello {{name}}</h1>
</div>
<script>
//阻止,Vue启动时提示的产生
Vue.config.productionTip = false;
//创建Vue实例
new Vue({
el: '#main', //el用于指定当前Vue的实例为哪个容器,值通常为CSS的选择器字符串
//通常用户存储数据,数据供el所指定的容器使用
data: {
name: '筱筱'
}
})
</script>
</body>
</html>
初识Vue:
- 想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象
- main容器里面的代码依然符合html规范,只不过时混入了一些特许的Vue语法
- main容器里的代码被称为[Vue模板]
- Vue实例和容器是一一对应的
- 真实开发中只有一个Vue实例,并且会配合着组件一起使用
- {{xxx}}中的xxx要写JS表达式,且xxx可以自动读取到data中的所有属性
- 一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新
六、Vue核心
1、模板语法
Vue模板语法有两大类:
- 插值语法:
-
- 功能:用于解析标签体内容
- 写法:{{xxx}},xxx是JS表达式,且可以直接读取到data中的所有属性
- 指令语法:
-
- 功能:用于解析标签(包括:标签属性、标签体内容、绑定事件....)
- 举例:v-bind:href="xxx" 或 简写为 :href="xxx",xxx同样要写JS表达式,且可以直接读取到data中所有的属性
- 备注:Vue中有很多指令,形式都是: v-????。当前知识拿v-bind举例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板语法</title>
<!-- 引用Vue -->
<script type="text/javascript" src="../js/vue.js" ></script>
</head>
<body>
<div id="main">
<h1>插值语法</h1>
<h3>你好,{{name}}</h3>
<h1>指令语法</h1>
<a href="http://www.netbox.net.cn/">点我去学习1</a>
<br>
<a v-bind:href="url">点我去学习2</a>
</div>
<script>
//阻止,Vue启动时提示的产生
Vue.config.productionTip = false;
//创建Vue实例
new Vue({
el: '#main', //el用于指定当前Vue的实例为哪个容器,值通常为CSS的选择器字符串
//通常用户存储数据,数据供el所指定的容器使用
data: {
name: '筱筱',
url: "https://www.baidu.com/"
}
})
</script>
</body>
</html>
2、数据绑定
Vue中有两种数据绑定方式
- 单向绑定(v-bind):数据只能从data流向页面
- 双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data
-
- 双向绑定一般都应用在表单类元素上
- v-model:value可以简写为 v-model,因为v-model默认收集的就是value值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数据绑定</title>
<!-- 引用Vue -->
<script type="text/javascript" src="../js/vue.js" ></script>
</head>
<body>
<div id="main">
<form action="">
<label>单向数据绑定:</label>
<input type="text" v-bind:value="name">
<br>
<label>双向数据绑定:</label>
<input type="text" v-model:value="name">
</form>
</div>
<script>
//阻止,Vue启动时提示的产生
Vue.config.productionTip = false;
//创建Vue实例
new Vue({
el: '#main', //el用于指定当前Vue的实例为哪个容器,值通常为CSS的选择器字符串
//通常用户存储数据,数据供el所指定的容器使用
data: {
name: '筱筱',
}
})
</script>
</body>
</html>
3、el与data两种写法
- el有两种写法
-
- new Vue()时候配置el属性
- 先创建Vue实例,然后再通过v.$mount('#main')执行el的值
- data有两种写法
-
- 对象式
- 函数式
- 如何体现:目前使用哪种写法都可以,后续到组件时,data必须使用函数式,否则会报错
- 重要性原则
-
- 由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再式Vue实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>el与data两种写法</title>
<!-- 引用Vue -->
<script type="text/javascript" src="../js/vue.js" ></script>
</head>
<body>
<div id="main">
<h3>你好,{{name}}</h3>
</div>
<script>
//阻止,Vue启动时提示的产生
Vue.config.productionTip = false;
//创建Vue实例
const v = new Vue({
//方式一
// el: '#main', //el用于指定当前Vue的实例为哪个容器,值通常为CSS的选择器字符串
//通常用户存储数据,数据供el所指定的容器使用
//方式一:对象式
// data: {
// name: '筱筱',
// }
//方式二:函数式
data(){
console.log("data:",this)
return{
name : '筱筱'
}
}
})
//方式二
//mount 挂载 --- 可灵活性运行
v.$mount('#main')
console.log("V",v)
</script>
</body>
</html>
4、MVVM模型
- M:模型(Model)对应data中的而数据
- V:视图(View)模板
- VM:视图模型(ViewModel)Vue实例对象
data中所有的属性,最后都出现在 vm 身上
vm身上的所有属性,及 Vue原型上所有属性,在Vue模板都可以直接使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MVVM模型</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="main">
<h1>{{name}}</h1>
<h1>{{address}}</h1>
<h1>{{$options}}</h1>
<h1>{{_c}}</h1>
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: '#main',
data:{
name : '肖生客',
address : '厦门市'
}
})
console.info(vm)
</script>
</body>
</html>
5、数据代理
5.1、Object.defineproperty
为Vue中的数据代理操作理解,铺垫JS的数据代理操作模式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
let number = 18
let person = {
name: '张三',
sex: '男',
}
//该方式创建之后不可枚举 - 不可遍历 - 不可修改 - 不可删除
Object.defineProperty(person,'age',{
// value: 10,
//控制属性是否可以枚举,默认 false
// enumerable: true,
// //可以被修改 - 默认 false
// writable: true,
// //属性可被删除 - 默认 false
// configurable: true
//当读取person的age属性时,get函数(getter)就会被调用,返回值是 age 的值
get(){
console.info("读取age属性")
return number
},
//当修改person的age属性时,set函数(setter)就会被调用,会收到修改的具体值
set(value){
console.info("操作set属性")
number = value
}
})
// 不可被枚举 - 则遍历不到
console.info(Object.keys(person))
//按下标形式迭代数据
for (let index in person) {
console.info(person[index])
}
console.info(person)
</script>
</body>
</html>
5.2、数据代理
JS简单的数据代理操作方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数据代理</title>
</head>
<body>
<script>
//数据代理:通过一个对象代理对另一个对象中的属性操作 读/写
let obj1 = {x:100}
let obj2 = {y:200}
//通过obj2读写obj1中的数据
Object.defineProperty(obj2,'x',{
get(){
//读取时 - 将obj1的x传递到obj2
return obj1.x
},
set(value){
//在obj2修改x值时 - 将obj1的x一起修改
obj1.x = value
}
})
</script>
</body>
</html>
直接输出obj2对象,发现,除了原本定义的y属性之外,还存在,x属性,和还存在 对 x 属性的 get() 和 set()
通过 访问obj2 对象的x属性,其实也就是调用了 obj2 内部的 get x 方法,然后返回了 obj1 对象的x属性。 也就是最终是去访问 obj1 对象中的 x 属性,打印出来是 100
修改 obj2 对象上的 x 属性值之后,再度输出 obj1 ,发现obj1 内部的 x 属性,也变成了修改后的值,这是因为,通过 obj2 修改 x 属性时,其实是调用了 set x 方法,最终是将 新的值,赋值给了 obj1 中的 x 属性
5.3、Vue中的数据代理
- Vue中的数据代理
-
- 通过vm对象来代理data对象中的属性操作
- Vue中的数据代理的好处
-
- 更加方便的操作data中的数据
- 基本原理
-
- 通过Object.defineProperty()把data对象中所有属性添加到vm上
- 为每一个添加到vm上的属性,都指定一个 getter/setter
- 在 getter/setter 内部去操作,data中对应的属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue中的数据代理</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="main">
<h2>{{name}}</h2>
<h2>{{address}}</h2>
</div>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: '#main',
data:{
name: '网盒教育',
address: '厦门市'
}
})
</script>
</body>
</html>
Getter进行访问
Setter修改
5.3.1、Setter怎么样去修改
在上面那一段应该时通过 vm.name = 'netbox' 修改属性值之后,调用了vm实例中关于name属性的set()函数,从而发生页面的变化,但是需要怎么验证 data.name 也发生了变化
直接在控制台输出 data.name 是无效的
因为data根本就不是全局随时都能用的变量,它只是Vue配置对象中的一个属性 -- 所以是找不到的
但配置好的data不可能说没有交给 vm 就丢弃,肯定会放在 vm 中的某个属性
data的数据交给vm后,放在_data中
怎么验证 这两个是否是属于同一个 data
经过以下代码的测试,发现两个是同一个
6、事件处理
6.1、如何使用事件
事件操作方式 ----- 错误演示
<div id="main">
<h1>{{name}}</h1>
<button v-on:click="showInfo">点我提示信息1</button>
</div>
<script src="../js/vue.js"></script>
<script>
function showInfo(){
console.info("你好")
}
const vm = new Vue({
el: "#main",
data:{
name : '肖生客'
}
})
</script>
上面操作时 -- 运行后则提示 -- 有一个属性或方法 "showInfo" 没有定义
- 在Vue实例中 - 在页面模板[main]中只能引用Vue中的实例,所以引用不到Vue实例外面的东西
下面改正写法 👇
<div id="main">
<h1>{{name}}</h1>
<!--<button v-on:click="showInfo">点我提示信息1</button>-->
<button @click="showInfo">点我提示信息1</button>
</div>
<script src="../js/vue.js"></script>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: "#main",
data:{
name : '肖生客'
},
methods:{
showInfo(){
// console.info(event.target.innerText)
console.info(this)
}
}
})
</script>
6.2、事件传参
传递参数主要有三种情况
- 无参方法
- 有参方法、
- 即需要参数,也需要浏览器产生的event事件
无参方法实现时,可以在调用方法时加入小括号,也可以不加小括号;
当方法有参数时,需要在调用方法时传入参数,当不写参数时默认为undefined。不写小括号,默认将浏览器产生的event事件传给方法;
当方法即需要参数,又需要event事件时,必须使用$event才可以返回事件; 当使用event时或者不写时返回undefined;
当方法中不填写任何值时,参数与evnet事件均为undefined; 当不填写小括号时,默认将event事件传入方法
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: "#main",
data:{
name : '肖生客'
},
methods:{
//写了 a b c d 四个参数
showInfo(a,b,c,d){
console.info(this)
console.log(a,b,c,d)
}
}
})
</script>
这时候在页面中显示 -- a[是有参数],b c d[中都是] undefined , 在前面中提示 - PointerEvent[指针事件] - 点击之后产生的事件对象 - 在原生JS中也是一样 event (不理解event - 可以补补原生JS)
event是默认第一个参数
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: "#main",
data:{
name : '肖生客'
},
methods:{
// 如果使用这种方式写函数 --- 则会变成 Window 对象 - 不再是 Vue 实例
// showInfo:(event)=>{
// console.info(this)
// //拿到事件的目标
// console.log(event.target.innerText)
// }
showInfo(event){
console.info(this)
//拿到事件的目标
console.log(event.target.innerText)
}
}
})
</script>
传递参数
在点击 按钮的时候传入一个id
<div id="main">
<h1>{{name}}</h1>
<!--<button v-on:click="showInfo">点我提示信息1</button>-->
<button @click="showInfo1">点我提示信息1</button>
<button @click="showInfo2(10)">点我提示信息2</button>
</div>
<script src="../js/vue.js"></script>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: "#main",
data:{
name : '肖生客'
},
methods:{
showInfo1(event){
console.info(this)
//拿到事件的目标
console.log(event.target.innerText)
},
showInfo2(number,a,b,c){
console.info(this)
//拿到事件的目标
console.info(number,a,b,c)
}
}
})
</script>
在于我们手动传递参数之后-会发生一个事件就是 event 不见了
避免于event会消失 --- 则可以在传递参数的时候可以手动加上 $event
<button @click="showInfo2($event,10)">点我提示信息2</button>
showInfo2(number,a){
console.info(this)
//拿到事件的目标
console.info(number,a)
}
事件的基本使用
- 使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名
- 事件的回调需要配置在methods对象中,最终会在vm上
- methods中配置的函数,不要用箭头函数!否则this就不是vm了
- methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象
- @click="demo" 和 @click="demo($event)"效果一致,但后者可以传参
<div id="main">
<h1>{{name}}</h1>
<!-- <button v-on:click="showInfo">点我提示信息1</button>-->
<button @click="showInfo1">点我提示信息1(不传参)</button>
<button @click="showInfo2(10,$event)">点我提示信息2(传参)</button>
</div>
<script src="../js/vue.js"></script>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: "#main",
data:{
name : '肖生客'
},
methods:{
showInfo1(event){
console.info(this)
//拿到事件的目标
console.log(event.target.innerText)
},
showInfo2(number,a){
console.info(this)
//拿到事件的目标
console.info(number,a)
}
}
})
</script>
注意:methods里面的函数不可直接写在 data 里面 -- 因为该函数只是在事件触发的时候进行操作-并不需要进行数据代理操作