vue3.0 -初探 -持续更新中

2021-12-23  本文已影响0人  人话博客

一.创建vue工程方式有两种

##首先保证本地的vue-cli版本在4.5.0以上
vue --version
##如果不是,先升级最新的vue-cli工具
npm i -g @vue\vue-cli
## 然后和之前的创建vue2的方式一样。
vue init webapack <project-name> ## 打包工具指定的是webpack
## 在后续list中,选择[vue3]即可。

传统的方式创建vue3,也没问题,但是这样一来的打包工具仍然是webpack。

## 创建工程
npm init vite-app <project-name> # 指定了脚手架为vite 以及项目框架是vue3.x [为什么是vue3.0框架?因为这个vite工具就是vue3开发团队写的,所以人家直接默认就用 vite-app 创建的项目就是基于 vue3.0]

## 进入功能目录
cd <project-name>
## 安装依赖
npm install
## 运行 
npm run dev

使用 vite 方式创建,打包工具就是 vite 了,项目也没有什么 build 文件夹,以及一堆 webpack.config.js webpack.base.js xxxxxx

二、 vue3.0中main.js文件

在 vue2.x 中,我们的 main.js 是这么写的。

import Vue from 'vue'
import App from './App'

const vm = new Vue({
    render(h) => h(App)
})
vm.$mount('#app')

在 vue3.0中是这么写的。

import { createApp } from 'vue'
import App from './App'

const app = createApp(App)
app.mount('#app')

在vue2.0中,我们直接调用 new Vue 构造函数创建一个vm实例。在v3.0中,我们使用 createApp函数,传递进去一个options对象,来创建一个app实例。 后面的挂载都是一样的。

你把 app 和 vm 打印到控制台查看一下,就会发现 app 比 vm 属性少很多,也就是说 vue3.0 里的 app 更为轻量。

三、 Vue3.0中的 setup 函数

在 vue2.x 中,我们定义组件的数据,方法,计算属性,watch等都是以配置选项的方式来进行的。

export default {
    name: 'App',
    data () {
        return {
            num:1
        }
    },
    methods: {},
    computed: {},
    watch: {}
}

在 vue3.0 中,所有需要的上述组件配置,都应该定义在 setup 函数里,并返回。(为什么要返回?返回才会挂载在当前组件实例上,才能在模板中使用。)

export default {
    name: 'App',
    setup () {
        // 我定义的函数
        // 我定义的数据
        // 我定义的watch
        // 我定义的计算属性
        // .....
        return {
            我定义的函数,
            我定义的数据,
            我定义的,
            我定义的计算属性
        }
    }
    
}

四、vue3.0中的ref函数

vue2.0 和 vue3.0 配置数据响应式也有区别。

在 vue2.0中,我们把数据放在 data 选项里,就可以完成响应式的配置了。

在vue3.0中,提供了更精细化的响应式数据配置。

// vue3.0 ref 函数功能说明
import { ref } from 'vue'
export default {
    name: 'App',
    setup () {
        // 定义一个基本数据类型响应式
        let num = ref(100)
        // 返回的是一个 RefImpl 的对象 RefImpl { ......}
        // 使用num
        num.value = 100  // 触发setter
        console.log(num.value) // 触发getter
        // 定义一个对象类型数
        let obj = ref({
            name: '张三-老工具人了',
            job: {
                detail: {
                    title: '前端开发',
                    salary: 30
                }
            }
        })
        
        // 修改name属性
        obj.value.name = '李四' //
        obj.value.job.detail.title = 'python开发' 
        // tips: 可能有人觉得,obj.value.xxx 不如 obj.xxx 直接来的直观,但是 ref 定义数据响应式就是有这么一个特点。
        
        return {
            num, // 在模板中,使用num,不需要加.value
            obj
        }   
    }
}

// ref 函数内部逻辑
// 1. 如果你传递的参数是基本数据类型,那么内部直接使用Object.defineProperty来定义一个新属性叫.value来实现响应式。
// 2. 如果你传递的是一个对象数据类型,那么内部使用 new Proxy 来定义数据的响应式。
// 所以,对于ref来说,内部选择使用 Object.defineProperty 还是 new Proxy 取决于你传递进来的数据.
// 大概逻辑如下.
function ref (value) {
    return new RefImpl(value)
}

function RefImpl (value) {
    this.__v_Ref = true
    this.__rawValue = value
    this.__newValue = value
    // this.__shallowRef = fasle
    if (typeof value !== 'object') {
        Object.define(this,'value', {
            get () {
                return this.__newValue
            },
            set (newVal) {
                this.__newValue = newVal
            }
        })
    } else {
        this.value = new Proxy (this,{
            get (target,propertyName) {
                return Reflect.get(target,propertyName)
            },
             set (target,propertyName,value) {
                Reflect.set(target,proeprtyName,value)
             },
            deleteProperty (target,propertyName) {
                //...监听delete属性操作...
                Reflect.delete(target,propertyName)
            },
        })
    }
}

如果你给 ref 传递的是基本数据类型,那么 .value 拿到的就是由 Object.defineProperty定义的那个 .value 属性。

如果你给 ref 传递的是对象数据类型,那么 .value 拿到的就是有 new Proxy 定义的那个对象。

五、 vue3.0 中的 reactive 函数

在ref函数介绍里,我们有这么一段代码

let obj = ref({
    name: '张三-老工具人了',
    job: {
        detail: {
            title: '前端开发',
            salary: 30
        }
    }
})
obj.value.name = '李四' //
obj.value.job.detail.title = 'python开发' 
// 可能有人觉得,obj.value.xxx 不如 obj.xxx 直接来的直观,但是 ref 定义数据响应式就是有这么一个特点。

可能有人觉得,obj.value.xxx 不如 obj.xxx 直接来的直观,但是 ref 定义数据响应式就是有这么一个特点。

所以,使用 ref 定义对象类型数据,并不是很好的方式。

于是就有了 reactive 函数。

import { reactive } from 'vue'
export default {
    name:'App',
    setup () {
        let person = reactive({
             name: '张三-老工具人了',
            job: {
                    detail: {
                        title: '前端开发',
                        salary: 30
                    }
                }
        })
        
        /// 访问数据
        console.log(person.name)
        // 修改属性
        person.job.detail.title = 'python开发' // 就没有烦人的.value了。
        
        return {
            person
        }
    }
    
}

所以,对于对象数据类型,使用 reactive 比 ref 更为合适。

建议: 基本数据类型,使用 ref, 对象类型使用 reactive

注意:不要给基本数据类型使用reactive做响应式,否则被报错

let num = reactive(0)

value cannot be made reactive: 0

总结ref和reactive

持续更新中......

上一篇下一篇

猜你喜欢

热点阅读