1. Vue简介

P1 课程简介

P2 Vue技术

虚拟dom通过diff算法比较差异实现渲染复用

P3 官网指南

学习-Cookbook

提供编程技巧(让代码更优雅)

资源列表-Awesome Vue

官方推荐认可的Vue第三方库(如能用来制作一个报表)

P4 开发环境

引入Vue.js后,可以在浏览器-console中输入Vue.config查看Vue API(全局配置 )

image-20210812175148792

2. 简单例子

P5 Hello 案例

{{}}:Vue设计的插值语法(获取Vue实例-data里的值)

root容器里的代码被称为【Vue模板

模板解析流程:

  1. 先有容器,然后有实例
  2. 实例拿到对应id容器
  3. 实例解析(看有没有设计的特殊语法)
  4. 把解析完后的Dom树导出替换容器

P6 分析Hello

容器和实例是一一对应的

<div  id='root'></div>
new Vue({
	el:'#root',
	……
})
},

‘{{}}’里必须写js表达式

3. 数据绑定

P7 模板语法

插值语法:解析标签体内容

<div>{{xxx}}</div>

指令语法:解析标签属性(属性、内容、事件)V-XXX

<a v-bind :herf='xxx'>点击</a>

P8 数据绑定

v-modal只能应用在表单类元素(输入类元素)上

P9 el和data两写法

  1. el

el:‘#root’ 和v.KaTeX parse error: Expected 'EOF', got '#' at position 8: mount('#̲root')效果相同(mount是vue实例原型构造器的方法)

  1. data
  • 对象式
data:{
	name:'xxx'
}
  • 函数式(以后用组件时必须用这种,对象式会报错)
data:function(){
	return{
		name:'xxx'
	}
}
//简写成(不能写箭头函数,不然this指向windows)
data(){
    return{
        name:'xxx'
    }
}

4. 数据代理(JS知识补充)

P10 MVVM

如图所示:

image-20210816162211103

代码:Vue实例把Data和View进行连接

image-20210816162354439

data里的数据最终出现在vm上,而模板{{}}或v-xxx可以从vm中获取属性值

<h1>{{$emit}}</h1>
//$emit是vm原型链上所有的属性

P11 defineProperty

为什么console.log()里面的属性不直接显示,原因:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iWiJHTsz-1652602773252)(Images/image-20210816165528539.png)]

给对象添加属性,具体语法如图:

第一个参数是对象名,第二个参数是属性名,然后是在defineProperty对属性的内置操作方法中写表达式

第三个参数中get():有人读取属性时,放回属性值;set():有人修改属性时,用改方法设置修改值

image-20210816164846993

P12 数据代理

image-20210816165124411

P13 Vue中的数据代理

vm._data === data

data(){
	return {
		data:'xxx'
	}
}
image-20210816170935288

但为什么vm._data===data呢?这个就不细讲了,只要知道是数据劫持即可

image-20210816171447521

5. 事件绑定

P14 事件处理

''里的模板只能用vm

注:所有vm里的方法有不要写成箭头函数,不然this指向windos

如何保持事件原有参数(用关键词传参)

image-20210816173101184

注:写在methods里的方法不会做数据代理,如果写在data中会多做一次数据代理

P15 修饰符

<a href='xxx' @click.prevent='showinfo'/>

prevent会组织默认事件,如阻止a的跳转

image-20210816180149558

不常用,具体细节看视频吧

P16 键盘事件

触发分为两种:@keyup和@keydown

image-20210816190237334

有几个按键比较特殊,具体看视频

P17 事件总结

修饰符可以连写,先后同时生效

<a href='xxx'@click.prevent.stop='xxx'/>

@click='xxx' === @click='xxx($event)'

6. 计算属性

P18 姓名案例

每次data改变,都会引起vue的重新渲染

所以如果使用方法替代计算属性的话,每次渲染都会return最新值

P19 计算属性

image-20210817113457202

computed有缓存机制,相对于methods来说更高效,这也是为什么要用计算属性的原因

get()只有当初始化和依赖数据发生改变时执行

computed不会像data和methods一样,直接绑定到vm上,所以{{fullName.get()}}会报错,Vue做了内部处理,{{fullName}}能默认调用get()

vm.fullname=xxx 则会调用fullname{}里的set()

P20 简写

只需要读取时可以使用简写

image-20210817114857649

7. 监视属性

P21 天气案例

注:如果页面内容没变,vm数据变了,开发者工具不一定更新(实际上是变了)

P22 监视属性

watch语法如下:

image-20210817140457768

key为被监控dataName计算属性也能被监视,并提供一系列方法

也可以直接调用vm.$watch(),效果相同

image-20210817140642585

P23 深度监视

  • 监视多级结构的某个属性(完整写法.)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dtE6RBzD-1652602773254)(Images/image-20210817141421438.png)]

  • 监视多级结构的所有属性(设置deep值)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rS5fImuP-1652602773254)(Images/image-20210817141514247.png)]

P24 简写

和methods相同,只有"单纯"操作时,才能简写(不可添加deep等配置)

两种写法如下(和methods相似)

  • 构造
image-20210817143232238
  • 实例
image-20210817143316548

P25 对比(watch和computed)

一般来说能用computed的就用计算,不能的再用watch(因为官方也推荐计算,代码量少呀)

然后计算属性因为只依靠return返回值,所以不能进行一些异步操作(setTimeout),加了异步就return不到计算属性函数上

image-20210817145213346

详细区别如下: image-20210817144831970

8. 样式渲染

P26 Class绑定

code

<!-- 指定单个样式变量-字符 -->
<div class="basic" :class="mood">{{name}}</div> <!-- class和:class可以共存-->
<!-- 指定多个样式变量-数组 -->
<div :class="classArr">{{name}}</div>
<div :class="['atguigu1','atguigu2']">{{name}}</div> 
	<div class="atguigu1 atguigu2">{{name}}</div> 
	<!-- 同效-感觉这方式只是为了少写代码,没啥妙用 -->
<!-- 指定多个样式变量并控制是否使用-对象 -->
<div :class="classObj">{{name}}</div> 
	<div :class="{atguigu1:value}">{{name}}</div> 
	<!-- 同效-可用这个替代部分三元 -->
<script>
	const vm = new Vue({
		data:{ //这三种都可以写在!!行内-更简洁,如果样式比较多可以写在data中控制
			mood:'normal',
			classArr:['atguigu1','atguigu2'],
			classObj:{
				atguigu1:false,
				atguigu2:false,
			},
		},
	})
</script>
<style>
    .basic{
		width: 400px;
		height: 100px;
		border: 1px solid black;
	}
	.normal{
		background-color: skyblue;
	}
    .atguigu1{
		background-color: yellowgreen;
	}
	.atguigu2{
		font-size: 30px;
		text-shadow:2px 2px 10px red;
	}
</style>

p:实际上这两节的内容并不实用,因为很多情况下的业务是条件渲染样式,这里实际上是各种动态指定样式变量

old

三种写法(字符串\数组\对象)

image-20210817152830241

https://www.cnblogs.com/guangzhou11/p/11116378.html

实例博客

P27 Style绑定

code

<view  :style="{ fontSize:fs }"/> <!-- 内联写法-指定对象的属性变量-->
	<view  :style="{ fontSize:prop }"/> <!-- 同上-更简洁,不走data-->
<div class="basic" :style="styleObj">{{name}}</div> <!-- 指定对象变量-->
	<view  :style="{ fontSize:prop,color:prop2 }"/> <!-- 同上-更简洁,不走data-->
<div :style="styleArr">{{name}}</div><!--指定对象变量-使用数组 -->
	……
<script>
	const vm = new Vue({
		data:{
            fs:'xxx'
			styleObj:{
				fontSize: '40px',
				color:'red',
			},
			styleArr:[
				{
					fontSize: '40px',
					color:'blue',
				},
				{
					backgroundColor:'gray'
				}
			]
		},
	})
</script>

p:个人感觉这样写不优雅

实战

<view :style="styleObject"/>  //指定对象变量
<view  :style="{ height: meunHeight }"/> //指定对象的属性变量
computed: {
  //根据当前菜单状态动态设置菜单高度
  meunHeight() {
    let meunHeight;
    switch (this.$store.state.nowMeun) {
      case "PathSelect":
        meunHeight = "340rpx";
        break;
      case "StartNav":
        meunHeight = "126rpx";
        break;
    }
    return meunHeight; 
  },
  //根据当前菜单高度   
  styleObject() {
    let obj;
    obj = {  //这里和上面的data-styleObj差不多,只不过用computed来动态设置对象的属性
      height: `calc(100vh - ${this.meunHeight} - var(--window-bottom))`,
      fontSize: "13px",
    };
    return obj;
  },
},

old

有两种(对象和数组)

注:{}要写样式对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Stmd0S01-1652602773255)(Images/image-20210817153938296.png)]

ps:class和style总结

image-20210817153815729

P28 条件渲染

如图所示(v-show\v-if\v-else-if\template)

v-show控制的是dispaly,所以是高频率合适,这里写反

image-20210817161457236

9. 列表渲染

P29 基本列表

数组\对象

image-20210817163509454 image-20210817163542918

其他:字符串\指定次数(用的少)

image-20210817163620722 image-20210817163731913

P30 Key作用与原理

具体分析见视频

文字总结:

image-20210817165644933

ps:如果没写key,Vue会自动帮我们使用:key=‘index’(所以只要不会破坏结构,就不用写key,减少代码量hh)

P31 过滤

Key: watch:{}中可以添加immediate:true属性使组件初始化时就调用一次监听

watch:{
	keyWorud:{
		immediate:true, //初始化调用
		handler(val){
			return xxx
		}
	}
}

这里时列表过滤的最优解-computed(通过输入框搜索展示列表内容)

具体还是看视频吧

image-20210817180621340

P32 列表顺序

如图,强大的计算属性功能哈

image-20210817192617972

10. 监视原理(JS补充)

P33 更新原理

下图的修改会失效,原因是内存变量确实改了,但是vue没监听到吼

image-20210817194844396

P34 Vue监听对象

这节是对对象的监视的分析,而不是基本类型

  • 错误写法

自己尝试写一个监视,但是会报错,说栈溢出(陷入死循环了)

image-20210818143035157

原因:上图如果有人读取name,则调用get(),但是get()中return 的是data.name,读取data.name有需要get(),所以会陷入嵌套死循环

image-20210818152422971
  • 模拟Vue底层写法
  1. 现在简单重现下vue底层方法实现(使用了一个构造函数)

构造函数就是通过defineproperty属性传入参数data,’拷贝‘data中所有属性,而且修改和读取时不会发生循环

image-20210818144856717 image-20210818151017097
  1. 所以上面的构造函数实例obs,console.log出来就是一个带有data所有属性的方法实例
image-20210818151155378
  1. 准备一个vm对象 ,复制obs
image-20210818151456223 image-20210818151553674
  1. 但是data还没变,然后来个连等(这样_data、data和obs就一样了)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2egK0uLA-1652602773256)(Images/image-20210818151646108.png)]

  1. 然后再defineproperty.set(){xxx}中添加操作就可以实现监听渲染了(不会像“错误写法”那样出现死循环)

    image-20210818152003821

PS:肯定又疑惑了,为什么构造的就不会像错误的那样出现死循环呢?

image-20210818152141814

⭐️个人感觉是构造的get()读取和set()的内容不是同一个东西(地址)

这里的this指的是构造函数Obeserver(obj)地址;

obj是指传入的对象地址

image-20210818152500486

如上图是错误的,因为return 后面的内容会再次触发读取(主要就是看绿色是否是同一个对象属性)

  • Vue真实底层

我们没有做到的内容:修改更便捷(数据代理)、多层设置

1.image-202108181540559012.image-20210818154239621

P35 Vue.set()方法

常见错误

直接赋值student.sex不可行,原因如图-没有相关方法

image-20220113152959666

正文

<h2 v-if="student.sex">性别:{{student.sex}}</h2>
<h2 >姓名:{{student.name}}</h2>
	data:{
			student:{
				name:'tom', //没有sex属性
			}
	},			
    
   	methods: {
				addSex(){
					// Vue.set(this.student,'sex','男') //Vue.set和this.$set都可以
					this.$set(this.student,'sex','男')
				}
			}

官方文档

注意:对象不能是 Vue 实例,或者 Vue 实例的根数据对象-data。

补充

关于属性不存在报错问题

<h2 >性别:{{student.sex}}</h2> 
//这里不报错,因为如果属性为空的话是返回undefined,undefined在页面不显示

student:{
	name:'tom',
   	//sex:'男'
}

P36 Vue监测数据改变的原理_数组

直接修改数组不可行

如图数组里是没有set()和get()

image-20220113163530312

直接改不可行

image-20220113163818955

vue对常见的数组方法封装,实现数组监听

如下图,两个方法不相同

image-20220113163203356

使用set()也可以-但是一般都直接用方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aXxFNrTX-1652602773257)(Images/image-20220113181824064.png)]

简写

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hm2mspAM-1652602773258)(Images/image-20220113163442213.png)]

相关官方文档

P37 总结Vue监视数据

Vue监视数据的原理:

​ 1. vue会监视data中所有层次的数据。

​ 2. 如何监测对象中的数据?

​ 通过setter实现监视,且要在new Vue时就传入要监测的数据。

​ (1).对象中后追加的属性,Vue默认不做响应式处理

​ (2).如需给后添加的属性做响应式,请使用如下API:

​ Vue.set(target,propertyName/index,value) 或

​ vm.$set(target,propertyName/index,value)

​ 3. 如何监测数组中的数据

​ 通过包裹数组更新元素的方法实现,本质就是做了两件事

​ (1).调用原生对应的方法对数组进行更新

​ (2).重新解析模板,进而更新页面

​ 4.在Vue修改数组中的某个元素一定要用如下方法:

​ 1.使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()

​ 2.Vue.set() 或 vm.$set()

​ 特别注意:Vue.set() 和 vm.$set() 不能给vmvm的根数据对象 添加属性!!!

//dom
<h1>学生信息</h1>
<button @click="student.age++">年龄+1岁</button> <br/>
<button @click="addSex">添加性别属性,默认值:男</button> <br/>
<button @click="student.sex = '未知' ">修改性别</button> <br/>
<button @click="addFriend">在列表首位添加一个朋友</button> <br/>
<button @click="updateFirstFriendName">修改第一个朋友的名字为:张三</button> <br/>
<button @click="addHobby">添加一个爱好</button> <br/>
<button @click="updateHobby">修改第一个爱好为:开车</button> <br/>
<button @click="removeSmoke">过滤掉爱好中的抽烟</button> <br/>
<h3>姓名:{{student.name}}</h3>
<h3>年龄:{{student.age}}</h3>
<h3 v-if="student.sex">性别:{{student.sex}}</h3>
<h3>爱好:</h3>

//data
student:{
	name:'tom',
	age:18,
	hobby:['抽烟','喝酒','烫头'],
	friends:[
		{name:'jerry',age:35},
		{name:'tony',age:36}
	]
}

//以下就是对于监视原理这章的总结
addSex(){
	// Vue.set(this.student,'sex','男')
	this.$set(this.student,'sex','男')
},
addFriend(){
	this.student.friends.unshift({name:'jack',age:70})
},
updateFirstFriendName(){
	this.student.friends[0].name = '张三'
},
addHobby(){
	this.student.hobby.push('学习')
},
updateHobby(){
	// this.student.hobby.splice(0,1,'开车')
	// Vue.set(this.student.hobby,0,'开车')
	this.$set(this.student.hobby,0,'开车')
},
removeSmoke(){
	this.student.hobby = this.student.hobby.filter((h)=>{
		return h !== '抽烟'
	})
}

10a.表单例子

P38 收集表单数据

收集表单数据:

​ 若:,则v-model收集的是value值,用户输入的就是value值。

​ 若:,则v-model收集的是value值,且要给标签配置value

​ 若:

​ 1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)

​ 2.配置input的value属性

​ (1)v-model的初始值非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)

​ (2)v-model的初始值是数组,那么收集的的就是value组成的数

​ 备注:v-model的三个修饰符

​ lazy:失去焦点再收集数据

​ number:输入字符串转为有效的数字

​ trim:输入首尾空格过滤

<form @submit.prevent="demo"><!-- 修饰符阻止默认行为-->
	账号:<input type="text" v-model.trim="userInfo.account"> <br/><br/>
	密码:<input type="password" v-model="userInfo.password"> <br/><br/>
	年龄:<input type="number" v-model.number="userInfo.age"> <br/><br/>
    <!-- number和.number保证输入的是数值-->
	性别:
	男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
	女<input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>
	爱好:
	学习<input type="checkbox" v-model="userInfo.hobby" value="study">
	打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
	吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat">
	<br/><br/>
	所属校区
	<select v-model="userInfo.city">
		<option value="">请选择校区</option> 
		<option value="beijing">北京</option>
		<option value="shanghai">上海</option>
		<option value="shenzhen">深圳</option>
		<option value="wuhan">武汉</option>
	</select>
	<br/><br/>
	其他信息:
	<textarea v-model.lazy="userInfo.other"></textarea> <br/><br/>
	<input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="http://www.atguigu.com">《用户协议》</a>
	<button>提交</button>
</form>
    
data:{
	userInfo:{
		account:'',
		password:'',
		age:18,
		sex:'female',
		hobby:[],
		city:'beijing',
		other:'',
		agree:''
	}
},
methods: {
	demo(){
		console.log(JSON.stringify(this.userInfo)) //转换成json,发送请求
	}
}

11. 过滤器

P39 过滤器用法

如图

image-20210818163726114 image-20210818163745248 image-20210818163810815

全局(组件公用)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5C6pRPQn-1652602773258)(Images/image-20210818163835397.png)]

userInfo.other">


阅读并接受《用户协议》
提交

data:{
userInfo:{
account:‘’,
password:‘’,
age:18,
sex:‘female’,
hobby:[],
city:‘beijing’,
other:‘’,
agree:‘’
}
},
methods: {
demo(){
console.log(JSON.stringify(this.userInfo)) //转换成json,发送请求
}
}


## 11. 过滤器

### P39 过滤器用法

 如图

<img src="Images/image-20210818163726114.png" alt="image-20210818163726114" style="zoom:67%;" />

<img src="Images/image-20210818163745248.png" alt="image-20210818163745248" style="zoom:80%;" />

<img src="Images/image-20210818163810815.png" alt="image-20210818163810815" style="zoom:80%;" />

全局(组件公用)

[外链图片转存中...(img-5C6pRPQn-1652602773258)]

GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐