美文网首页
vue3.0 -初探 -持续更新中

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

作者: 人话博客 | 来源:发表于2021-12-23 19:39 被阅读0次

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

    • 传统的 vue-cli 方式
    ##首先保证本地的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。

    • 使用 vite 创建
    ## 创建工程
    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

    • ref 可以定义基本数据类型响应式,也可以定义对象类型数据响应式
      • 当你给 ref 传递基本数据类型时,其内部的.value是使用的Object.defineProperty来实现响应式。
      • 当给你ref传递对象类型数据是,其内部的.value是使用的 new Proxy 来实现响应式。
      • 使用 ref 定义响应式,想访问到真实的数据,必须加一个 .value
    • reactive 只能定义对象类型数据响应式

    持续更新中......

    相关文章

      网友评论

          本文标题:vue3.0 -初探 -持续更新中

          本文链接:https://www.haomeiwen.com/subject/sxhkqrtx.html