Vue3.0 学习总结

自Vue3.0发布后,借着空闲摸鱼的时间还有下班后的时间,零零散散的看过几篇大佬们总结的Vue3.0的相关内容知识,但是因为公司项目中Vue3.0暂时无法使用,脑子中没有一个很完整地概念,总感觉知识体系是这一块那一块拼凑起来的,所以借着写这篇文章总结一下。之前没仔细看过官网文档,所以这次主要是看文档加自己理解。有哪里不对,还望各位,不吝指教。(PS:这次也算是自己逼着自己分享的,之前想写一点东西,但是总不知要写点什么,算是第一次正儿八经的写🤦‍♂️🤦‍♂️🤦‍♂️。文笔不好,基础不牢,大佬们轻喷🍗🍗🍗)

安装

  • 通过脚手架 vue/cli

    命令行输入vue create <project name>,然后会出现下图所示的选项,可以选择Vue2.x、Vue3.x版本来创建项目,这里需要注意vue/cli 的版本需要大于4.5 ,否则输入以上命令后,默认是以Vue2.x创建项目的。

  • 通过Vite

    命令行输入npm init vite <project-name> -- --template vue

值得注意的新特性

组合式API - Composition Api

1. 为什么?

在Vue2.x中,我们通常使用data、methods、computed等组件选项来组织业务逻辑,如果功能项不多,开发起来还相对轻松;但是一旦页面功能增加,开发时就要在各个选项内来回跳转,开发体验极其不好。同时这种碎片化使得理解和维护组件变的困难,功能模块复用也比较麻烦。

2. 组合式API与传统方式(Option Api)的对比

这里推荐 @大帅老猿 老师的做了一夜动画,就为让大家更好的理解Vue3的Composition Api,简单生动易懂。

3. 组合式API的入口setup
参数(props, context)
  • props
    setup函数中的props是响应式的,当传入新的prop时,它将被更新。

    javascript 复制代码
        export default {
          props: {
            title: String
          },
          setup(props) {
            console.log(props.title)
          }
        }

    Tips :但是因为props是响应式的,不能使用ES6解构,它会消除prop的的响应式。如果需要解构prop,可以在setup函数中使用toRefs函数完成此操作。对于这一块的个人理解:直接使用解构取得元素,直接消除了Proxy对数据的响应式包装,直接把封装好的数据的.value值取出(好像😂),返回普通的元素对象;而使用了toRefs函数后,则每个数据都是ObjectRefImpl对象,保持响应式。这里贴一下ES6解构的原理理解

    javascript 复制代码
           const book = reactive({
             author: 'Vue Team',
             year: '2020',
             title: 'Vue 3 Guide',
             description: 'You are reading this book right now ;)',
             price: {
               after: 11,
               before: 22
             }
           })
           let formatBook = toRefs(book)
           let { price: p } = toRefs(book)
           let { price } = book
           console.log(formatBook)
           console.log(p)
           console.log(p.value)
           console.log(price)
           
           // 分别输出
           // {author: ObjectRefImpl, year: ObjectRefImpl, title: ObjectRefImpl, description: ObjectRefImpl, price: ObjectRefImpl}
           // ObjectRefImpl {_object: Proxy, _key: "price", __v_isRef: true}
           // Proxy {after: 11, before: 22}
           // Proxy {after: 11, before: 22}
  • Context
    context是一个普通的javascript对象,它暴露组件的三个属性:attrsslotsemit,这些属性在Vue2.x中需要通过this才能访问到,它不是响应式的,意味着你可以安全的对context使用解构。(名词解释摘自官网文档)

    1. attrs-->(V2)this.$attrs:包含了父作用域中不作为prop被识别(且获取)的attribute绑定。
    javascript 复制代码
            // 父组件
            <template>
                <Test v-model:name="userName" cn="china"></Test>
            </template>
            
            // 子组件 Test.vue
            <template>
              <div>Test {{ name }}</div> 
            </template>
            <script>
            export default {
                props: {
                    name: String
                },
                setup(props, context) {
                    let { attrs } = context
                    return {
                        cn: attrs.cn // china
                    }
                }
            }
            </script>
    1. slots-->(V2)this.$slots:用来分发被插槽分发的内容;每个具名插槽有其相应的property;default property包括了所有没有在具名插槽中的节点或v-slot:default的内容。
    javascript 复制代码
            // 父组件
            <Init>
               <div>D E F A U L T</div>
               <template v-slot:footer>
                  <div>T H I S I S F O O T E R</div>
               </template>
           </Init>
           
           // 子组件
           <template>
               <slot></slot>
               <slot name="footer"></slot>
           </template>
           <script>
           export default {
               setup(props, context) {
                   let { slots } = context
                   console.log(slots)
                   // Proxy {_: 1, __vInternal: 1, footer: ƒ, default: ƒ}
               }
           }
           </script>
    1. emit-->(V2)this.$emit
访问组件的property

先看下setup的运行时间:

javascript 复制代码
export default {
    setup(props, context) {
        console.log('setup')
    },
    beforeCreate() {
        console.log('beforeCreate')
    },
    created() {
        console.log('created')
    },
    
    // 输出
    // setup
    // beforeCreate
    // created
}

执行setup时,组件实例尚未被创建。因此只能访问一下property:props,attrs,slots,emit,换句话说,你将无法访问一下组件选项:data,computed,methods

使用this

在setup()内部,this不是该活跃实例的引用,因为setup()是在解析其他组件选项之前被调用的,所以setup()内部的this的行为与其他选项中的this完全不同。

生命周期钩子
选项式 API Hook inside setup
beforeCreate Not needed*
created Not needed*
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeUnmount onBeforeUnmount
unmounted onUnmounted
errorCaptured onErrorCaptured
renderTracked onRenderTracked
renderTriggered onRenderTriggered
activated onActivated
deactivated onDeactivated

setup这个函数是在beforeCreate和created之前运行的,所以可以用它来代替这两个钩子函数。项目开发过程中尽量避免两种生命周期的混用。

4. 响应性API
reactive

返回对象的响应式副本;响应式转换是"深层"的 --- 它影响所有嵌套property。

这里推荐 深入源码理解Vue3 reactive

readonly

接受一个对象(响应式或纯对象)或ref并返回原始对象的只读代理。只读代理是深层的:任何被访问的嵌套property也是只读的。

javascript 复制代码
const original = reactive({ count: 0 })
const copy = readonly(original)
copy.count++ // 变更副本将失败并导致警告
ref

接受一个内部值(通常是基本数据类型)并返回一个响应式且可变的ref的对象。ref对象具有指向内部值的单个property.value

这里推荐 深入源码剖析Vue3 ref

javascript 复制代码
const count = ref(0)
toRef

可以用来为源响应式对象上的某个property新创建一个ref。然后,ref可以被传递,它会保持对其源property的响应式连接。

javascript 复制代码
const state = reactive({
  foo: 1,
  bar: 2
})
const fooRef = toRef(state, 'foo')
state.foo++
console.log(fooRef.value)  // 2
toRefs

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

javascript 复制代码
const state = reactive({
  foo: 1,
  bar: 2
})
const format = toRefs(state)
console.log(state)
console.log(format)

// state:  Proxy {foo: 1, bar: 2}
// format:
/**
    {foo: ObjectRefImpl, bar: ObjectRefImpl}
        bar: ObjectRefImpl {_object: Proxy, _key: "bar", __v_isRef: true}
        foo: ObjectRefImpl {_object: Proxy, _key: "foo", __v_isRef: true}
**/
相关推荐
汤姆Tom2 小时前
CSS 新特性与未来趋势
前端·css·面试
尘世中一位迷途小书童2 小时前
🚀 pnpm + Monorepo 实战指南:现代前端项目管理的最佳实践
前端·架构
杨超越luckly3 小时前
HTML应用指南:利用GET请求获取全国中国建设银行网点位置信息
前端·arcgis·html·数据可视化·门店数据
王翼鹏3 小时前
html 全角空格和半角空格
前端·html
敲代码的嘎仔3 小时前
JavaWeb零基础学习Day2——JS & Vue
java·开发语言·前端·javascript·数据结构·学习·算法
CsharpDev-奶豆哥3 小时前
jq获取html字符串中的图片逐个修改并覆盖原html的解决方案
前端·html
IT_陈寒3 小时前
Python性能优化:用这5个鲜为人知的内置函数让你的代码提速50%
前端·人工智能·后端
简小瑞3 小时前
VSCode源码解密:一行代码解决内存泄漏难题
前端·设计模式·visual studio code
邢行行3 小时前
Node.js 核心模块与模块化笔记
前端