Vue3.0从入门到一骑绝尘

一、vue3.0快速上手

1、Vue3简介

Vue3.0支持大多数的Vue2的特性,Vue3中设计了一套强大的composition组合API代替Vue2中的optionAPI,复用性更强大了,对TypeScript有更好的支持。

2、Vue3带来了什么?

1、性能的提升
  • 打包大小减少了41%
  • 初次渲染块55%,更新渲染块133%
  • 内存减少54%
2、源码的升级
  • 使用Proxy代替defineProperty实现响应式
  • 重写虚拟DOM的实现和Tree-Shaking
3、拥抱TypeScript
  • Vue3可以更好的支持ypeScript
4、新的特性

1、Composition API(组合API)

  • setup配置
  • ref与reactive
  • watch与watchEffect
  • provide与inject

2、新的内置组件

  • Fragment
  • Teleport
  • Suspense

3、其他改变

  • 新的生命周期钩子
  • data选项应始终被声明为一个函数
  • 移除keyCode支持作为v-on的修饰符

二、创建项目

2.1Vue-cli脚手架搭建项目

(1)首先查看你的版本

## 查看@vue/cli版本,确保@vue/cli版本在4.5.0以上
vue -V
## 安装获取升级你的@vue/cli
npm install -g @vue/cli
## 创建
vue create vue-test
## 启动
cd vue_test
npm run serve

注意:yarn安装npm install -g yarn

在这里插入图片描述

2.2、使用vite创建

  • 什么是vite?—— 是Vue团队打造的新一代前端构建工具。
  • 优势如下:
    1、开发环境中,无需打包操作,可快速的冷启动。
    2、轻量快速的热重载(HMR)。
    3、真正的按需编译,不再等待整个应用编译完成。
npm init @vitejs/app <项目名>

三、Composition API

3.1是什么?

Composition API也叫组合式API,是Vue3.0的新特性。

通过创建Vue组件,我们可以将接口的可重复部分及其功能提取到可重复的代码部分及其功能提取到可重用的代码段中。

3.2为什么使用CompositionAPI?

在这里插入图片描述

3.3函数

在这里插入图片描述

3.4(一)setup

setup()函数是vue3.0中,专门为组件提供的新属性,它为我们使用vue3的CompositionAPI新特性提供了统一的入口。

  • 1、组件中所用到的:数据、方法等等,均要配置在setup中。
  • 2、若返回一个对象,则对象中的属性、方法,在模板中均可以直接使用。若返回一个渲染函数:则可以自定义渲染内容。
<template>
  <h1>博主的信息</h1>
  <h2>姓名:{{name}}</h2>
  <h2>年龄:{{age}}</h2>
  <h2>性别:{{gender}}</h2>
  <button @click="sayInfo">显示信息</button>
</template>

<script>
// import {h} from 'vue'
export default {
  name: "App",
  //此处只是测试一下setup,暂时不考虑响应式的问题。
  setup(){
    // 数据
    let name = "YK菌"
    let age = 18
    let gender = "男"

    // 方法
    function sayInfo(){
      alert(`你好${name},你太厉害了吧`)
    }
    // 返回一个对象(常用)
    return {
      name,age, gender,sayInfo
    }
    // 返回一个函数(渲染函数)
    // return ()=> h('h1','YK菌yyds')
  }
};
</script>
props:组件传入的属性 context:上下文对象

在这里插入图片描述

3.5(二)ref函数

作用: 定义一个响应式的数据
语法: const xxx = ref(initValue)

  • 创建一个包含响应式数据的引用对象(reference对象,简称ref对象)。
  • JS中操作数据: xxx.value
  • 模板中读取数据:不需要.value,直接:<div>{{xxx}}</div>

备注:

  • 接收的数据可以是:基本类型、也可以是对象类型。
  • 基本类型的数据:响应式依靠的是类上的getter与setter完成的(我们等下看下源码你就知道了)。
  • 对象类型的数据:内部 “ 求助 ”了Vue3.0中的一个新函数—— reactive函数。
<template>
  <!-- <h3>数量:{{num}}</h3> -->
  <h3>count数量:{{count}}</h3>
  <input type="text" v-model="count">
  <button @click="getCount()">获取</button>
</template>
<script>
    import {ref} from 'vue'
    export default {
        //option API方式
        // data(){
        //     return{
        //         num:0
        //     }
        // }
        //composition API方式
        setup(){//data methods computed watch都是写在setup中
            //直接这样定义 不是响应式的数据
            // const count = 0;
            
            //创建响应式的数据对象 我们的count 给初始值为0
            const count = ref(0)

            let getCount = ()=>{
                //如果要访问ref() 创建出来响应式数据对象的值 必须通过.value属性才可以
                console.log(count.value)
            }
            //模板中要使用这些变量和方法 都需要调用,所以需要return
            return{
                count,getCount
            }
        }
    }
</script>
<style>
</style>

3.5(三)reactive

  • 作用: 定义一个对象类型的响应式数据(基本类型不要用它,要用ref函数)
  • 语法:const 代理对象= reactive(源对象)接收一个对象(或数组),返回一个代理对象(Proxy的实例对象,简称proxy对象)
  • reactive定义的响应式数据是“深层次的”。
  • 内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据进行操作。

3.6(四)reactive对比ref

1、从定义数据角度对比

ref用来定义:基本类型数据
reactive用来定义:对象(或数组)类型数据
备注:ref也可以用来定义对象(或数组)类型数据, 它内部会自动通过reactive转为代理对象

2、从原理角度对比

ref通过类中的的gettersetter来实现响应式(数据劫持)。
reactive通过使用Proxy来实现响应式(数据劫持), 并通过Reflect操作源对象内部的数据。

3、从使用角度对比

ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value
reactive定义的数据:操作数据与读取数据:均不需要.value

3.7(五)toRefs

toRefs将响应式对象转换为普通对象,其中结果对象的每个property都是指向原始对象相应property的ref。

  • 作用:创建一个ref对象,其value值指向另一个对象中的某个属性。
  • 语法:const name = toRef(person,'name')
  • 应用: 要将响应式对象中的某个属性单独提供给外部使用时。
  • 扩展:toRefstoRef功能一致,但可以批量创建多个 ref 对象,语法:toRefs(person)

3.8(六)computed

<template>
	<hr>
	<input type="text" v-model="test">
	<h2>user:{{test}}</h2>
	<!-- <h3>姓名:{{data.user.name}}</h3> -->
	<h3>姓名:{{user.name}}</h3>
	<li v-for="item in list ">
		{{item}}
	</li>
	<hr>
	<p>
		姓:<input type="text" v-model="firstName">
	</p>
	<p>
		名:<input type="text" v-model="lastName">
	</p>
	<h4>全名:{{fullName}}</h4>
	
	<button @click="getFullName">获取计算属性</button>
</template>

<script>

	import {ref,toRefs,reactive,computed} from 'vue'
	export default{
		setup(){
			//reactive创建响应式数据对象
			const data = reactive({
				test:"测试",
				user:{
					name:"木道人",
					sex:"男"
				},
				list:["特斯拉","追梦","请叫我小平头"]
			})
			
			//创建一个响应式对象 user
			const user = reactive({
				firstName:"",
				lastName:""
			})
			
			//它会根据user的值 创建一个响应式的计算属性fullName 自动计算并返回一个新的响应式数据(ref)
			const fullName = computed(()=>{
				return user.firstName + " " + user.lastName
			})
			
			const getFullName = ()=>{
				console.log(fullName.value)
			}
			
			return{
				// 解构响应式对象数据
				/* 用 ...扩展运算解构响应式对象数据,是不可行。因为解构后就变成成了一个普通变量,不在具有响应式的能力 */
				// ...data 
				// toRefs 把一个响应式的对象转换成普通对象,对data进行了包装,再使用...拓展符的方式将data解构
				...toRefs(data),
				...toRefs(user),fullName,getFullName
			}
		}
	}
</script>
<style>
</style>

3.9(七)watch

watch()函数用来监视某些数据项的变化,从而触发某些特定的操作,使用之前需要按需导入:

注意:
1、监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)。
2、监视reactive定义的响应式数据中某个属性时:deep配置有效。

export default{
		setup(props,context){//composition API的入口
			const num = ref(0)
			const str = ref("测试")
			const state = reactive({
				id:101,
				uname:'莫愁'
			})
			
			//只要num有变化 会触发watch的回调 watch会在创建时自动调用
			// watch(()=>{console.log(num.value)})
			
			/* val:新的值 oval:旧的值 */
			watch(num,(val,oval)=>{
				console.log(val,oval)
				console.log("c num:",num.value)
			},{//第二个参数obj immediate deep
				immediate:false //默认就是只有数据改变时才会监听,第一次不会执行,设置true第一次也会执行
			})
			
			//侦听state下的id,数据的变化
			watch(state,(val,oval)=>{
				console.log("id:",val.id,oval)
			},{
				immediate:true ,//默认就是只有数据改变时才会监听,第一次不会执行,设置true第一次也会执行
				deep:true,//开启深度侦听 能够侦听到对象的属性值的变化
			})
			
			//单个侦听state下的uname
			watch(()=>state.uname,(uname,p)=>{
				console.log(uname,p)
			},{
				immediate:true ,//默认就是只有数据改变时才会监听,第一次不会执行,设置true第一次也会执行
			})
			//const s = toRefs(state)  watch(s.id,()=>{})  等于 ()=>state.id
			
			//多个侦听数据
			const stop = watch([()=>state.id,()=>state.uname],([id,uname],[oid,oname])=>{
				console.log("id:",id,oid)
				console.log("uname",uname,oname)
			})			
			return{
				num,stop,
				...toRefs(state)
			}
		}
	}

3.10(八)watchEffect函数【用到哪个、监视哪个】

watch的套路是:既要指明监视的属性,也要指明监视的回调。
watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。
watchEffect有点像computed

  • 1、但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
  • 2、而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。

在这里插入图片描述

3.11(九)API

在这里插入图片描述

Vue3.0也提供了 Composition API 形式的生命周期钩子,与Vue2.x中钩子对应关系如下:

  • beforeCreate===>setup()
  • created=======>setup()
  • beforeMount===>onBeforeMount
  • mounted=======>onMounted
  • beforeUpdate===>onBeforeUpdate
  • updated =======>onUpdated
  • beforeUnmount ==>onBeforeUnmount
  • unmounted =====>onUnmounted

3.12(十)自定义 hook函数【重点】

  • 什么是hook?—— 本质是一个函数,把setup函数中使用的Composition API进行了封装。
  • 类似于vue2.x中的混合机制mixin
  • 自定义hook的优势: 复用代码, 让setup中的逻辑更清楚易懂。

1、创建一个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;
}

2、在组件中使用

<template>
	<h2>我是HelloWorld组件</h2>
	<h2>当前点击时鼠标的坐标为:x:{{point.x}},y:{{point.y}}</h2>
</template>

<script>
	import usePoint from '../hooks/usePoint'
	export default {
		name:'HelloWorld',
		setup(){
			const point = usePoint()
			return {point}
		}
	}
</script>

四、其它 Composition API

1、shallowReactiveshallowRef

  • shallowReactive:只处理对象最外层属性的响应式(浅响应式)。

  • shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理。

  • 什么时候使用?

    1、如果有一个对象数据,结构比较深, 但变化时只是外层属性变化 ===> shallowReactive
    2、如果有一个对象数据,后续功能不会修改该对象中的属性,而是生新的对象来替换 ===>shallowRef

2、readonlyshallowReadonly

  • readonly: 让一个响应式数据变为只读的(深只读)。
  • shallowReadonly: 让一个响应式数据变为只读的(浅只读)。
  • 应用场景: 不希望数据被修改时。

3、toRawmarkRaw

toRaw:

  • 作用: 将一个由reactive生成的响应式对象转为普通对象
  • 使用场景: 用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。

markRaw:

  • 作用: 标记一个对象,使其永远不会再成为响应式对象。
  • 应用场景: ①有些值不应被设置为响应式的,例如复杂的第三方类库等。②当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。

4、customRef

  • 作用: 创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。
  • 实现防抖效果
<template>
  <input type="text" v-model="keyWord" />
  <h3>{{ keyWord }}</h3>
</template>

<script>
import { 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、provide

provide: 向子组件以及子孙组件传递数据。接收两个参数,第一个参数是key.即数据的名称;第二个参数为value,即数据的值

在这里插入图片描述

2、inject

inject: 接收父组件或祖先组件传递过来的数据。接收一个参数key,即父组件或祖先组件传递的数据名称

在这里插入图片描述

6、响应式数据的判断

  • isRef: 检查一个值是否为一个ref对象
  • isReactive: 检查一个对象是否是由 reactive创建的响应式代理
  • isReadonly: 检查一个对象是否是由readonly创建的只读代理
  • isProxy:检查一个对象是否是由 reactive 或者 readonly 方法创建的代理

五、新的组件

1、Fragment

  • 在Vue2中: 组件必须有一个根标签
  • 在Vue3中: 组件可以没有根标签, 内部会将多个标签包含在一个Fragment虚拟元素中
  • 好处: 减少标签层级, 减小内存占用

2、Teleport

什么是Teleport?—— Teleport 是一种能够将我们的组件html结构移动到指定位置的技术。

3、Suspense

等待异步组件时渲染一些额外内容,让应用有更好的用户体验。

六、vue3.x中集成typescript

6.1为什么要使用ts

  • 类型检查、直接编译到原生的js、引入语法糖。
  • TypeScript的设计目的应该是解决JavaScript的“痛点”:【弱类型、没有命名空间。导致很难模块化、不适合开发大型程序】;
  • 另外它还提供了一些语法糖来帮助大家更方便地实践面向对象的编程。

6.2vue-cli(脚手架)安装ts

在这里插入图片描述
在这里插入图片描述

6.3vite安装ts

在这里插入图片描述

6.4定义组件

如果要让TypeScript正确推断Vue组件选项中的类型,需要使用defineComponent全局方法定义组件:在这里插入图片描述

6.5案例代码

<template>
	<h2>集成ts与compositionAPI一起使用</h2>
	<h4>姓名:{{uname}}</h4>
	<h4>兴趣:{{hobby}}</h4>
	<h4>年龄:{{age}}</h4>
	<h5>getUNname:{{getUNname(111)}}</h5>
	<p>{{count}}</p>
	<button @click="setCount()">setCount</button>
</template>

<script lang="ts">
	//defineComponent 启用类型校验
	import {defineComponent,reactive,toRefs,ref} from 'vue'
	//约束data中的属性与方法
	interface user{
		uname:string,	
		hobby:string,
		age:number,
		getUNname(msg:string):string
	}
	export default defineComponent ({
		setup(){
			//  三种方式:  :  <>  as
			const data:user = reactive({
				uname:"肖雅涵",
				hobby:"舞蹈",
				age:20,
				getUNname(msg){
					return msg
				}
			})
			//不支持:这种方式约束类型
			// const count:number = ref(0)
			const count= ref<number>(0)
			function setCount(){
				count.value = 123
			}
			return{
				...toRefs(data),count,setCount
			}
		}
	})
</script>
<style>
</style>

七、组合式API结合vue-router

引入setup和Vue的组合式API,开辟了新的可能性,但要充分发挥Vue Router的潜力,我们需要使用一些新的函数来代替访问this和组件内导航守卫。
因为我们在setup里面没有访问this,所以我们不能在直接访问this.$router或this.$route。作为替代,我们使用useRouter和useRoute函数。

//引入路由
import {useRouter,useRoute} from 'vue-router'
export default{
	setup(){
		const router = useRouter()//等同于this.$router
		const route = useRoute()//等同于this.$route
		
	}
}

八、组合式API结合vuex

如果在使用Vue 中的 组合式API进行编写组件,就不能延续之前的写法(如: this. s t o r e ) 。 由 于 我 们 无 权 访 问 s e t u p 的 内 部 t h i s , 因 此 要 在 s e t u p 中 使 用 s t o r e , 可 以 调 用 该 u s e S t o r e 函 数 。 这 等 效 t h i s . store)。由于我们无权访问setup的内部this,因此要在setup中使用store,可以调用该useStore函数。这等效this. store)访setupthissetup使storeuseStorethis.store于使用Option API在组件内进行检索。

8.1setup中访问vuex

请注意,在模板中我们仍然可以访问$store,所以不需要在setup中返回store

九、resolve alias 别名定义

将会被传递到 @rollup/plugin-alias 作为它的 entries。也可以是一个对象,或一个 { find,replacement } 的数组.
当使用文件系统路径的别名时,请始终使用绝对路径。相对路径作别名值将按原样使用导致不会解析到文件系统路径中。

export default defineConfig({
  resolve: {
  alias: {
	  "@": path.resolve(__dirname, "src"),
	  "@comps": path.resolve(__dirname, "src/components"),
	  "@views": path.resolve(__dirname, "src/views"),
	  },
  },
  plugins: [vue()],
})

或者 数组的形式

import {defineConfig} from 'vite'
import path from "path";
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
	resolve: {
		alias: [{
			find: '@',
			replacement: path.resolve(__dirname, 'src')
		},
	{
		find: 'components',
		replacement: path.resolve(__dirname, 'src/components')
	}
],
},
	plugins: [vue()],
})

其他文章:【Vue】带你快速上手Vue3 - 使用 - Composition API - 响应式原理 - 新特性

在这里插入图片描述

  • 10
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
前端人年终技术升级 2h极速入门Vue3.0 年终岁尾,又到了打工人写总结的时候,各位前端工程师,今年你的总结里是否有“Vue3.0”的身影呢? 9月Vue3.0问世,对前端人来说,这是技术升级的一大步,同样也是一场学习效率的角逐。  不论你是: Vue2.x的老用户  or  没有接触过Vue的小白; 前端工程师  or  想从事前端岗位的学生   只要你与前端工作有关, Vue3.0的问世都可能是你脱颖而出的好机会! 抢先进阶,成为首批Vue3.0开发者,升职、加薪、找工作一路绿灯!   你为Vue3.0入门,准备了多少学习时间? 三天?五天?还是七天? 完全不需要!本门课程可以帮您在2小时内极速入门。 即刻学习 年终完成项目升级 Vue在全球拥有超130万用户,在不同场景中均有应用;在国内Vue是最火热的前端框架,迭代后Vue3.0框架更快捷、精悍,容易维护,同时还添加了新特性,对于前端工作者来说,这是一次重要的进阶。   To 学生党&求职者:提升简历丰富度、提高自身价值,增加面试成功的几率 To 前端工程师:完成现有项目的优化升级,全面适配Vue3.0,年终总结上又可以添上一笔啦! 精华知识+名师指导 Vue小白也能快速进阶 问:没有用过Vue2.0,可以直接学习Vue3.0吗? 答:没问题,本门课程着重于基础夯实,Vue小白也能轻松掌握。   问:学完本门课程,我可以得到什么? 答:你可以建立对Vue知识的认知;       了解Vue的基本使用与调试方法;       掌握Vue的常用指令。   问:2个小时的课程,知识要点全面吗? 答:课程围绕Vue3.0入门开讲,全套知识要点浓缩在2个小时的课程中,学员每一分钟都可以Get满满干货!   问:师资力量有保障吗? 答:本门课程邀请到了南京大学软件工程硕士汤小洋,作为CSDN学院金牌讲师,汤小洋老师在本站拥有超15万学员。  汤小洋老师曾就职于擎天科技、中软国际、华为等上市公司,从事软件开发及软件教育培训多年,具有丰富的实战经验,授课耐心细致,通俗易懂,风趣幽默,善于将复杂问题简单化,曾为多家知名企业进行软件开发实训。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java亮小白1997

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值