Vue教程(一):Vue核心
1.1 Vue简介
1.1.1 Vue是什么?
一套用于构建用户界面的渐进式JS框架。
1.1.2 谁开发的?
——尤雨溪。
- 2015-10-27 正式发布 Vue1.0.0 Evangelion(新世纪福音战士)
- 2016-10-1 正式发布 Vue 2.0.0 (工壳机动队)
- 2020-9-18 正式发布 Vue 3.0.0 (海贼王)
1.1.3 Vue的特点
- 采用
组件化模式,提高代码复用率、且让代码更好维护。 声明式编码,让编码人员无需直接操作DOM,提高开发效率。- 使用
虚拟DOM+优秀的Diff算法,尽量复用DOM节点。
1.1.4 学习Vue之前要掌握的JavaScript基础知识
- ES6语法规范
- ES6模块化
- 包管理器
- 原型、原型链
- 数组常用方法
- axios
- promise
1.1.5 Vue官网使用指南
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FomWRbNw-1689559654954)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20220818130734982.png)]](https://img-blog.csdnimg.cn/024ad4e06c814bf3aca35a5195614a96.png)
1.1.6 搭建VUE开发环境
Vue.config.productionTip = false;
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UH3cv6Sx-1689559654955)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20220818155656396.png)]](https://img-blog.csdnimg.cn/beceba6543cb42eab707f8f2f1e58b6d.png)
1.2 初始Vue
1.2.1 Hello小案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>初识vue</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!--
初识Vue:
想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象
root容器里的代码依然符合html规范,只不过混入了一些特殊的语法
root容器里的代码称为【Vue模版】
注意区分:js表达式 和 js代码(语句)
1、表达式:一个表达式会生成一个值,可以放在任何一个需要的地方:
(1).a
(2).a+b
(3).demo(1)
(4).x === y ? 'a' : 'b'
2、js代码(语句)不生成值,控制代码走向
(1). if(){}
(2). for(){}
-->
<!-- 准备一个容器 -->
<div id="root">
<h1>Hello, {{name}},{{address}},{{Date.now()}}</h1>
<button>Test</button>
</div>
<!-- <div id="root2">
<h1>Hello, {{address}}</h1>
</div> -->
<script>
// 设置为 false 以阻止 vue 在启动时生成生产提示。
Vue.config.productionTip = false;
// 创建Vue实例
new Vue({
// el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串
el: '#root',
data: {
// data用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
name: 'wang',
address: '武汉'
}
})
// new Vue({
// // el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串
// el: '#root2',
// data: {
// // data用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
// address: '武汉',
// }
// })
</script>
</body>
</html>
1.2.2 总结
- 想让Vue工作,就必须创建一个
Vue实例,且要传入一个配置对象 - root容器里的
代码依然符合html规范,只不过混入了一些特殊的语法 - root容器里的代码称为
【Vue模版】 - Vue实例和容器是
一一对应的 - 真实开发中只有一个
Vue实例,并且会配合着组件一起使用 - {{xxx}}中的xxx要写js表达式,且xxx可以
自动读取到data中的数据 - 一旦data中的数据发生改变,那么模版中用到该数据的地方也会
自动更新
1.3 模版语法
1.3.1 效果
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uQbbLFOq-1689559654955)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20220927093230720.png)]](https://img-blog.csdnimg.cn/a771844b65b8436d8868ef83bf319b7f.png)
1.3.2 总结
- Vue模版语法有两大类:
- 差值语法
- 功能:用于解析标签体内容
- 写法:{{xxx}},xxx是js表达式,且可以
直接读取到data中的所有属性
- 指令语法
- 功能:用于解析标签(包括:标签属性、标签体内容、绑定事件)
- 举例:
v-bind:href="xxx"或简写为:href="xxx",xxx同样要写js表达式,且可以直接读取到data中的所有属性。 - 备注:Vue中有很多指令,且形式都是:v-???,此处我们只是拿v-bind举个例子
- 差值语法
1.4 数据绑定
1.4.1 效果
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1UvSvbgp-1689559654956)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20220927094657446.png)]](https://img-blog.csdnimg.cn/986e8f8e81c04cf0aafc1cd4243ab65d.png)
1.4.2 单向数据绑定
v-bind
单向数据绑定:<input type="text" v-bind:value="name"/><br/>
1.4.3 双向数据绑定
v-model
双向数据绑定:<input type="text" v-model:value="name"/>
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q4nMvSSv-1689559654956)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20220927094429401.png)]](https://img-blog.csdnimg.cn/605cba0aef084c6da2a881388bb46dc2.png)
1.4.4 总结
- Vue中有2两种数据绑定的方式
- 单向绑定(
v-bind):是关于只能从data流向页面 - 双向绑定(
v-model):数据不仅能从data流向页面,还可以从页面流向data- 备注:
- 双向绑定一般都应用在表单类元素上,如input、select
- v-model:value 可以简写为v-model,因为v-model默认收集的就是value
- 备注:
- 单向绑定(
简写方式:
<!-- 简写 -->
单向数据绑定:<input type="text" :value="name"/><br/>
双向数据绑定:<input type="text" v-model="name"/>
1.5 el与data的两种写法
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DhDUVWlY-1689559654956)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20220927095642175.png)]](https://img-blog.csdnimg.cn/e6ce14d8a95d40758a7614c589624484.png)
1.5.1 el的两种写法
// el的两种写法
const v = new Vue({
// 第一种写法
el: '#root',
data:{
name: 'jack',
}
})
console.log(v)
// 等待1秒再进行绑定
setTimeout(() => {
// 第二种写法,有挂载的意思mount
v.$mount('#root')
}, 1000);
1.5.2 data的两种写法
// data的两种写法
new Vue({
el: '#root',
// data的第一种写法
// data:{
// name: 'jack'
// }
// data的第二种写法
data(){
return{
name: 'jack'
}
}
})
1.5.3 总结
- el与data的两种写法
- el的两种写法
- new Vue时候配置el属性
- 先创建Vue实例,随后再通过vm.$mount(‘#root’)指定el的值
- data的2种写法
- 对象式
- 函数式
一个重要的原则:-
由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了,因为
箭头函数没有自己的this,只能往外找,就找到了window -
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NPKso2KE-1689559654957)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20220927100929045.png)]](https://img-blog.csdnimg.cn/6dfd4c2664df429cbbc48479906ad0b4.png)
-
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-65oiPbEC-1689559654957)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20220927101020835.png)]](https://img-blog.csdnimg.cn/af7707a959004c40a2b6e0dc95cec1cf.png)
-
- el的两种写法
1.6 MVVM模型
- M:模型(Model):对应data中的数据
- V:视图(View):模版
- VM:视图模型(ViewModel):Vue实例对象
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zzLhqQNO-1689559654957)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221014081758558.png)]](https://img-blog.csdnimg.cn/9cf3a2652e2748b9ba6425eeaabbc5b6.png)
data中所有的属性,最后都出现在了vm身上。vm身上的所有属性,及vue原型上所有属性,在vue模版中都可以直接使用。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kzXPkd4p-1689559654958)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221014082646003.png)]](https://img-blog.csdnimg.cn/029a19c8660a441a9839b0da8bc68f62.png)
1.7 Object.defineProperty
是否可以枚举
**需求:**给张三添加一个属性年龄age,值是18.
Object.defineProperty(person, 'age',{
value:18
})
仔细看到,age的颜色和name、sex颜色不同。说明age是不可枚举的。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0LFA9J9I-1689559654958)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221014083410273.png)]](https://img-blog.csdnimg.cn/204fa1f7e1d84aa7bb9a6ff8ac7ff32e.png)
这里说明什么是不可枚举:
首先,我们直接给person,加上age属性,然后打印出person的key有哪些
<script type="text/javascript">
Vue.config.productionTip = false;
let person = {
name:'张三',
sex:'男',
age:18
}
//Object.defineProperty(person, 'age',{
//value:18
//})
console.log(Object.keys(person));
console.log(person);
</script>
去浏览器查看打印的结果,是可以看到age属性的。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fw9pEImq-1689559654958)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221014083933681.png)]](https://img-blog.csdnimg.cn/ed8f6e7c079c4d80ad94ebc32d112252.png)
但是,当我们通过Object.defineProperty给person添加age属性的时候,打印的时候,这里的age是无法取到的,这就是此时的age不可枚举。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zk12zUnv-1689559654958)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221014083901738.png)]](https://img-blog.csdnimg.cn/1e507ccd9adb4fb4834e30e70251b9fc.png)
但是,也可以通过设置另外一个属性,设置age可枚举,通过属性enumerable即可设置,代码如下:
Object.defineProperty(person, 'age',{
value:18,
enumerable: true, //控制属性是否可以枚举,默认值是false
})
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8aw3rZ1H-1689559654959)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221014084232227.png)]](https://img-blog.csdnimg.cn/da46fa4ba42d4bb1ae9f5a5d7fd57ff5.png)
是否可以修改
这里的writable控制属性是否可以被修改,默认值是false
Object.defineProperty(person, 'age',{
value:18,
enumerable: true,
writable: true,
})
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TnGXhj93-1689559654959)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221019082245690.png)]](https://img-blog.csdnimg.cn/8bc2bc38f1874324904ee60de163c316.png)
是否可以删除
直接写在let person里面的属性是可以直接删除的,比如name属性。
let person = {
name:'张三',
sex:'男',
// age:18
}
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YnIKbX2q-1689559654960)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221019082450019.png)]](https://img-blog.csdnimg.cn/c24397e1fca74988a8bbb76ab788d92d.png)
但是,写在defineProperty里面的属性是不能删除的,比如age属性
Object.defineProperty(person, 'age',{
value:18,
enumerable: true,
writable: true,
})
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vCNpZX7a-1689559654960)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221019082522894.png)]](https://img-blog.csdnimg.cn/62ce070097b44d08a795168fad1e71c7.png)
可以设置configurable: true这个属性,来设置可以删除某个属,可以看到删除成功
Object.defineProperty(person, 'age',{
value:18,
enumerable: true,
writable: true,
configurable: true,
})
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LUxE9GTN-1689559654960)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221019082810899.png)]](https://img-blog.csdnimg.cn/57e310591f2e45009bba026f3f1a7c1c.png)
另一个需求 get()
当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
初始代码
let number = 18;
let person = {
name:'张三',
sex:'男',
age: number,
}
我修改number的值,age也要跟着变
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JU2GtvE8-1689559654960)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221019083418087.png)]](https://img-blog.csdnimg.cn/54e8257195ac4d5ba1679e2639a74561.png)
修改代码
Object.defineProperty(person, 'age',{
// value:18,
// enumerable: true,
// writable: true,
// configurable: true,
// 当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
get(){
return number;
}
})
打印结果成功
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PzTaeC3u-1689559654961)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221019083837980.png)]](https://img-blog.csdnimg.cn/04848d10bb6446f88e9a85aab31956b1.png)
set()函数
当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
Object.defineProperty(person, 'age',{
// value:18,
// enumerable: true,
// writable: true,
// configurable: true,
// 当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
get(){
return number;
},
// 当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
set(value){
console.log('有人修改了age属性,且值是', value);
}
})
查看结果
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y7O1liQP-1689559654961)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221019084130948.png)]](https://img-blog.csdnimg.cn/72d2f91020654020811006ed3918d9d2.png)
整体输出一下:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jicEthNk-1689559654961)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221019084349106.png)]](https://img-blog.csdnimg.cn/102a84e1553c4e289e5f83ebf91b68e7.png)



















