共计 17201 个字符,预计需要花费 44 分钟才能阅读完成。
Vue3 疾速上手
提醒:Vue 尚硅谷笔记整顿
一、应用 vue-cli 创立 Vue3.0 工程(js 版)
官网文档:https://cli.vuejs.org/zh/guide/creating-a-project.html#vue-create
例如:随着人工智能的一直倒退,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的根底内容。
## 查看 @vue/cli 版本,确保 @vue/cli 版本在 4.5.0 以上
vue --version
## 装置或者降级你的 @vue/cli
npm install -g @vue/cli
## 创立
vue create vue_test
## 启动
cd vue_test
npm run serve
二、罕用 Composition API
1. setup
了解:
Vue3.0 中一个新的配置项,值为一个函数。setup 是所有 Composition API(组合 API)“表演的舞台”。组件中所用到的:数据、办法等等,均要配置在 setup 中。
- setup 函数的两种返回值:
- 若返回一个对象,则对象中的属性、办法, 在模板中均能够间接应用。(重点关注!)
-
若返回一个渲染函数:则能够自定义渲染内容。(理解)
- 留神点:
-
尽量不要与 Vue2.x 配置混用
- Vue2.x 配置
(data、methos、computed...)
中能够拜访到setup
中的属性、办法。 - 但在
setup
中不能拜访到 Vue2.x 配置(data、methos、computed...)
。 - 如果有重名,
setup
优先。
- Vue2.x 配置
-
setup 不能是一个
async
函数,因为返回值不再是return
的对象, 而是promise
, 模板看不到return
对象中的属性。(前期也能够返回一个Promise
实例,但须要Suspense
和异步组件的配合)<template> <h1> 一个人的信息 </h1> <h2> 姓名:{{name}}</h2> <h2> 年龄:{{age}}</h2> <button @click="sayHello"> 谈话(Vue3 所配置的——sayHello)</button> </template> <script> export default { name: 'App', // 此处只是测试一下 setup,临时不思考响应式的问题。setup(){ // 数据 let name = '张三' let age = 18 let a = 200 // 办法 function sayHello(){alert(` 我叫 ${name},我 ${age}岁了,你好啊!`) } // 返回一个对象(罕用)return { name, age, sayHello, } } } </script>
1.1 setup 的两个留神点
- setup 执行的机会
-
在
beforeCreate
之前执行一次,this
是undefined
。- setup 的参数
-
props
:值为对象,蕴含:组件内部传递过去,且组件外部申明接管了的属性。attrs
: 值为对象,蕴含:组件内部传递过去,但没有在 props 配置中申明的属性, 相当于this.$attrs
。slots
: 收到的插槽内容, 相当于 this.$slots。emit
: 散发自定义事件的函数, 相当于 this.$emit。
context
:上下文对象
2. ref 函数
1、作用: 定义一个响应式的数据
2、语法: const xxx = ref(initValue)
- 创立一个蕴含响应式数据的援用对象(reference 对象,简称 ref 对象)。
- JS 中操作数据:
xxx.value
- 模板中读取数据: 不须要
.value
,间接:<div>{{xxx}}</div>
3、备注:
- 接管的数据能够是:根本类型、也能够是对象类型。
- 根本类型的数据:响应式仍然是靠
Object.defineProperty()
的get
与set
实现的。
4、vue3 如何通过 ref 属性获取元素
<template>
<div ref='box'>I am DIV</div>
</template>
<script>
import {ref,onMounted}
export default{setup(){let box = ref(null);
onMounted(()=>{console.log(box.value)
});
return {box}
}
}
</script>
5、Vue3 父组件调用子组件的办法
// 父组件
<template>
<div>
父页面
<son-com ref="sonRef"/>
<button @click="handleClick">test</button>
</div>
</template>
<script>
import {
defineComponent,
ref,
} from 'vue';
export default defineComponent({setup(){const sonRef = ref(null);
const handleClick = () => {sonRef.value.song();
}
return {sonRef, handleClick,}
}
})
</script>
// 子组件
<template>
<div>
子页面
</div>
</template>
<script>
import {defineComponent} from 'vue';
export default defineComponent({setup(){const song = () => alert('hello world');
return {song, // 别忘记 return}
}
})
</script>
<template>
<h1> 一个人的信息 </h1>
<h2> 姓名:{{name}}</h2>
<h2> 年龄:{{age}}</h2>
<h3> 工作品种:{{job.type}}</h3>
<h3> 工作薪水:{{job.salary}}</h3>
<button @click="changeInfo"> 批改人的信息 </button>
</template>
<script>
import {ref} from 'vue'
export default {
name: 'App',
setup(){
// 数据
let name = ref('张三')
let age = ref(18)
let job = ref({
type:'前端工程师',
salary:'30K'
})
// 办法
function changeInfo(){
// name.value = '李四'
// age.value = 48
console.log(job.value)
// job.value.type = 'UI 设计师'
// job.value.salary = '60K'
// console.log(name,age)
}
// 返回一个对象(罕用)return {
name,
age,
job,
changeInfo
}
}
}
</script>
3. reactive 函数
- 作用: 定义一个 对象类型 的响应式数据(根本类型不要用它,要用 ref 函数)
- 语法:
const 代理对象 = reactive(源对象)
接管一个对象(或数组),返回一个 代理对象(Proxy 的实例对象,简称 proxy 对象) reactive
定义的响应式数据是“深层次的”。-
外部基于
ES6
的Proxy
实现,通过代理对象操作源对象外部数据进行操作。<template> <h1> 一个人的信息 </h1> <h2> 姓名:{{person.name}}</h2> <h2> 年龄:{{person.age}}</h2> <h3> 工作品种:{{person.job.type}}</h3> <h3> 工作薪水:{{person.job.salary}}</h3> <h3> 喜好:{{person.hobby}}</h3> <h3> 测试的数据 c:{{person.job.a.b.c}}</h3> <button @click="changeInfo"> 批改人的信息 </button> </template> <script> import {reactive} from 'vue' export default { name: 'App', setup(){ // 数据 let person = reactive({ name:'张三', age:18, job:{ type:'前端工程师', salary:'30K', a:{ b:{c:666} } }, hobby:['抽烟','喝酒','烫头'] }) // 办法 function changeInfo(){ person.name = '李四' person.age = 48 person.job.type = 'UI 设计师' person.job.salary = '60K' person.job.a.b.c = 999 person.hobby[0] = '学习' } // 返回一个对象(罕用)return { person, changeInfo } } } </script>
4. Vue3.0 中的响应式原理
4.1 vue2.x 的响应式
1、实现原理:
- 对象类型:通过
Object.defineProperty()
对属性的读取、批改进行拦挡(数据劫持)。 -
数组类型:通过重写更新数组的一系列办法来实现拦挡。(对数组的变更办法进行了包裹)。
Object.defineProperty(data, 'count', {get () {}, set () {} })
2、存在问题:
- 新增属性、删除属性, 界面不会更新。
- 间接通过下标批改数组, 界面不会自动更新。
-
模仿 Vue2 中实现响应式
// 源数据 let person = { name:'张三', age:18 } Object.defineProperty(p,'name',{ configurable:true, get(){ // 有人读取 name 时调用 return person.name }, set(value){ // 有人批改 name 时调用 console.log('有人批改了 name 属性,我发现了,我要去更新界面!') person.name = value } }) Object.defineProperty(p,'age',{get(){ // 有人读取 age 时调用 return person.age }, set(value){ // 有人批改 age 时调用 console.log('有人批改了 age 属性,我发现了,我要去更新界面!') person.age = value } })
4.2 Vue3.0 的响应式
1、实现原理:
- 通过
Proxy
(代理): 拦挡对象中任意属性的变动, 包含:属性值的读写、属性的增加、属性的删除等。 - 通过
Reflect
(反射): 对源对象的属性进行操作。 -
MDN 文档中形容的
Proxy
与Reflect
:- Proxy:https://developer.mozilla.org…
- Reflect:https://developer.mozilla.org…
2、模仿 Vue3 中实现响应式
// 源数据
let person = {
name:'张三',
age:18
}
const p = new Proxy(person,{
// 有人读取 p 的某个属性时调用
get(target,propName){console.log(` 有人读取了 p 身上的 ${propName}属性 `)
return Reflect.get(target,propName)
},
// 有人批改 p 的某个属性、或给 p 追加某个属性时调用
set(target,propName,value){console.log(` 有人批改了 p 身上的 ${propName}属性,我要去更新界面了!`)
Reflect.set(target,propName,value)
},
// 有人删除 p 的某个属性时调用
deleteProperty(target,propName){console.log(` 有人删除了 p 身上的 ${propName}属性,我要去更新界面了!`)
return Reflect.deleteProperty(target,propName)
}
})
5. reactive 比照 ref
1、从定义数据角度比照:
ref
用来定义:根本类型数据。reactive
用来定义:对象(或数组)类型数据。- 备注:
ref
也能够用来定义对象(或数组)类型数据, 它外部会主动通过reactive
转为代理对象。
2、从原理角度比照:
ref
通过Object.defineProperty()
的 get 与 set 来实现响应式(数据劫持)。reactive
通过应用 Proxy 来实现响应式(数据劫持), 并通过Reflect
操作源对象外部的数据。
3、从应用角度比照:
ref
定义的数据:操作数据须要.value
,读取数据时模板中间接读取不须要.value
。reactive
定义的数据:操作数据与读取数据:均不须要.value
。
7. 计算属性与监督
7.1. computed 函数
- 与 Vue2.x 中 computed 配置性能统一
-
写法
<template> <h1> 一个人的信息 </h1> 姓:<input type="text" v-model="person.firstName"> <br> 名:<input type="text" v-model="person.lastName"> <br> <span> 全名:{{person.fullName}}</span> <br> 全名:<input type="text" v-model="person.fullName"> </template> <script> import {reactive,computed} from 'vue' export default { name: 'Demo', setup(){ // 数据 let person = reactive({ firstName:'张', lastName:'三' }) // 计算属性——简写(没有思考计算属性被批改的状况)/* person.fullName = computed(()=>{return person.firstName + '-' + person.lastName}) */ // 计算属性——残缺写法(思考读和写)person.fullName = computed({get(){return person.firstName + '-' + person.lastName}, set(value){const nameArr = value.split('-') person.firstName = nameArr[0] person.lastName = nameArr[1] } }) // 返回一个对象(罕用)return {person} } } </script>
7.2. watch 函数
1、与
Vue2.x
中watch
配置性能统一
2、两个小“坑”: - 监督
reactive
定义的响应式数据时:oldValue
无奈正确获取、强制开启了深度监督(deep
配置生效)。 - 监督
reactive
定义的响应式数据中某个属性时:deep
配置无效。
3、写法
<template>
<h2> 以后求和为:{{sum}}</h2>
<button @click="sum++"> 点我 +1</button>
<hr>
<h2> 以后的信息为:{{msg}}</h2>
<button @click="msg+='!'"> 批改信息 </button>
<hr>
<h2> 姓名:{{person.name}}</h2>
<h2> 年龄:{{person.age}}</h2>
<h2> 薪资:{{person.job.j1.salary}}K</h2>
<button @click="person.name+='~'"> 批改姓名 </button>
<button @click="person.age++"> 增长年龄 </button>
<button @click="person.job.j1.salary++"> 涨薪 </button>
</template>
<script>
import {ref,reactive,watch} from 'vue'
export default {
name: 'Demo',
setup(){
// 数据
let sum = ref(0)
let msg = ref('你好啊')
let person = reactive({
name:'小叮当啊~',
age:18,
job:{
j1:{salary:20}
}
})
// 状况一:监督 ref 所定义的一个响应式数据
watch(sum,(newValue,oldValue)=>{console.log('sum 变了',newValue,oldValue)
},{immediate:true})
// 状况二:监督 ref 所定义的多个响应式数据
watch([sum,msg],(newValue,oldValue)=>{console.log('sum 或 msg 变了',newValue,oldValue)
},{immediate:true})
/*
状况三:监督 reactive 所定义的一个响应式数据的全副属性
1. 留神:此处无奈正确的获取 oldValue
2. 留神:强制开启了深度监督(deep 配置有效)*/
watch(person,(newValue,oldValue)=>{console.log('person 变动了',newValue,oldValue)
},{deep:false}) // 此处的 deep 配置有效
// 状况四:监督 reactive 所定义的一个响应式数据中的某个属性
watch(()=>person.name,(newValue,oldValue)=>{console.log('person 的 name 变动了',newValue,oldValue)
})
// 状况五:监督 reactive 所定义的一个响应式数据中的某些属性
watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{console.log('person 的 name 或 age 变动了',newValue,oldValue)
})
// 非凡状况
watch(()=>person.job,(newValue,oldValue)=>{console.log('person 的 job 变动了',newValue,oldValue)
},{deep:true})
// 此处因为监督的是 reactive 素定义的对象中的某个属性,所以 deep 配置无效
// 返回一个对象(罕用)return {
sum,
msg,
person
}
}
}
</script>
7.3. watchEffect 函数
1、watch
的套路是:既要指明监督的属性,也要指明监督的回调。
2、watchEffect
的套路是:不必指明监督哪个属性,监督的回调中用到哪个属性,那就监督哪个属性。
3、watchEffect
有点像computed
:
- 但
computed
重视的计算出来的值(回调函数的返回值),所以必须要写返回值。 -
而
watchEffect
更重视的是过程(回调函数的函数体),所以不必写返回值。<template> <h2> 求和为:{{sum}}</h2> <button @click="sum++"> 点我 +1</button> <hr> <h2> 以后信息:{{msg}}</h2> <button @click="msg+='!'"> 批改 </button> <hr> <h2> 姓名:{{person.name}}</h2> <h2> 年龄:{{person.age}}</h2> <h2> 薪资:{{person.job.j1.salary}}K</h2> <button @click="person.name+='~'"> 批改姓名 </button> <button @click="person.age++"> 增长年龄 </button> <button @click="person.job.j1.salary++"> 涨薪 </button> </template> <script> import {ref,reactive,watch,watchEffect} from 'vue' export default { name: 'Demo', setup(){ // 数据 let sum = ref(0) let msg = ref('你好啊') let person = reactive({ name:'张三', age:18, job:{ j1:{salary:20} } }) // 监督 /* watch(sum,(newValue,oldValue)=>{console.log('sum 的值变动了',newValue,oldValue) },{immediate:true}) */ watchEffect(()=>{ const x1 = sum.value const x2 = person.job.j1.salary console.log('watchEffect 所指定的回调执行了') }) // 返回一个对象(罕用)return { sum, msg, person } } } </script>
8. 生命周期
1、Vue3.0
中能够持续应用 Vue2.x
中的生命周期钩子,但有有两个被更名:
beforeDestroy
改名为beforeUnmount
destroyed
改名为unmounted
2、Vue3.0
也提供了 Composition API
模式的生命周期钩子,与 Vue2.x
中钩子对应关系如下:
beforeCreate
===>setup()
created
=======>setup()
beforeMount
===>onBeforeMount
mounted
=======>onMounted
beforeUpdate
===>onBeforeUpdate
updated
=======>onUpdated
beforeUnmount
==>onBeforeUnmount
unmounted
=====>onUnmounted
<template>
<h2> 以后求和为:{{sum}}</h2>
<button @click="sum++"> 点我 +1</button>
</template>
<script>
import {ref,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from 'vue'
export default {
name: 'Demo',
setup(){console.log('---setup---')
// 数据
let sum = ref(0)
// 通过组合式 API 的模式去应用生命周期钩子
onBeforeMount(()=>{console.log('---onBeforeMount---')
})
onMounted(()=>{console.log('---onMounted---')
})
onBeforeUpdate(()=>{console.log('---onBeforeUpdate---')
})
onUpdated(()=>{console.log('---onUpdated---')
})
onBeforeUnmount(()=>{console.log('---onBeforeUnmount---')
})
onUnmounted(()=>{console.log('---onUnmounted---')
})
// 返回一个对象(罕用)return {sum}
},
// 通过配置项的模式应用生命周期钩子
//#region
beforeCreate() {console.log('---beforeCreate---')
},
created() {console.log('---created---')
},
beforeMount() {console.log('---beforeMount---')
},
mounted() {console.log('---mounted---')
},
beforeUpdate(){console.log('---beforeUpdate---')
},
updated() {console.log('---updated---')
},
beforeUnmount() {console.log('---beforeUnmount---')
},
unmounted() {console.log('---unmounted---')
},
//#endregion
}
</script>
9. 自定义 hook 函数
1、什么是 hook
?—— 实质是一个函数,把setup
函数中应用的 Composition API
进行了封装。
2、相似于 vue2.x
中的 mixin
。
3、自定义hook
的劣势: 复用代码, 让 setup
中的逻辑更分明易懂。
4、Demo.vue
中
<template>
<h2> 以后求和为:{{sum}}</h2>
<button @click="sum++"> 点我 +1</button>
<hr>
<h2> 以后点击时鼠标的坐标为:x:{{point.x}},y:{{point.y}}</h2>
</template>
<script>
import {ref} from 'vue'
import usePoint from '../hooks/usePoint'
export default {
name: 'Demo',
setup(){
// 数据
let sum = ref(0)
let point = usePoint()
// 返回一个对象(罕用)return {sum,point}
}
}
</script>
5、hooks/usePoint.js
中
import {reactive,onMounted,onBeforeUnmount} from 'vue'
export default function (){
// 实现鼠标“打点”相干的数据
let point = reactive({
x:0,
y:0
})
// 实现鼠标“打点”相干的办法
function savePoint(event){
point.x = event.pageX
point.y = event.pageY
console.log(event.pageX,event.pageY)
}
// 实现鼠标“打点”相干的生命周期钩子
onMounted(()=>{window.addEventListener('click',savePoint)
})
onBeforeUnmount(()=>{window.removeEventListener('click',savePoint)
})
return point
}
10. toRef
1、作用:创立一个 ref
对象,其 value
值指向另一个对象中的某个属性。
2、语法:const name = toRef(person,'name')
3、利用: 要将响应式对象中的某个属性独自提供给内部应用时。
4、扩大:toRefs
与 toRef
性能统一,但能够批量创立多个 ref
对象,语法:toRefs(person)
<template>
<h4>{{person}}</h4>
<h2> 姓名:{{name}}</h2>
<h2> 年龄:{{age}}</h2>
<h2> 薪资:{{job.j1.salary}}K</h2>
<button @click="name+='~'"> 批改姓名~</button>
<button @click="age++"> 增长年龄~</button>
<button @click="job.j1.salary++"> 升职加薪走上人生巅峰 </button>
</template>
<script>
import {ref,reactive,toRef,toRefs} from 'vue'
export default {
name: 'Demo',
setup(){
// 数据
let person = reactive({
name:'张三',
age:18,
job:{
j1:{salary:20}
}
})
// const name1 = person.name
// console.log('***',name1)
// const name2 = toRef(person,'name')
// console.log('...',name2)
const x = toRefs(person)
console.log('******',x)
// 返回一个对象(罕用)return {
person,
// name:toRef(person,'name'),
// age:toRef(person,'age'),
// salary:toRef(person.job.j1,'salary'),
...toRefs(person)
}
}
}
</script>
三、其它 Composition API
1. shallowReactive 与 shallowRef
1、shallowReactive
:只解决对象最外层属性的响应式(浅响应式)。
2、shallowRef
:只解决根本数据类型的响应式, 不进行对象的响应式解决。
3、什么时候应用?
- 如果有一个对象数据,构造比拟深, 但变动时只是外层属性变动 ===>
shallowReactive
。 - 如果有一个对象数据,后续性能不会批改该对象中的属性,而是生新的对象来替换 ===>
shallowRef
。
<template>
<h4> 以后的 x.y 值是:{{x.y}}</h4>
<button @click="x={y:888}"> 点我替换 x </button>
<button @click="x.y++"> 点我 x.y++</button>
<hr>
<h4>{{person}}</h4>
<h2> 姓名:{{name}}</h2>
<h2> 年龄:{{age}}</h2>
<h2> 薪资:{{job.j1.salary}}K</h2>
<button @click="name+='~'"> 批改姓名 </button>
<button @click="age++"> 增长年龄 </button>
<button @click="job.j1.salary++"> 涨薪 </button>
</template>
<script>
import {ref,reactive,toRef,toRefs,shallowReactive,shallowRef} from 'vue'
export default {
name: 'Demo',
setup(){
// 数据
// let person = shallowReactive({ // 只思考第一层数据的响应式
let person = reactive({
name:'张三',
age:18,
job:{
j1:{salary:20}
}
})
let x = shallowRef({y:0})
console.log('******',x)
// 返回一个对象(罕用)return {
x,
person,
...toRefs(person)
}
}
}
</script>
2. readonly 与 shallowReadonly
1、readonly
: 让一个响应式数据变为只读的(深只读)。
2、shallowReadonly
:让一个响应式数据变为只读的(浅只读)。
3、利用场景: 不心愿数据被批改时。
<template>
<h4> 以后求和为 --:{{sum}}</h4>
<button @click="sum++"> 点我 ++</button>
<hr>
<h2> 姓名:{{name}}</h2>
<h2> 年龄:{{age}}</h2>
<h2> 薪资:{{job.j1.salary}}K</h2>
<button @click="name+='~'"> 批改姓名 </button>
<button @click="age++"> 增长年龄 </button>
<button @click="job.j1.salary++"> 涨薪 </button>
</template>
<script>
import {ref,reactive,toRefs,readonly,shallowReadonly} from 'vue'
export default {
name: 'Demo',
setup(){
// 数据
let sum = ref(0)
let person = reactive({
name:'张三',
age:18,
job:{
j1:{salary:20}
}
})
person = readonly(person)
// person = shallowReadonly(person)
// sum = readonly(sum)
// sum = shallowReadonly(sum)
// 返回一个对象(罕用)return {
sum,
...toRefs(person)
}
}
}
</script>
3. toRaw 与 markRaw
1、toRaw:
- 作用:将一个由
reactive
生成的响应式对象转为一般对象。 - 应用场景:用于读取响应式对象对应的一般对象,对这个一般对象的所有操作,不会引起页面更新。
2、markRaw: - 作用:标记一个对象,使其永远不会再成为响应式对象。
-
利用场景:
- 有些值不应被设置为响应式的,例如简单的第三方类库等。
- 当渲染具备不可变数据源的大列表时,跳过响应式转换能够进步性能。
<template> <h4> 以后求和为:{{sum}}</h4> <button @click="sum++"> 点我 ++</button> <hr> <h2> 姓名:{{name}}</h2> <h2> 年龄:{{age}}</h2> <h2> 薪资:{{job.j1.salary}}K</h2> <h3 v-show="person.car"> 座驾信息:{{person.car}}</h3> <button @click="name+='~'"> 批改姓名 </button> <button @click="age++"> 增长年龄 </button> <button @click="job.j1.salary++"> 涨薪 </button> <button @click="showRawPerson"> 输入最原始的 person</button> <button @click="addCar"> 给人增加一台车 </button> <button @click="person.car.name+='!'"> 换车名 </button> <button @click="changePrice"> 换价格 </button> </template> <script> import {ref,reactive,toRefs,toRaw,markRaw} from 'vue' export default { name: 'Demo', setup(){ // 数据 let sum = ref(0) let person = reactive({ name:'张三', age:18, job:{ j1:{salary:20} } }) function showRawPerson(){const p = toRaw(person) p.age++ console.log(p) } function addCar(){let car = {name:'飞驰',price:40} person.car = markRaw(car) } function changePrice(){ person.car.price++ console.log(person.car.price) } // 返回一个对象(罕用)return { sum, person, ...toRefs(person), showRawPerson, addCar, changePrice } } } </script>
4. customRef
1、作用:创立一个自定义的 ref
,并对其依赖项跟踪和更新触发进行显式管制。
2、实现防抖成果:
<template>
<input type="text" v-model="keyWord">
<h3>{{keyWord}}</h3>
</template>
<script>
import {ref,customRef} from 'vue'
export default {
name: 'App',
setup() {
// 自定义一个 ref——名为:myRef
function myRef(value,delay){
let timer
return customRef((track,trigger)=>{
return {get(){console.log(` 有人从 myRef 这个容器中读取数据了,我把 ${value}给他了 `)
track() // 告诉 Vue 追踪 value 的变动(提前和 get 商量一下,让他认为这个 value 是有用的)return value
},
set(newValue){console.log(` 有人把 myRef 这个容器中数据改为了:${newValue}`)
clearTimeout(timer)
timer = setTimeout(()=>{
value = newValue
trigger() // 告诉 Vue 去从新解析模板},delay)
},
}
})
}
// let keyWord = ref('hello') // 应用 Vue 提供的 ref
let keyWord = myRef('hello',500) // 应用程序员自定义的 ref
return {keyWord}
}
}
</script>
5. provide 与 inject
1、作用:实现祖与后辈组件间通信
2、套路:父组件有一个 provide
选项来提供数据,后辈组件有一个 inject
选项来开始应用这些数据
3、具体写法:
-
祖组件中:
setup(){ ...... let car = reactive({name:'飞驰',price:'40 万'}) provide('car',car) ...... }
-
后辈组件中:
setup(props,context){ ...... const car = inject('car') return {car} ...... }
6. 响应式数据的判断
- isRef: 查看一个值是否为一个
ref
对象 - isReactive: 查看一个对象是否是由
reactive
创立的响应式代理 - isReadonly: 查看一个对象是否是由
readonly
创立的只读代理 -
isProxy: 查看一个对象是否是由
reactive
或者readonly
办法创立的代理setup(){let car = reactive({name:'飞驰',price:'40W'}) let sum = ref(0) let car2 = readonly(car) console.log(isRef(sum)) console.log(isReactive(car)) console.log(isReadonly(car2)) console.log(isProxy(car)) console.log(isProxy(sum)) return {...toRefs(car)} }
四、新的组件
1. Fragment
1、在 Vue2 中: 组件必须有一个根标签
2、在 Vue3 中: 组件能够没有根标签, 外部会将多个标签蕴含在一个Fragment
虚构元素中
3、益处: 缩小标签层级, 减小内存占用
2. Teleport
什么是 Teleport?—— Teleport
是一种可能将咱们的组件 html
构造挪动到指定地位的技术。
<teleport to="挪动地位">
<div v-if="isShow" class="mask">
<div class="dialog">
<h3> 我是一个弹窗 </h3>
<button @click="isShow = false"> 敞开弹窗 </button>
</div>
</div>
</teleport>
3. Suspense
1、期待异步组件时渲染一些额定内容,让利用有更好的用户体验
2、应用步骤:
-
异步引入组件
import {defineAsyncComponent} from 'vue' const Child = defineAsyncComponent(()=>import('./components/Child.vue')) 应用 Suspense 包裹组件,并配置好 default 与 fallback <template> <div class="app"> <h3> 我是 App 组件 </h3> <Suspense> <template v-slot:default> <Child/> </template> <template v-slot:fallback> <h3> 加载中.....</h3> </template> </Suspense> </div> </template>
五、其它
1. 全局 API 的转移
1、Vue 2.x 有许多全局 API 和配置。
-
例如:注册全局组件、注册全局指令等。
// 注册全局组件 Vue.component('MyButton', {data: () => ({count: 0}), template: '<button @click="count++">Clicked {{count}} times.</button>' }) // 注册全局指令 Vue.directive('focus', {inserted: el => el.focus() }
2、Vue3.0 中对这些 API 做出了调整:
- 将全局的 API,即:Vue.xxx 调整到利用实例(app)上
2.x 全局 API(Vue ) |
3.x 实例 API (app ) |
---|---|
Vue.config.xxxx | app.config.xxxx |
Vue.config.productionTip | 移除 |
Vue.component | app.component |
Vue.directive | app.directive |
Vue.mixin | app.mixin |
Vue.use | app.use |
Vue.prototype | app.config.globalProperties |
2. 其余扭转
1、data
选项应始终被申明为一个函数。
-
适度类名的更改:
.v-enter, .v-leave-to {opacity: 0;} .v-leave, .v-enter-to {opacity: 1;}
-
Vue3.x 写法
.v-enter-from, .v-leave-to {opacity: 0;} .v-leave-from, .v-enter-to {opacity: 1;}
3、移除
keyCode
作为v-on
的修饰符,同时也不再反对config.keyCodes
4、 移除v-on.native
修饰符 -
父组件中绑定事件
<my-component v-on:close="handleComponentEvent" v-on:click="handleNativeClickEvent" />
-
子组件中申明自定义事件
<script> export default {emits: ['close'] } </script>
5、移除 过滤器(
filter
)
过滤器尽管这看起来很不便,但它须要一个自定义语法,突破大括号内表达式是“只是 JavaScript”的假如,这不仅有学习老本,而且有实现老本!倡议用办法调用或计算属性去替换过滤器。