美文网首页
Vue3 新特性

Vue3 新特性

作者: 我是Msorry | 来源:发表于2021-01-13 15:41 被阅读0次
    • 重构响应式系统,使用Proxy替换Object.defineProperty,使用Proxy优势:
    • 可直接监听数组类型的数据变化
    • 监听的目标为对象本身,不需要像Object.defineProperty一样遍历每个属性,有一定的性能提升
    • 可拦截 applyownKeyshas等13种方法,而Object.defineProperty不行
    • 直接实现对象属性的新增/删除
    • 新增 Composition API,更好的逻辑复用和代码组织
    • 重构 Virtual DOM
    • 模板编译时的优化,将一些静态节点编译成常量
    • slot 优化,将 slot 编译为 lazy 函数,将 slot 的渲染的决定权交给子组件
    • 模板中内联事件的提取并重用(原本每次渲染都重新生成内联函数)
    • 代码结构调整,更便于Tree shaking,使得体积更小
    • 使用 Typescript 替换 Flow

    使用 Composition API

    1. setup
     export default {
         props: {
            str: String
         },
         setup(props, context) {
             console.log(props) // str
             console.log(context)  // attrs, slots, parent, root, emit, refs
         },
     }
    
    1. relative
     import { reactive } from 'vue'
     export default {
         setup() {
             const state = reactive({count: 0}) // 创建响应式数据对象
             return state //将响应式数据对象 return 出去,供 template 使用
         }
     }
    
    1. ref
      ref() 函数根据给定的值创建一个响应式的数据对象,返回值是一个对象,这个对象上只包含一个 .value 属性
     import { ref } from 'vue'
     export default {
         setup() {
             const count = ref(0) // 创建响应式数据对象 count,初始值为 0
             console.log(count.value) // 在setup内访问count值需要.value 属性才可以,但在template中可以直接访问
             return {
                count
             }
         },
     }
    
    1. toRefs
      toRefs() 函数可以将 reactive() 创建出来的响应式对象,转换为普通的对象,只不过,这个对象上的每个属性节点,都是 ref() 类型的响应式数据
    
     import { reactive, toRefs } from 'vue'
    
     export default {
    
         setup() {
             const state = reactive({count: 0, name:'weedsFly'}) // 用reactive集中创建多个响应式对象
             const add = () => { // methods写在setup内
                 state.count++
             }
             return {
                 // ...state,  // 使用展开运算符后 用reactive创建的响应式数据 变成了 固定的值
                 ...toRefs(state), // 可以用toRefs函数 将传进来的非响应式对象 转成 ref() 类型的响应式数据
    
                 add
            }
        },
     }
    
    1. watch
      1. 监视单个数据源变动

    监视单个 reactive 创建的数据源

    
     import { reactive, watch } from 'vue'
    
     export default {
         setup() {
             const state = reactive({count: 100}) 
             watch(
                 () => state.count,
                 (newVal, oldVal) => { console.log(newVal, oldVal)},
                 {lazy: true} // 在 watch 被创建的时候,不执行回调函数中的代码
             )
             setTimeout(() => {
                state.count++
             }, 1500)
         }
     }
    

    监视单个 ref 创建的数据源

    
     import { ref, watch } from 'vue'
    
     export default {
         setup() {
             const count = ref(100) 
             watch(
                 count,
                 (newVal, oldVal) => { console.log(newVal, oldVal)},
                 {lazy: true} // 在 watch 被创建的时候,不执行回调函数中的代码
             )
             setTimeout(() => {
                count++
             }, 1500)
         }
     }
    
      1. 监视多个数据源

    监视多个 reactive 创建的数据源

    
     import { reactive, watch } from 'vue'
    
     export default {
         setup() {
         const state = reactive({count: 100, name: 'Laiyj'})
         watch(
             [() => state.count, () => state.name],
             ([newCount, newName], [oldCount, oldName]) => { 
                 console.log(newCount, oldCount)
                 console.log(newName, oldName)
             },
             {lazy: true} // 在 watch 被创建的时候,不执行回调函数中的代码
         )
         setTimeout(() => {
             state.count++
             state.name = 'Lucy'
         }, 1000)
         }
     }
    

    监视多个 ref 创建的数据源

    
     import { ref, watch } from 'vue'
    
     export default {
         setup() {
             const count = ref(100)
             const name = ref('Laiyj')
             watch(
                 [count, name],
                 ([newCount, newName], [oldCount, oldName]) => {
                     console.log(newCount, oldCount)
                     console.log(newName, oldName)
                 },
                 {lazy: true} // 在 watch 被创建的时候,不执行回调函数中的代码
             )
             setTimeout(() => {
                 count++
                 name = 'Lucy'
             }, 1000)
         }
     }
    
      1. 清除watch监视
    
     import { ref, watch } from 'vue'
    
     export default {
         setup() {
             const count = ref(100)
             const stop = watch( // 创建监视,并得到 停止函数
                 count,
                 (newVal, oldVal) => {
                     console.log('I am watching.')
                     console.log(newVal, oldVal)
                 },
                 {lazy: true} // 在 watch 被创建的时候,不执行回调函数中的代码
             )
             setTimeout(() => {
                count++
             }, 1000)
             const clearWatch = () => {
                stop()
             }
             return {
                 count,
                 clearWatch
             }
         }
     }
    
      1. 在 watch 中清除无效的异步任务(与节流防抖同效)
    
     import { ref, watch } from 'vue'
    
     export default {
         setup() {
             const keyword = ref('')
             const asyncPrint = (val) => { // 执行异步任务,并得到关闭异步任务的 timerId
                 return setTimeout(() => {
                    console.log(val)
                 }, 1000)
             }
             watch(
                 keyword,
                 (newVal, oldVal, onClean) => {
                     const timeId = asyncPrint()
                     onClean(() => {clearTimeout(timeId)}) // 如果 watch 监听被重复执行了,则会先清除上次未完成的异步任务
                 }
             )
             return {
                 keyword
             }
         }
     }
    
    1. provide & inject
      provide() 和 inject() 可以实现嵌套组件之间的数据传递。
      这两个函数只能在 setup() 函数中使用。
      父级组件中使用 provide() 函数向下传递数据;子级组件中使用 inject() 获取上层传递过来的数据。

    相关文章

      网友评论

          本文标题:Vue3 新特性

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