尚硅谷Vue2-3(张天禹老师) 学习笔记

这里写目录标题

  • (一) 基本模块
    • 01基础模板语法
      • 1.1插值语法 -- 解析标签体里的内容
      • 1.2指令语法 -- 解析标签 数据绑定 条件渲染
        • 1.2.1 **`v-bind:xxx`**
        • 1.2.2 **`v-model:xxx `**
        • 1.2.3 **`v-on:xxx`**
        • 1.2.4**事件的修饰符:**
        • 1.2.5**键盘事件:**
        • 1.2.6 **v-if/v-else-if**
        • 1.2.7 **v-show**
        • 1.2.8 **v-for**
        • 1.2.9 其他不常用的内置指令
        • 1.2.10 自定义指令
      • 1.3Vue实例里的配置项
        • 1.3.1 **el *[element(元素)]***
        • 1.3.2 **data**
        • 1.3.3 **methods**
        • 1.3.4 **computed**
        • 1.3.5 **watch**
        • 1.3.6 directives
        • 1.3.7 mounted
    • 02MVVM模型
    • ==03数据代理==
    • 04监视数据原理
    • ==05Vue的生命周期==
  • (二)组件化模块
    • 01 组件基本使用
    • ==02关于VueComponent:==
    • ==03对象原型==
    • 04render()函数
  • (二)脚手架
    • 01 文件目录结构
    • 02 vue.config.js配置文件
    • 03 ref属性
    • 04 props配置项
    • 05 mixin(混入)
    • 06 插件
    • 05 scoped样式
    • 06 总结TodoList案例
    • 07 webStorage
    • 08 组件的自定义事件
    • 09 全局事件总线(GlobalEventBus)
    • 10 消息订阅与发布(pubsub)
    • 11 nextTick
    • 12 Vue封装的过度与动画
  • (三)vue脚手架配置代理
      • 01 方法一
      • 02 方法二
    • 03 插槽
  • (四)Vuex
      • 1.概念
      • 2.何时使用?
      • 3.搭建vuex环境
      • 4.基本使用
      • 5. getters的使用
      • 6.四个map方法的使用
      • 7.模块化+命名空间
  • (五)路由
      • 1.基本使用
      • 2.几个注意点
      • 3.多级路由(多级路由)
      • 4.路由的query参数
      • 5.命名路由
      • 6.路由的params参数
      • 7.路由的props配置
      • 8.``````的replace属性
      • 9.编程式路由导航
      • 10.缓存路由组件
      • 11.两个新的生命周期钩子
      • 12.==路由守卫==
      • 13.路由器的两种工作模式
  • (六) Vue3 新特性
    • 一、创建Vue3.0工程
      • 1.使用 vue-cli 创建
      • 2.使用 vite 创建
    • 二、常用 Composition API
      • 1.拉开序幕的setup
      • 2.ref函数
      • 3.reactive函数
      • ==4.Vue3.0中的响应式原理==
        • 1. vue2.x的响应式
        • 2. Vue3.0的响应式
      • 5.reactive对比ref
      • 6.==setup的两个注意点==
      • ==7.计算属性与监视==
        • 1.computed函数
        • 2.watch函数
        • 3.watchEffect函数
      • 8.生命周期
      • 9.自定义hook函数
      • 10.toRef
    • 三、其它 Composition API
      • 1.shallowReactive 与 shallowRef
      • 2.readonly 与 shallowReadonly
      • 3.toRaw 与 markRaw
      • 4.customRef
      • 5.provide 与 inject
      • 6.响应式数据的判断
    • 四、Composition API 的优势
      • 1.Options API 存在的问题
      • 2.Composition API 的优势
    • 五、新的组件
      • 1.Fragment
      • 2.Teleport
      • 3.Suspense
    • 六、其他
      • 1.全局API的转移
      • 2.其他改变
    • 六、其他
      • 1.全局API的转移
      • 2.其他改变

(一) 基本模块

01基础模板语法

1.1插值语法 – 解析标签体里的内容

data -> {{}} 里可以写js表达式,或者js语句 : 通过{{}}在标签体里插入data里面的数据

  <div id="root">{{}}div> //{{}}:插值语法 - vue模板
  <script>
    // 创建Vue实例
    const x = new Vue({
    //配置对象
    	// el: element(元素)  -> (挂载)用于指定当前Vue实例为那个容器服务,值一般为css选择器的字符串
      el: '#root',
        //data 中用于存放数据,数据供el所指定的容器去使用,值普通用法可以写成对象
      data: {
      	name:'尚硅谷'
      }
    })
  script>

1.2指令语法 – 解析标签 数据绑定 条件渲染

1.2.1 v-bind:xxx

简写 -> : xxx 一般用于解析标签属性,经过解析后 值也要写成js表达式,

v-bind:为单向数据绑定 ,数据只能从data流向页面

  <div :id="root">{{school.age}}div> // : 指令语法 - v-bind简写
  <script>
    const x = new Vue({
      el: '#root',
      //对象式
      data: {
      	name:'尚硅谷',
        school: {  //可以分为多个层级
            age: 12
        }
      //函数式
      data() {
      	console.log(this) //this指向Vue实例
      	return{}
      	}
      }
    })
  script>

v-bind:动态绑定样式

1.2.2 v-model:xxx

为双向数据绑定,数据可以在页面与data中双向流动,但是一般用于表单类元素上(如:inport, select等)

  • 在获取表单数据时, v-model会获取value值

    对于一般的文本框, 则输入的内容就是value的值

    对于单选 则要设置要获取的value值

    对于多选框 设置要获取的value后还要把v-model绑定的数据写成数组的形式

  • 修饰符

    v-model.number 使输入的数据类型转换成 Number类型

    v-model.lazy 时输入的数据在失去焦点后, 才会被收集

    v-model.trim 去掉前后的空格

1.2.3 v-on:xxx

简写 -> @xxx 用于绑定事件, 事件的回调要配置在methods中最终会在Vue实例(vm)上,存放在data里的数据才会有数据劫持数据代理 ,@click=‘showInfo($event)’ 使用$占位符,可以传递even参数**

  <div id="root">
    <h1>{{name}}h1>
    <button @click="showInfo">button>
    <h1>{{address}}h1>
  div>
  <script>
    const vm = new Vue({
      el: '#root',
      data: {
        name: '尚硅谷',
        address: '北京' 
      },
      methods: {
        click() {
          console.log('事件被点击');
        }
      }
    })
  script>

1.2.4事件的修饰符:

Vue中的事件修饰符:

1.prevent:阻止默认事件(常用);

2.stop:阻止事件冒泡(常用);

3.once:事件只触发一次(常用)

4.capture:使用事件的捕获模式,在事件捕获阶段进行处理;

5.self:只有event.target是当前操作的元素时才触发事件;

6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;

在绑定事件的后面添加

点我提示信息

修饰符可以连用

1.2.5键盘事件:

1.Vue中常用的按键别名:

​ 回车 => enter

​ 删除 => delete (捕获“删除”和“退格”键)

​ 退出 => esc

​ 空格 => space

​ 换行 => tab (特殊,必须配合keydown去使用)

​ 上 => up

​ 下 => down

​ 左 => left

​ 右 => right

2.系统修饰键(用法特殊):ctrl、alt、shift、meta

​ (1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。

​ (2).配合keydown使用:正常触发事件。

4.也可以使用 keyCode去指定具体的按键 编码(不推荐,以后可能会移除)

5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名

Vue.config.keyCodes.huiche = 13 //定义了一个别名按键

1.2.6 v-if/v-else-if

写法: v-if=‘表达试’ , 功能与js中的一样, 适用于切换频率比较低的场景, 不展示的DOM元素会直接别移除, 且与v-else-if 结合使用时中间不能添加其他元素, 否则结构会被打断

1.2.7 v-show

写法: v-show=‘表达式’, 适用于切换频率比较低的场景, 不展示的DOM元素会不会被移出,而是使用样式进行隐藏,

vue3中v-if 比 v-show 的优先级要高, 但使用v-if时, 元素可能会获取不到, 而使用v-show时则一定会获取到

1.2.8 v-for

v-for用于展示列表数据

语法: v-for=“(item, index) in xxx “ :key=”yyy”

可以遍历: 数组, 对象, 字符串, 指定遍历次数

  • v-for中key值得作用

    b站尚硅谷Vue3 看视频

1.2.9 其他不常用的内置指令

  • v-text v-html

与差值语法类似,但 v-text不能解析 标签, v-html可以解析 结构标签转成字符串, 但会造成xss(跨域脚本攻击)漏洞

  • v-cloak

为使用该指令的标签 提供一个遮罩, 在Vue实例创建完成,并接管容器后, 会删除v-cloak

使用css的display:none属性, 配合v-cloak解决网速过慢时页面展示出 {{xxx}} 的问题, 防止页面闪烁

  • v-once v-pre

v-once: 所在节点模板只 动态渲染 一次,然后视为静态渲染, 可以优化性能,

v-pre: 跳过所在节点的编译过程, 可用于不使用插值语法,指令语法 的节点, 会加快编译

1.2.10 自定义指令

见1.3.6

1.3Vue实例里的配置项

1.3.1 el [element(元素)]

el:'xxx' 用于挂载当前vue实例指定的容器,值一般为css的选择器字符串,

本质是调用了vue实例里的$mount属性

const vm = new Vue({
  el:'#root'
})
vm.$mount('root')

1.3.2 data

data 用于定义属性(属性名+属性值)

const vm = new Vue({
  el:'#root',
  //对象方法,一般用法
  data: {
      name: '张三'
  },
  //函数方法,用于组件,使函数的this指向Vue实例
  data() {
      name: '张三'
  }
})

1.3.3 methods

methods 方法,主要用于定义 绑定事件的 方法

<div id="root">
    <h1>{{name}}</h1>
    <button @click="showInfo"></button>
    <h1>{{address}}</h1>
  </div>
  <script>
    const vm = new Vue({
      el: '#root',
      data: {
        name: '尚硅谷',
        address: '北京' 
      },
      methods: {  //定义click方法
        click() {
          console.log('事件被点击');
        }
      }
    })
  </script>

methods定义的方法也可以在插值语法{{}},中使用 当data里的数据发生改变则vue会对模板进行重新解析,当解析到定义的函数时,进行调用

1.3.4 computed

computed 计算属性:

​ 1.定义:要用的属性不存在,要通过已有属性计算得来。

​ 2.原理:底层借助了Objcet.defineproperty方法提供的getter和setter。

​ 3.get函数什么时候执行?

​ (1).初次读取时会执行一次。

​ (2).当依赖的数据发生改变时会被再次调用。

​ 4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。

​ 5.备注:

​ 1.计算属性最终会出现在vm上,直接读取使用即可。

​ 2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。

​ 3.注意: computed里不能写异步任务

1.3.5 watch

监视属性watch:

immediate:true 在初始化时就进行调用

handler(新值,旧值){ }

​ 1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作

​ 2.监视的属性必须存在,才能进行监视!!

​ 3.监视的两种写法:

​ (1).new Vue时传入watch配置

​ (2).通过vm.$watch监视

​ 4.deep:true 开启深度监视, 要写成完整形式

1.3.6 directives

  • 用于自定义指令
	<div id="root"> <h2>放大10倍后的n值是:<span v-xxx="n"></span> </h2> </div>

new Vue({
    el:'#root',
	data:{
		name:'尚硅谷',
		n:1
    },
		//定义全局指令  yyy是对象形式, 如果配置函数形式的全局,则使用回调函数
		 Vue.directive('yyy',{  //注意在定义全局时, 是directive 不是 directives
			//指令与元素成功绑定时(一上来)
			bind(element,binding){
				element.value = binding.value
			},
			//指令所在元素被插入页面时
			inserted(element,binding){
				element.focus()
			},
			//指令所在的模板被重新解析时
			update(element,binding){
				element.value = binding.value
			}
		}) 
	directives: {
    //xxx函数合适会被调用? 1,指令与元素绑定成功时  2,指令所在的模板被重新解析时
        //函数形式, 适合简单的操作
        xxx(element, binding) { //element:绑定v-xxx所在的元素(span)       binnding:绑定v-xxx所在的值(n) 	console.log(this) // 此处的this是指向window
        },
        //对象形式, 适合一些细节上的操作
        yyy: {
        }
    }
})

(1).局部指令:

new Vue ({ directives:{指令名:配置对象} })

new Vue ({ directives{指令名:回调函数} )}

(2).全局指令:

Vue.directive(指令名,配置对象) 或 Vue.directive(指令名,回调函数)

1.3.7 mounted

Vue完成模板的解析并把初始的, 真实DOM元素放入页面后(挂载完毕)调用mounted(回调函数)

02MVVM模型

  • 模板(view)通过 --> Vue实例对象 --> 监听对应data中的数据(model)

  • data中的数据(model)通过 --> Vue实例对象 --> 绑定模板(view)

  1. data中的所有属性,最后都会出现在vm身上
  2. vm身上所有的数据, 及Vue原型身上所有的属性, 在Vue模板中都可以直接使用
尚硅谷Vue2-3(张天禹老师) 学习笔记_第1张图片 尚硅谷Vue2-3(张天禹老师) 学习笔记_第2张图片

03数据代理

	<script type="text/javascript" >
			let number = 18
			let person = {
				name:'张三',
				sex:'男',
			}
			Object.defineProperty(person,'age',{  // 第二个参数,表示要读/写第一个参数的那个属性
				// value:18,
				// enumerable:true, //控制属性是否可以枚举,默认值是false
				// writable:true, //控制属性是否可以被修改,默认值是false
				// configurable:true //控制属性是否可以被删除,默认值是false
				//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
				get(){
					console.log('有人读取age属性了')
					return number
				},
				//当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
				set(value){  //参数value 就是收到的修改的值
					console.log('有人修改了age属性,且值是',value)
					number = value
				}
			})
			// console.log(Object.keys(person))
			console.log(person)
		</script>

数据代理 – 通过一个对象代理对另一个对象中属性的操作(读/写)

		<script type="text/javascript" >
			let obj = {x:100}
			let obj2 = {y:200}
			Object.defineProperty(obj2,'x',{
				get(){
					return obj.x
				},
				set(value){
					obj.x = value
				}
			})
		</script>

使用数据代理可以 通过obj2.x来操作obj.x的值得变化

尚硅谷Vue2-3(张天禹老师) 学习笔记_第3张图片

通过vm对象来代理data对象中的属性操作(读/写),更方便的data中的数据,通Object.defineProperty()把data对象中所有属性添加到vm上, 并为每个添加上的属性都指定一个 getter/setter 来操作(读/写)data中的对应属性 如果不做数据处理 则 在使用插值语法 插入data中的数据时 要这样{{ _data.name }} {{ _data.adderss }}插入

04监视数据原理

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.如何监测数组中的数据?03

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

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

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

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

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

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

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

05Vue的生命周期

生命周期:

​ 1.又名:生命周期回调函数、生命周期函数、生命周期钩子

​ 2.是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。

​ 3.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。

​ 4.生命周期函数中的this指向是vm 或 组件实例对象。

尚硅谷Vue2-3(张天禹老师) 学习笔记_第4张图片

常用的生命周期钩子:

​ 1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。

​ 2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。

关于销毁Vue实例

​ 1.销毁后借助Vue开发者工具看不到任何信息。

​ 2.销毁后自定义事件会失效,但原生DOM事件依然有效。

​ 3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。

(二)组件化模块

01 组件基本使用

定义: 实现应用中局部功能 代码 和资源的 集合

Vue中使用组件的三大步骤:

​ 一、定义组件(创建组件)

​ 二、注册组件

​ 三、使用组件(写组件标签)

一、如何定义一个组件?

​ 使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;

​ 区别如下:

​ 1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。

​ 2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系(this指向)。

​ 备注:使用template可以配置组件结构。

二、如何注册组件?

​ 1.局部注册:靠new Vue的时候传入components选项

​ 2.全局注册:靠Vue.component(‘组件名’,组件)

三、编写组件标签:


		
//全局组件标签

02关于VueComponent:

​ 1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。

2.我们只需要写,Vue解析时会帮我们创建(new 了一个)school组件的实例对象,即Vue帮我们执行的:new VueComponent(options), 当然你也可以自己new一个。

3.特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!

​ 4.关于this指向:

​ (1).组件配置中:

​ data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。

​ (2).new Vue(options)配置中:

​ data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。

03对象原型

Vue构造函数的属性中存在一个prototype属性, 值为一个对象, this指向他的 原型对象. 这个指向也叫作做 显式原型链. 当new一个Vue的实例对象时,他的属性中存在一个__proto__属性, 值为一个对象, this也指向Vue原型对象, 这个指向也叫作,隐式原型链. 而Vue的原型对象属性里也会在一个__proto__属性, this指向Object的原型对象, 他的属性中也存在一个__proto__属性, this指向为null

VueComponent构造函数的属性中存在一个prototype属性, 值为一个对象, this指向他的 原型对象. 这个指向也叫作做 显式原型链. 当编写一个组件标签时(或者new一个VueComponent的实例对象)时,他的属性中存在一个__proto__属性, 值为一个对象, this也指向VueComponent原型对象, 这个指向也叫作,隐式原型链. 而VueComponent的原型对象属性里也会在一个__proto__属性, (原本的this指向应该指向Object的原型对象, ), 但是在Vue中, Vue把这条隐式原型链, 指向了Vue的原型对象, 即:

VueComponent.prototype.__proto__ === Vue.prototype , 从而使组件实例对象可以访问到Vue原型上的属性和 方法

尚硅谷Vue2-3(张天禹老师) 学习笔记_第5张图片

04render()函数

关于不同版本的Vue:

1.vue.js与vue.runtime.xxx.js的区别:

​ (1).vue.js是完整版的Vue,包含:核心功能+模板解析器。

​ (2).vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。

2.因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用 render函数接收到的 ceateElement函数去指定具体内容。

new Vue({
	el:'#app',
	//render函数完成了这个功能:将App组件放入容器中
  render: h => h(App),
	// render:q=> q('h1','你好啊')
	// template:`

你好啊

`,
// components:{App}, })

(二)脚手架

01 文件目录结构

├── node_modules 
├── public
│   ├── favicon.ico: 页签图标
│   └── index.html: 主页面
├── src
│   ├── assets: 存放静态资源
│   │   └── logo.png
│   │── component: 存放组件
│   │   └── HelloWorld.vue
│   │── App.vue: 汇总所有组件
│   │── main.js: 入口文件
├── .gitignore: git版本管制忽略的配置
├── babel.config.js: babel的配置文件
├── package.json: 应用包配置文件 
├── README.md: 应用描述文件
├── package-lock.json:包版本控制文件

02 vue.config.js配置文件

  1. 使用vue inspect > output.js可以查看到Vue脚手架的默认配置。
  2. 使用vue.config.js可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh

03 ref属性

  1. 被用来给元素或子组件注册引用信息(id的替代者)
  2. 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
  3. 使用方式:
    1. 打标识:

      .....

    2. 获取:this.$refs.xxx

04 props配置项

  1. 功能:让组件接收外部传过来的数据

  2. 传递数据:父组件 ===> 子组件

  3. 接收数据:

    1. 第一种方式(只接收):props:['name']

    2. 第二种方式(限制类型):props:{name:String}

    3. 第三种方式(限制类型、限制必要性、指定默认值):

      props:{
      	name:{
      	type:String, //类型
      	required:true, //必要性
      	default:'老王' //默认值
      	}
      }
      

    备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。

05 mixin(混入)

  1. 功能:可以把多个组件共用的配置提取成一个混入对象

  2. 使用方式:

    第一步定义混合:

    {
        data(){....},
        methods:{....}
        ....
    }
    

    第二步使用混入:

    ​ 全局混入:Vue.mixin(xxx)
    ​ 局部混入:mixins:['xxx']

06 插件

  1. 功能:用于增强Vue

  2. 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。

  3. 定义插件:

    对象.install = function (Vue, options) {
        // 1. 添加全局过滤器
        Vue.filter(....)
        // 2. 添加全局指令
        Vue.directive(....)
        // 3. 配置全局混入(合)
        Vue.mixin(....)
        // 4. 添加实例方法
        Vue.prototype.$myMethod = function () {...}
        Vue.prototype.$myProperty = xxxx
    }
    
  4. 使用插件:Vue.use()

05 scoped样式

  1. 作用:让样式在局部生效,防止冲突。
  2. 写法: