初识Vue3

本文详细介绍了如何创建Vue3项目,包括使用vue-cli和vite的方法,并深入探讨了Vue3的响应式原理,对比Vue2的响应式差异。同时,解析了setup()、ref()和reactive()的使用,以及它们之间的区别。文章还提供了实际的代码示例,帮助理解Vue3的新特性和优势。


Vue3.0发布至今已有20个月了,虽然公司还未进行Vue3的项目,但前端的技术更新迭代很快,那就把自己卷起来。
本文介绍了如何创建Vue3项目,重点介绍了setup()函数、ref()函数、 reactive()函数。总结了2.x与3.x中响应式原理,ref与reactive的区别

1、认识Vue3

Vue3.0于2020年09月18日已正式发布,开发过程中有100多位贡献者,2600多次代码提交,600多次PR,相比Vue2.x上作出很多优化。Vue3很好的支持Vue2的大多数特性,目前属于2.x到3.x的过渡期,Vue3很好的兼容Vue2.x的语法,此外,3.x版本能更好的支持TypeScript。此外,还有几个性能上的提升:

1)打包大小减少41%

2)模板编译速度提升,初次渲染快55%,更新渲染快133%

3)内存减少54%

4)使用Proxy代替defineProperty,实现数据响应式

5)重写虚拟DOM的实现和Tree-Shaking(摇树,保留最重要的)

6)可以有很多根节点

2、创建Vue3项目
法1:使用vue-cli创建

注意:必须保证vue cli在4.5.0版本以上

文档:https://clivuejs.org/zh/guide/creating-a-project.html#vue-create

vue --version   或 vue -V  //查看版本
npm uninstall vue-cli -g   //卸载版本   
npn install -g vue/cli    //安装vue-cli
vue create wlvue3    //创建项目   项目名称只能全小写

安装完成后,键入npm run serve启动项目

安装element plus组件库

npm install element-plus --save    或npm install -S element3  
//main.js引入
import elementPlus from 'element-plus'
createApp(App).use(elementPlus).mount('#app')

注意: 1、elementUI是基于Vue2.x版本开发的,需要安装elementUI升级版本element plus

​ 2、Vue3开始使用函数式编程,因此可以使用链式调用。

添加Vue3的工具

Vue3有专用的调试工具,可在谷歌商店自行下载

在这里插入图片描述

法2:使用vite创建:

注意:vite由vue团队开发的,依赖的node版本高于12.0.0;

vite还没有大规模应用,本次示例依然使用cli创建项目

1)vite官网地址:https://vitejs.cn/

2)vite是一个由原生ESM驱动的Web 开发构建工具。在开发环境下基于浏览器原生ES imports开发的

3)做到了本地快速开发启动,在生产环境下基于Rollup打包。

快速的冷启动,不需要等待打包操作;轻量的热承载;

即时的热模块更新,替换性能和模块数量的解耦让更新飞起;

真正的按需编译,不再等待整个应用编译完成,这是一个巨大的改变。

npm init vite@latest
npm install 或 npm i
npm run dev

手动从空文件夹到安装所有

npm install -y
npm install ts-node -g
npm install @types/node -D
npm install express -S
npm install @types/express -D
npm install axios -D

构建vue项目

npm init vue@latest
npm init vite@latest   //两者都行
3、项目结构及单页内容
1 )入口文件main.js
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)  
app.mount('#app')   //挂载

Vue3不再引入Vue构造函数,而是createApp工厂函数,创建的应用示例对象app,类似于之前的vm,但app比vm更轻

2)App.vue文件
<template>
  <login></login>
</template>

单页内容可以没有根节点div

3) 组合式的Composition APl

常用的有setup()、ref()、 reactive()、isRef()、toRefs()、computed()、watch()等

a、setup()函数

setup()函数是Vue3中,专为组件提供的新属性,为Composition APl 新特性提供统一入口,是一个配置项。Vue过去的data,methods,watch等都配置在setup()函数中。

注意:*setup()函数的使用,尽量不要Vue2与Vue3混用。因为Vue2.x的配置可以访问到setup的属性方法,但setup中不能访问到Vue2.x配置,如果有重名,setup优先;

*setup不能是async函数,因为返回值不再是return对象,而是promise,模板看不到return对象中的属性

​ *props:用来接收props的数据

​ *context:用来定义上下文,上下文包含了一些属性,在Vue2中这些属性需要this才能访问,在setup()中,this是undefined无法被访问

setup(props,context) { //context上下文对象
    context.attrs  //值为对象,包含组件外部传递过来,但没有在props配置中声明的属性,相当于vue2的this.$attrs.
    context.slots  //收到的插槽内容,相当于vue2的this.$slots
    context.emit 	//分发自定义事件的函数,相当于vue2的this.$emit
    context.refs
    return{}
}
b、ref()函数

定义一个响应式数据,处理基本类型数据,响应式依然是靠Object.defineProperty()的get与set

let name = ref('李四')
template读取:<span>{{name}}</span>
js中获取ref的值:name.value

基本类型响应式数据:

在这里插入图片描述

c、reactive()函数

定义了一个对象类型的响应式数据,里面封装了proxy函数,其定义的响应式数据是深层次的,内部基于ES6的Proxy实现,通过代理对象操作源对象内部数据。创建出对象类型数据后,在setup中return出去,在template中调用

对象类型响应式数据:
在这里插入图片描述

总体代码演示

<template>
    <h3>姓名:{{name}}</h3>
    <h3>年龄:{{age}}</h3>
    <h3>工作种类:{{obj.type}}</h3>
    <h3>薪水:{{obj.salary}}</h3>
    <el-button @click="changeInfo">修改个人信息</el-button>
</template>
<script>
    import {h} from 'vue'
    import {reactive, ref} from "@vue/reactivity";
  export default {
    name: "login",
    setup () {
      let name = ref('张三')
      let age = ref(12)
      let obj = reactive({
        type:'前端工程师',
        salary:'30k'
      })
     function changeInfo() {   //方法
           name.value='李四'
           age.value=111
           obj.type='UI设计'
           obj.salary='21k'
       console.log(name,age,obj)
     }
      return{   //返回一个对象
        input,
        name,
        age,
        obj,
        sayHello,
        changeInfo
      }
        // return ()=>h('h1','员工')  //返回一个渲染函数
    }
  }
</script>
4、比较Vue2与Vue3的响应式原理
1) Vue2.x的响应式原理

对象类型实现原理:通过Object.defineProperty()对属性的读取、修改进行拦截、数据劫持;

数组类型实现原理:通过重写更改数组的一系列方法来实现拦截。(对数组的变更方法进行包裹)

Object.defineProperty(data,'count',{
    get(){},
    set(){}
})
存在问题:

新增、删除属性,界面不会更新

直接通过下标修改数组,界面不会自动更新

2) Vue3的响应式原理

通过Proxy(代理),拦截对象中任意属性的变化,包括:属性的读写、添加、删除等

通过Reflect(反射):对被代理对象(源对象)的属性进行操作

new Proxy(data,{
    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)    
    },
})

代码展示

setup () {
  let name = ref('张三')
  let age = ref(12)
  let obj = reactive({
    type:'前端工程师',
    salary:'30k',
    hobby : ['学习','运动']
  })
 function changeInfo() { //改
       name.value='李四'
       age.value=111
       obj.type='UI设计'
       obj.salary='21k'
  	    obj.hobby[0] = '修改后爱好'
 }
 function addInfo() { //增
   obj.sex = '女'
   obj.hobby[2] ='篮球'
 }
 function deleteSalary() { //删
   delete obj.salary
   delete obj.hobby[1]
 }
  return{
    name,
    age,
    obj,
    changeInfo,
    addInfo,
    deleteSalary
  }
}
5、ref与reactive对比
从定义数据角度:

​ ref用来定义:基本数据类型

​ reactive用来定义:对象(或数组)类型数据

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

从原理角度对比:

​ ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)

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

从使用角度对比:

​ ref定义的数据:操作数据需要.value,读取数据时直接读取

​ reactive定义的数据:操作与读取数据,不需要.value

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值