目录

简介

一、创建项目

1.使用vue-clli创建

2.使用Vite创建

二、Composition API(组合式API)

1.setup函数

2.ref函数和reactive函数

1.ref函数

2.reactive函数

3.模拟vue3实现响应式

4.computed函数

5.watch函数

6.watchEffect函数

7.生命周期

8.自定义hook函数

9.toRef 和 toRefs

三.其它 Composition API

1. shallowReactive 和 shallowRef

2.readonly 和 shallowReadonly

3.toRaw 和 markRaw

4.customRef

5.provide 和 inject

6.响应式数据的判断

四.新的组件

1.Fragment

2.Teleport

参考



简介

本文基于b站尚硅谷vue教程尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通_哔哩哔哩_bilibili编写,以作个人学习记录。


一、创建项目

1.使用vue-clli创建

## 查看@vue/cli版本,确保@vue/cli版本在4.5.0以上
vue -V
## 安装或升级@vue/cli
npm install -g @vue/cli
## 创建项目 选择vue3
vue create projectName
## 进入项目所在文件夹,启动项目
npm run serve

2.使用Vite创建

## 创建工程
npm init @vitejs/app projectName
## 进入工程目录
cd projectName
## 安装依赖
npm install
## 运行项目
npm run dev

二、Composition API(组合式API)

1.setup函数

①在vue3中数据、方法等均要配置在setup中

②setup有两种返回值:

        I.返回一个对象,包含需要使用的数据和方法,模板能直接使用这些数据和方法

        II.返回一个渲染函数(较少使用)

③setup()早于beforeCreate()执行,其有两个参数:(props,context)

  • props:值为对象,包含父组件传过来的,且本组件有接收(同vue2中接收props)的属性
  • context:值为对象,包含attrs、slots、emit
    • attrs等同于this.$attrs,用以获取父组件传递的但本组件未在props中声明的属性
    • slots等同于this.$slots,用以获取插槽
    • emit等同于this.$emit,用以触发自定义事件(自定义事件需要在新的配置项emits声明,否则控制台会报警告)

*注意点:

1.尽量不要与vue2混用,vue2可以访问到setup的数据、方法,反之则不行

2.setup不能是async函数,否则返回的是一个promise,模板无法获取return的对象中的属性(后期也可以返回一个Promise实例,但需要Surspense和异步组件的配合)

<template><h4>姓名:{{ name }}</h4><h4>学校:{{ info.school }}</h4><h4>年级:{{ info.grade }}</h4><h4>爱好:{{ hobbies }}</h4><button @click="sayHello">点我</button>
</template><script>
export default {name: "Setup",setup() {let name = "trytou";let hobbies = ["抽烟", "喝酒", "烫头"];let info = {school: "菜头市第一小学",grade: "一年级",};function sayHello(){alert("hello")}return{name,info,hobbies,  sayHello,}},
};
</script>

2.ref函数和reactive函数

ref函数和reactive函数都可以定义一个响应式的数据,需要引入才能使用

使用方式:const xx=ref(value) 或 const xx=reactive(value)

1.ref函数

  • ref函数既可以接收基本数据类型,也可以接收引用数据类型(数组或对象)
  • 对于基本数据类型,响应式依然时通过Object.defineProperty()实现
  • 对于对象类型数据,响应式则靠vue3中的一个新函数——reactive函数实现
  • 在js中操作ref定义的响应式数据时要通过xxx.value获取,模板中则不需要

2.reactive函数

  • reactive函数只能接收引用数据类型的数据(数组或对象)
  • reactive函数返回一个proxy对象
  • reactive函数定义的数据是深层次的,其内部的属性可以直接修改,(在vue2中通过直接赋值的方式来修改data中的数组的某个元素是无效的)
<template><h4>姓名:{{name}}</h4><h4>年龄:{{age}}</h4><h4>学校:{{info.school}}</h4><h4>年级:{{info.grade}}</h4><h4>爱好:{{hobbies}}</h4><button @click="sayHello">点我</button><button @click="changeHobby">点我换爱好</button><button @click="changeSchool">点我换学校</button>
</template><script>
import { reactive, ref } from 'vue'export default {name:'Ref_Reactive',setup(){//ref函数定义一个响应式数据let name=ref('trytou')let age=ref(20)let info=reactive({school:'菜头市第一小学',grade:'一年级'})let hobbies=reactive(['抽烟','喝酒','烫头'])function sayHello(){alert('hello trytou');}function changeHobby(){hobbies[0]='打球'}function changeSchool(){info.school='反斗花园幼儿园'}return{name,age,info,hobbies,  sayHello,changeHobby,changeSchool}}
}
</script>

3.模拟vue3实现响应式

vue3中通过Proxy(代理)和Reflect(反射)来实现响应式

<script>let person = {name: 'trytou',age: 20}const p = new Proxy(person, {get(target, prop) {return Reflect.get(target,prop)},set(target, prop, value) {return Reflect.set(target,prop,value)},deleteProperty(target,prop){return Reflect.deleteProperty(target,prop)}})p.name='Chan'console.log(p);</script>

4.computed函数

  • computed接收一个函数或者一个对象需要引入才能使用
import {computed} from 'vue'
export default {name: "Computed",setup() {let person = reactive({firstName: "try",lastName:'tou',})//计算属性-简写// person.fullName=computed(()=>person.name+'-'+person.age)//计算属性-完整写法person.fullName=computed({get(){return person.firstName+'-'+person.lastName},set(value){person.firstName=value.split('-')[0]person.lastName=value.split('-')[1]}})return{person,}},
};

5.watch函数

watch函数中有较多的坑,监视reactive定义的数据时要注意

  • 情况一:监视ref定义的一个响应式数据
watch(num,(newValue,oldValue)=>{console.log(newValue,oldValue);
})
  • 情况二:监视ref定义的多个响应式数据
watch([num,msg],(newValue,oldValue)=>{console.log(newValue,oldValue);
})
  • 情况三:监视reactive定义的一个响应式数据 (默认deep:true,且无法设置为false)

watch(person,(newValue,oldValue)=>{//此处 oldValue == newValue , 无法获取正常的 oldValueconsole.log(newValue,oldValue);
},{deep:false})
  • 情况四:监视reactive定义的某个响应式数据中的某个属性

watch(()=>person.age,(newValue,oldValue)=>{console.log(newValue,oldValue);
})
  • 情况五:监视reactive定义的某一个响应式数据中的多个属性

watch([()=>person.age,()=>person.name],(newValue,oldValue)=>{console.log(newValue,oldValue);
})
  • 情况六:监视reactive定义的深层次的响应式数据

watch(()=>person.jobs,(newValue,oldValue)=>{console.log(newValue,oldValue);
},{deep:true})//需要设置deep为true

6.watchEffect函数

watchEffect函数类似computed,但前者无需写返回值,且不必指明监视哪个属性

//类似computed属性,检测回调函数中用到的数据发生变化即会重新执行回调
watchEffect(()=>{console.log(person.age);
})

7.生命周期

在vue3中有两种使用生命周期钩子的方式

  • 第一种方式是通过配置对象的形式,与vue2中生命周期钩子使用方式一致,但有两个更换了名字:

    • beforDestroy更名为beforeUnmount
    • destroyed更名为unmounted
  • 第二种方式是通过组合API的形式,除了setup之外的钩子都应在setup内部调用,与vue2生命周期钩子对应关系如下:
    • 因为 setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以不需要显式地定义它们。
    • setup()  ==>  beforeCreate() 和 created()
    • onBeforeMount()  ==>  beforeMount()
    • onMounted  ==>  mounted()

    • onBeforeUpdate  ==>  beforeUpdate()

    • onUpdated  ==>  updated()

    • onBeforeUnmount()  ==>  beforeDestroy()

    • onUnmounted()  ==>  destroy()()

  • 两种方式可以同时使用(但尽量不要这么做),组合式API的生命周期钩子会比配置对象形式的钩子先执行

8.自定义hook函数

  • hook本质上是一个函数,作用类似于mixin

在usePoint.js中定义一个hook并暴露出去

import {onMounted,onUnmounted, reactive} from 'vue';export function usePoint() {let point = reactive({x: '',y: ''})let getPoint = function (event) {point.x = event.pageXpoint.y = event.pageY}onMounted(() => {window.addEventListener('click', getPoint)})onUnmounted(() => {window.removeEventListener('click', getPoint)})return point
}

在组件中引入hook便可直接使用,无需再次引入hook中引用的组合式api

<template><h4>点击任意位置获取当前鼠标的坐标</h4><span>X轴坐标:{{point.x}}</span><br><span>Y轴坐标:{{point.y}}</span>
</template><script>
import {usePoint} from '../hooks/usePoint';
export default {name:'Hook',setup(){let point=usePoint()return {point}}
}
</script>

9.toRef 和 toRefs

  • toRef 和 toRefs 都是函数,后者可以批量创建多个ref
  • toRef可以为一个响应式对象中的某个属性创建一个ref,且这个ref的值会指向源响应式对象中的那个属性
  • toRefs可以为一个响应式对象中的每一个最外层的属性创建ref
<template><h4>{{person}}</h4><hr><h4>my name is {{name}}</h4><button @click="name='Chan'">rename</button><h4>salary: {{jobs.job1.salary}}k</h4><button @click="jobs.job1.salary++">涨薪</button><button @click="salary++">涨薪</button><h4>age: {{age}}</h4><button @click="age++">长大了</button>
</template><script>
import { reactive, toRef ,toRefs} from 'vue'
export default {name:'ToRef',setup(){let person=reactive({name:'trytou',age:20,jobs:{job1:{salary:8}}})/salary的值发生变化,person.jobs.job1.salary的值也会发生变化const salary=toRef(person.jobs.job1,'salary')console.log(salary);/console.log(toRefs(person));return{person,salary,...toRefs(person)}}
}
</script>

三.其它 Composition API

1. shallowReactive 和 shallowRef

//shallowReactive 与 reactive的区别在于shallowReactive只处理对象最外层属性的响应式(浅响应式)

let sReaPerson=shallowReactive(person)

//shallowRefref的区别在于 shallowRef 不会将.value变成响应式(proxy),而仍是一个普通的对象

let sRefPerson=shallowRef(person)

2.readonly 和 shallowReadonly

//readonly接收一个响应式数据并使其成为只读的(深只读)

let p1 = readonly(reactive(person));

let p3 = readonly(ref(num));

//shallowReadonly接收一个响应式数据并使其成为只读的(浅只读)

let p2 = shallowReadonly(reactive(person));

let p4 = shallowReadonly(ref(num));

3.toRaw 和 markRaw

//toRaw返回reactive或readonly代理的原始对象(ref无效)

console.log(toRaw(person));

console.log(toRaw(pet));

//markRaw标记一个对象,使其永远不会转换为 proxy,返回对象本身

let mr = markRaw({ age: 20 });

let kid = reactive(mr);

4.customRef

  • 创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track 和 trigger 函数作为参数,并且应该返回一个带有 get 和 set 的对象。

使用自定义ref实现防抖效果:

<template><input type="text" v-model="msg" /><h4>{{ msg }}</h4>
</template><script>
import { customRef, ref } from "@vue/reactivity";
export default {name: "CustomRef",setup() {function myRef(initValue) {let timer;return customRef((track, trigger) => {return {get() {track();return initValue;},set(newValue) {clearTimeout(timer);timer = setTimeout(() => {initValue = newValue;trigger();}, 500);},};});}let msg = myRef("hello");return {msg,};},
};
</script>

5.provide 和 inject

  • 作用:可以用来实现祖孙组件之间的通信
  • 在祖组件中使用provide(),后代组件使用inject()接收

祖组件

...
setup(){
let msg=ref('love u')provide('msg',msg)
...
}

后代组件

...
setup(){let msg=inject('msg')...
}

6.响应式数据的判断

...
setup(){let p1=ref(0)let p2=reactive({})let p3=readonly({})console.log(isRef(p1));//判断一个值是否为一个 ref 对象console.log(isReactive(p2));//判断一个对象是否是由 reactive 创建的响应式代理console.log(isReadonly(p3));//判断一个对象是否是由 readonly 创建的只读代理console.log(isProxy(p2));//判断一个对象是否是由 reactive 或者 readonly 方法创建的代理console.log(isProxy(p3));}
...

四.新的组件

1.Fragment

  • 在vue3中组件无需根标签,内部会自动将模板中的内容包含在一个Fragment中

2.Teleport

  • teleport可以让组件移动到指定位置,在下面的例子中Son组件有一个Dialog组件,如果我们想让这个Dialog组件位于body下可以通过teleport中的to属性来指定

祖组件

<template><div class="cur"><h3>我是祖先</h3><Child></Child></div>
</template><script>
import Child from './17_child.vue';
export default {name: "TeleportComponent",components:{Child}
};
</script>
<style>
div{padding:20px
}
</style>

子组件

<template><div class="child"><h4>我是Child组件</h4><Son></Son></div>
</template><script>
import Son from './17_son.vue';
export default {name:'Child',components:{Son}
}
</script><style>
.child{background-color: rgb(47, 145, 184);
}
</style>

孙组件

<template><div class="son"><h5>我是Son组件</h5><Dialog></Dialog></div>
</template><script>
import Dialog from './17_Dialog.vue';
export default {name:'Son',components:{Dialog},setup(){}
}
</script><style>
.son{background: rgb(236, 80, 80);
}
</style>

Dialog组件

<template><button @click="isShow = true">开启弹窗</button><teleport to="body"><div class="mask" v-if="isShow"><div class="dialog"><h3>我是弹窗</h3><button @click="isShow = false">关闭弹窗</button></div></div></teleport>
</template><script>
import { ref } from "vue";export default {name: "Dialog",setup() {let isShow = ref(false);return {isShow,};},
};
</script><style>
.dialog {position: absolute;width: 440px;height: 300px;top: 50%;left: 50%;transform: translate(-50%, -50%);text-align: center;background-color: pink;z-index: 999;
}.mask {width: 100%;height: 100%;position: absolute;top: 0;left: 0;background-color: rgba(0, 0, 0, 0.5);
}
</style>

可以看到teleport包含的结构出现在<body>下


参考

尚硅谷vue3教程:尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通_哔哩哔哩_bilibili

vue3官方文档:Vue.js

vite官方文档:Vite中文网

【Vue】菜头学前端 - vue3学习笔记相关推荐

  1. 前端面试+学习笔记(HTML+CSS+JavaScript+ES6+Vue+NodeJs)

    前端面试+学习笔记(HTML+CSS+JavaScript+ES6+Vue+NodeJs) 一. HTML 1. 盒子模型 是什么:每个元素被表示为一个矩形的盒子,有四个部分组成:内容(content ...

  2. 【百度前端学院学习笔记】Day6 浮动/BFC

    [百度前端学院学习笔记]Day6 浮动/BFC 一.什么是浮动? 二.普通流 / 浮动 / 绝对定位 三.BFC/Flow Root 3.1 什么是BFC? 3.2 BFC 的特性 3.2.1 特性一 ...

  3. 重磅推出:分享阿里云大学前端开发学习路线链接

    重磅推出:分享阿里云大学前端开发学习路线链接 这是一份阿里云大学推出前端开发学习路线,适合入门.也适合刚入职场一两年的小伙伴,来一个基础知识进行加深视频学习.内容言简意赅,通过demo练习等来理解学习 ...

  4. 前端开发学习笔记(一):HTML

    前端开发学习笔记(一):HTML 文章目录 前端开发学习笔记(一):HTML 一. HTML的文档结构 二.标签属性 2.1. 标签属性 2.2. 文字格式化标签 2.3. html实体转义 三. t ...

  5. 【百度前端学院学习笔记】Day9 圣杯布局和双飞翼布局

    [百度前端学院学习笔记]Day9 圣杯布局和双飞翼布局 圣杯布局(古老而费解的方法) 双飞翼布局(圣杯的改进) 参考资料: In search of the Holy Grail - A list a ...

  6. java前端nui_spring mvc 及普元nui前端框架学习笔记

    spring mvc 及普元nui前端框架学习笔记 页面传值 一.同一页面 直接通过$J.getbyName("id").setValue(id); Set值即可 二.跳转页面(b ...

  7. 前端自学学习笔记——ES5、ES6

    前端自学学习笔记--ES5.ES6 文章目录 前端自学学习笔记--ES5.ES6 1.面向过程与面向对象 1.1面向过程 1.2面向对象 1.3面向过程与面向对象对比 2.对象与类 2.1对象 2.1 ...

  8. 优达学城-深度学习笔记(一)

    优达学城-深度学习笔记(一) 标签: 机器学习 优达学城-深度学习笔记一 一 神经网络简介 最大似然概率 交叉熵Cross entropy 1交叉熵代码实现 2多类别交叉熵 对数几率回归的误差函数co ...

  9. 前端入门学习笔记(三十五)vue.js入门(三)条件 v-if 与循环 v-for,v-for 中 in 和 of 的区别

    1.v-if v-if相当好理解,这里我就只贴实例代码了 <div id="app"><p v-if="true">现在你看到我了< ...

最新文章

  1. 嗨:VSCode和IDEA都请安装上这个神奇的插件
  2. 把java程序作为windows服务运行
  3. pandas python groupby_pandas之分组groupby()的使用整理与总结
  4. 前端学习(3169):react-hello-react之删除一个todoList
  5. 使C#代码现代化——第二部分:方法
  6. 超搞笑之仙桃有没有毛?
  7. oracle数据库赋权_Oracle角色权限创建用户赋权
  8. im2col函数解析
  9. Udacity也弃用React Native了 !
  10. 简单易学Matlab深度学习教程--矩阵
  11. 单片机 一键开关机 软件结合
  12. python爬关键词百度指数_利用python+selenium_phantomjs批量获取百度指数 第一步 分析...
  13. 易捷web文件服务器软件,易捷文件共享Web服务器
  14. 关于瞬时功率的无功功率和有功功率,在不同坐标系下的验证
  15. 尚硅谷todolist案例
  16. 鸿蒙系统推送表,【前沿】华为P40首发鸿蒙系统?| 附EMUI 10正式版推送时间表
  17. 关于表单防重复提交一些东东
  18. 弘辽科技:淘宝老链接很难做起来吗?淘宝老链接如何做起来?
  19. html怎么搞一个微信图标,怎样在微信名字添加图标和微信名字里怎么加表情?什么系统都可以...
  20. win10无法访问共享解决办法

热门文章

  1. Java数据同步方案
  2. 罗马数字 古罗马数字转换为阿拉伯数字
  3. Yan LeCun会是AI界的居里夫人吗?
  4. 一文读懂Java接口
  5. 养蜂人教你怎么辨别真假蜂蜜
  6. riak文件服务器,riak简介(一)
  7. win7安装node版本最高只支持13.14.0
  8. Win7-64 重装 Anaconda3
  9. 新研究评估Masimo SedLine(R)脑功能监护仪能否预测心跳骤停后ICU患者的神经系统转归和长期生存
  10. MySQL 设计与开发规范