欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue3.0学习笔记

程序员文章站 2024-01-02 12:33:40
...

一、复习vue 2中的一些特性

  • 动态参数 :
1. v-bind缩写 :[key]=''
2. v-on缩写 @[event]=''
3. 动态参数格式为字符串,为null 时默认移除,非字符类型将会被警告
  • 防抖和节流:
如果某个组件仅使用一次,可以在 methods直接应用防抖
methods:{
 click: _.debounce(function(){})
}
  • 混入
  • 实用新功能:
browserlist
  • 位于根目录中,可以指定项目的目标浏览器范围
>1%
>5% in CN
5% in my stats
last 2 versions
Firefox ESR
Firefox > 20
not ie <=8
Firefox 12.1
since 2013 
  • 对于vue2来说,vue3主要添加和改进,并无重大更改
  • vue3源代码是用typescript写的
 

二、v3.0新特性

1. 性能
1) 双向响应原理由 Object.defineProperty改为Es6r Proxy,速度更快,颗粒度更大
2) 重写vodm,据说性能上更好了
3) 模板编译的优化
4) 更加高效的组件初始化。
2. Tree-Shaking支持,消除没有用到的代码,但都是有限的,有条件的,所以说这个插件正在优化,不是很完善。详细的Tree-Shaking说明 :https://juejin.cn/post/6844903544756109319。
3. Composition  API,其实是参考 了ReactHooks,可提高代码可复用性,另外,把Reactivity模块独立开来,使Vue3.0的响 应式模块可以与其他框架相组合。
  • reactive() 接收一个对象,返回一个响应式对象
    将 vue2中只需要在data() 中定义数据变成 vue3中需要用reactive函数或ref来创建响应式数据
    1)用reactive创建响应式对象
    // 在组件库中引入 reactive
    import { reactive } from '@vue/composition-api'
    

setup() {
// 创建响应式对象
const state = reactive({
count:0
});

// 将响应式对象return出去,暴露给模板使用
return state;

}​

2)使用响应式对象

<p>当前的count的值为:{{count}}</p>

<button @click=“count++”>点击增加count<button>

  • ref() 根据给定的值 创建 一个响应式对象,返回值是一个对象,且只包含一个.value属性
    1)用ref 创建响应式对象
    // 引入 ref
    import { ref } from '@vue/composition-api'
    
  • setup() {
    // 创建响应式对象
    const count = ref(0);

    return {
        count
    }
    

    }​

    reactive() 和 ref() 创建出来的响应式对象的区别:

    用 reactive() 创建的响应式对象,整个对象是响应式的,但对象里的值不是。
    而用 ref() 创建的响应式的值,本身就是响应式的,并不依赖于其他对象。

    2) 使用响应式对象

    <p>当前的count的值为:{{count}}</p>
    

    <button @click=“count++”>点击增加count</button>​

    3)ref注意事项

    在setup()函数中,ref()创建的响应式数据返回的是对象,需要 用.value来访问,而在setup()函数外部则不需要
    可以在reactive对象中访问ref()函数创建的响应式数据
    新的ref()会覆盖旧的ref()
  • computed() 只读计算属 性,返回一个ref()实例
    const count = ref(1)
    
  • // 创建一个计算属性,使其值比 count 大 1
    const bigCount = computed(() => count.value + 1)

    console.log(bigCount.value) // 输出 2
    bigCount.value++ // error 不可写​

     

    创建可读可写的计算属性
    const count = ref(1)
    

    // 创建一个 computed 计算属性,传入一个对象
    const bigCount = computed({
    // 取值函数
    get: () => (count.value + 1),
    // 赋值函数
    set: val => {
    count.value = val - 1
    }
    })

    // 给计算属性赋值的操作,会触发 set 函数
    bigCount.value = 9
    // 触发 set 函数后,count 的值会被更新
    console.log(count.value) // 8​

  • readonly()  返回一个只读的对象代理
    const state = reactive({ count: 0 })
    
  • const copy = readonly(state)

    watchEffect(() => {
    // 依赖追踪
    console.log(copy.count)
    })

    // state 上的修改会触发 copy 上的侦听
    state.count++

    // 这里只读属性不能被修改
    copy.count++ // warning!​

  • watchEffect() 初次渲染执行,在传入的函数依赖变更时重新运行
    //基本用法 :
    const count = ref(0)
    
  • // 初次直接执行,打印出 0
    watchEffect(() => console.log(count.value))

    setTimeout(() => {
    // 被侦听的数据发生变化,触发函数打印出 1
    count.value++
    }, 1000)​
    /*****************************************************************************/
    const stop = watchEffect(() => {
    /* … */
    })

    // 停止侦听
    stop()

  • watch 与vue2基本一样
    与watchEffect不同:
    1)初次渲染不执行
    2)侦听更具体
    3)可以访问侦听变化前后的值
    侦听单个数据源:
    // 侦听一个 getter
    const state = reactive({ count: 0 })
    watch(
      () => state.count,
      (count, prevCount) => {
        /* ... */
      }
    )
    
  • // 直接侦听一个 ref
    const count = ref(0)
    watch(count, (count, prevCount) => {
    /* … */
    })​

     

    侦听多个数据源:
    watch([ref1, ref2], ([newRef1, newRef2],   [prevRef1, prevRef2]) => {
      /* ... */
    })​

    composition-API 依赖工具

    1. isRef() 判断某个值是否为ref()创建 出来的响应式的值
      import { isRef } from '@vue/composition-api'
      

    const unwrapper = isRef(foo) ? foo.value : foo​

  • toRefs() 可以将 reactive()创建出来的响应式对象转换成内容为ref响应式的值的普通对象,当你需要展开 reactive()时,希望它的值也是响应式的就会用到它。
    import { toRefs } from '@vue/composition-api'
    
  • setup() {
    // 定义响应式数据对象
    const state = reactive({
    count: 0
    })

    // 定义简单的函数,使count每次+1
    const add = () =&gt; {
        state.count++
    }
    
    // 将setup函数的内容return出去,供外界使用
    return {
        // 将 state 展开导出,同时将其属性都转化为 ref 形式的响应式数据
        ...toRefs(state),
        add
    }
    

    }​

    <template>
        <div>
            <p>当前的count值为:{{count}}</p>
            <button @click="add">点击+1</button>
        </div>
    </template>



    4. Fragments, 不再限制只有一个template根节点, render函数 也可以返回数据,有点像React。Fragments。
    5. 支持Typescript。
    6.  Custom Renderer API 实现用DOM方式进行WebGL编程,也就是说可以在canvas上渲染了。详情:https://blog.csdn.net/liubangbo/article/details/114079301
     

    三、vue3.0体验

    初始化项目
    1. 使用脚手架创建 项目
    vue create my-Project 
    2. 安装 composition-api 
    npm i @vue/composition-api -s
    3. 使用插件
    //main.js 
    import Vue from 'vue'
    import VueCompositionAPI from '@vue/composition-api‘
    

    Vue.use(VueCompositionAPI )

     

    四、Setup 函数

    专门为组件提供的新属性, 为基于 Composition API 的新特性提供了统一入口
    methods、watch 、computed、data 的数据都会放在setup()函数中
    1. 执行时机
    beforeCreate >stepup>created
    2. 接口props数据
    props是setup()的一个形参,组件接收的数据可以在setup函数内访问到
    3. context 上下文对象
    context是setup()的第二个形参,它是一个上下文对象,可以通过context来访问Vue实例的this
     
    setup(props, context){
      // 查看或使用props中的参数
      // 查看或使用context
    }
    get 拦截
    1. 在 vue2 中,computedwatchrender 函数都会封装成一个 watcher 对象,这个 watcher 对象可以储存收集到的依赖,也可以触发收集到的依赖。vue3 中取消 watcher这个概念,变为 effect ,依赖通过全局的weakMap 进行储存。
    1. 依赖储存在一个全局变量 weakMap 中(上面源码中的 targetMap ),key 是 proxy 代理的对象,value 是一个新的 map,我们称为 map2 , map2 的 key 是我们读取的属性值,value 是被此属性收集到的所有依赖,是个 set 对象。为什么依赖用 weakMap 储存,其实是为了性能优化,假设我们监听的对象被我们手动的销毁掉,因为 weakMap 对对象的引用都是弱引用,所以对象和他的依赖占用的内存都会被自动清除。
    1. proxyget 劫持中,我们将收集到的依赖储存到全局的 weakMap 中,为了性能优化,只有触发 get 且属性值为 object 类型,才会继续的递归进行数据的监听。

      总结(摘抄).

    1. 事实上分析到现在来说,vue3 并没有什么太大变化,远不及 react 15 和 16 的变化。
    1. 新 api proxy 毫无疑问更加强大,那么可以说 vue 彻底放弃低版本 ie 的兼容。
    1. 新 diff 算法虽然速度快一点,但是多了最长递归子序列需要的空间。那么最终新 diff 带来的价值我个人感觉未必有那么大。
    1. 块优化,典型的空间复杂度换时间复杂度,且严重依赖于模板解析。可是在复杂应用中基本都要靠 jsx/render 函数来替代模板。那么对于复杂应用来说是不是浪费了一大波空间,但是时间复杂度倒没有发生改善。
    1. ref 包装一层 value 的结构,会不会当时间久了,或者数据传递层级多了。你都分不清 value 是因为数据自身本来就有 vue 还是因为 ref 包装的 value。
    1. ts 更加完美支持是好事,之前 vue2 出现类型推导断层确实是难受,vue3 算是用函数的方式完美支持了 ts,但是模板里面的 ts 推导怎么处理,目前还不确定,这个应该veturvue 团队一起发力。

    感想如下:

    1. 将 computed,data,生命周期全部放到 setup 函数里面。ts 对函数的类型推导已经很完美,也不需要考虑如何弥补逻辑断层从而挂载在 this 上。render 函数里面直接传递 methods 等值,感觉 新语法+tsx 很完美。
    1. 类 hooks 语法,逻辑复用的粒度更细,也解决了命名冲突,额外组件实例等问题。
    1. 看解释说 createComponent 内部实现是个 noop(直接返回参数本身)。这个作用是给 TSX 和 Vetur 的模版自动补全。
    1. 之前 options base 的时候,data,methods,watch 等等都清晰的分开,现在全部放在 setup,会不会很乱?
    1. 新api proxy毫无疑问更加强大,那么可以说vue彻底放弃低版本ie的兼容。
    1. 新diff算法虽然速度快一点,但是多了最长递归子序列需要的空间。那么最终新diff带来的价值我个人感觉未必有那么大。
    1. 块优化,典型的空间复杂度换时间复杂度。但是毕竟严重依赖于模板解析。但是在复杂应用中基本都要靠jsx表达式来替代模板。那么对于复杂应用来说是不是浪费了一大波空间,但是时间复杂度倒没有发生改善。
    1. ref包装一层value的结构,会不会当时间久了,或者数据传递层级多了。你都分不清value是因为数据自身本来就有vue还是因为ref。

上一篇:

下一篇: