vue 3.x新特性

【知乎 - Vue Function-based API RFC】https://zhuanlan.zhihu.com/p/68477600

【 vuejs/composition-api - api文档】https://vue-composition-api-rfc.netlify.com/#summary

【github - vuejs/composition-api】https://github.com/vuejs/composition-api

 

根据 vue 作者尤雨溪去年发布的 vue 3.0 开发路线,vue 3.0 很可能在 2019 年下半年与大家见面。

与此同时,今年下半年初,Vue 团队先后对外发布了 vue-function-api 和 vue-compisition-api 的 RFC,供开发者提前体验 vue 3.0 的新特性,并且希望通过这些预览版的 API,来征求广大开发者的意见与反馈,从而为 vue 3.0 的后续开发和落地打下坚实与稳定的基础。

一、vue3.0将从头开始重写

2018年9 月 30 日,尤雨溪在 medium 个人博客上发布了 Vue 3.0 的开发路线,我们不妨看看 Vue 3.0 将会有怎样的发展。

兼容

按照尤雨溪的说法,因为 Vue 3.0 是主要版本,所以会包含一些重大变更。不过,开发组会非常重视兼容性问题,他们也将尽快开始传达这些重大变更,并做了这样的保证:除了渲染函数 API 和作用域插槽语法之外的所有内容都将保持不变,或者通过兼容性构建让其与 2.x 保持兼容。

总的来说,Vue 3.0 虽然会对顶级 API 进行重大的修整,但依然会保持与 2.x 的兼容。此外,2.x 的最后一个次要版本将成为 LTS,并在 3.0 发布后继续享受 18 个月的 bug 和安全修复更新。

重构

为了实现更清晰、更易维护的源代码架构,尤雨溪表示将从头开始重写 3.0,并将一些内部功能分解为单独的包,以便隔离复杂性。

vue 3.x新特性_第1张图片

新的源代码结构(有可能会变化)

此外,代码库现在也用 TypeScript 编写,相信 TypeScript 的类型系统和 IDE 的支持将让新的代码贡献者更容易做出有意义的贡献。

其他的改进

  • 改进编译器
  • 支持 IE 11
  • 其他运行时改进
  • 改进观察机制

 

二、Vue 3.0中的Composition-API尝鲜

虽然 Vue 3.0 尚未发布,但是其处于 RFC 阶段的 Composition API 已经可以通过插件 @vue/composition-api 进行体验了。

1、使用 Composition-API 风格重构逻辑

安装 @vue/composition-api 插件以后,按照文档在 main.js 引用便开启了 Composition API 的能力。

  • main.js
import Vue from 'vue' import App from './App.vue' 
import VueCompositionApi from '@vue/composition-api' 

Vue.config.productionTip = false 
Vue.use(VueCompositionApi) 

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

回到 App.vue,从 @vue/composition-api 插件引入 { reactive, computed, toRefs } 三个函数:

import { reactive, computed, toRefs } from '@vue/composition-api'

仅保留 components: { ... } 选项,删除其他的,然后写入 setup() 函数:

export default { 
    components: { ... }, 
    setup () {} 
}

接下来,我们将会在 setup() 函数里面重写之前的逻辑。

 

首先定义数据。

为了让数据具备“响应式”的能力,我们需要使用 reactive() 或者 ref() 函数来对其进行包装,关于这两个函数的差异,会在后续的章节里面阐述,现在我们先使用 reactive() 来进行。

在 setup() 函数里,我们定义一个响应式的 data 对象,类似于 2.x 风格下的 data() 配置项。

setup () {
    const data = reactive({
      todoList: [],
      showingStatus: 'all',
      onShowList: computed(() => {
        if (data.showingStatus === 'all') {
          return data.todoList
        } else if (data.showingStatus === 'completed') {
          return data.todoList.filter(({ completed }) => completed)
        } else if (data.showingStatus === 'uncompleted') {
          return data.todoList.filter(({ completed }) => !completed)
        }
      })
    })
}

其中计算属性 onShowList 经过了 computed() 函数的包装,使得它可以根据其依赖的数据的变化而变化。

 

接下来定义方法。

在 setup() 函数里面,对之前的几个操作选项的方法稍加修改即可直接使用:

    function submit (content) {
      data.todoList.push({
        completed: false,
        content,
        id: parseInt(Math.random(0, 1) * 100000)
      })
    }
    function onStatusChanged (status) {
      data.showingStatus = status
    }
    function toggleStatus ({ isChecked, id }) {
      data.todoList.forEach(item => {
        if (item.id === id) {
          item.completed = isChecked
        }
      })
    }
    function onItemDelete (id) {
      let index = 0
      data.todoList.forEach((item, i) => {
        if (item.id === id) {
          index = i
        }
      })
      data.todoList.splice(index, 1)
    }

与在 methods: {} 对象中定义的形式所不同的地方是,在 setup() 里的方法不能通过 this 来访问实例上的数据,而是通过直接读取 data 来访问。

 

最后,把刚刚定义好的数据和方法都返回出去即可:

    return {
      ...toRefs(data),
      submit,
      onStatusChanged,
      toggleStatus,
      onItemDelete,
    }

这里使用了 toRefs() 给 data 对象包装了一下,是为了让它的数据保持“响应式”的。

 

2、Composition API 的优势及扩展

Vue 其中一个被人诟病得很严重的问题就是逻辑复用。随着项目越发的复杂,可以抽象出来被复用的逻辑也越发的多。但是 Vue 在 2.x 阶段只能通过 mixins 来解决(当然也可以非常绕地实现 HOC,这里不再展开)。mixins 只是简单地把代码逻辑进行合并,如果需要对逻辑进行追踪将会是一个非常痛苦的过程,因为繁杂的业务逻辑里面往往很难一眼看出哪些数据或方法是来自 mixins 的,哪些又是来自当前组件的。

另外一点则是对 TypsScript 的支持。为了更好地进行类型推断,虽然 2.x 也有使用 Class 风格的 ts 实现方案,但其冗长繁杂和依赖不稳定的 decorator 的写法,并非一个好的解决方案。受到 React Hooks 的启发,Vue Composition API 以函数组合的方式完成逻辑,天生就适合搭配 TypeScript 使用。

至于 Options API 和 Composition API 孰优孰劣的问题,在本文所展示的例子中其实是比较难区分的,原因是这个例子的逻辑实在是太过简单。但是如果深入思考的话不难发现,如果项目足够复杂,Composition API 能够很好地把逻辑抽离出来,每个组件的 setup() 函数所返回的值都能够方便地被追踪(比如在 VSCode 里按着 cmd 点击变量名即可跳转到其定义的地方)。这样的能力在维护大型项目或者多人协作项目的时候会非常有用,通用的逻辑也可以更细粒度地共享出去。

关于 Composition API 的设计理念和优势可以参考官网的 Motivation 章节。

如果脑洞再开大一点,Composition API 可能还有更酷的玩法。

  • 对于一些第三方组件库(如 element-ui),除了可以提供包含了样式、结构和逻辑的组件之外,还可以把部分逻辑以 Composition API 的方式提供出来,其可定制化和玩法将会更加丰富。
  • reactive() 方法可以把一个对象变得响应式,搭配 watch() 方法可以很方便地处理 side effects:
const state = Vue.observable({ count: 0 })

const Demo = {
  render(h) {
    return h('button', {
      on: { click: () => { state.count++ }}
    }, `count is: ${state.count}`)
  }
}

上述例子中,当响应式的 state.count 被修改以后,会触发 watch() 函数里面的回调。基于此,也许我们可以利用这个特性去处理其他平台的视图更新问题。微信小程序开发框架 mpvue 就是通过魔改 Vue 的源码来实现小程序视图的数据绑定及更新的,如果拥有了 Composition API,也许我们就可以通过 reactive() 和 watch() 等方法来实现类似的功能,此时 Vue 将会是位于数据和视图中间的一层,数据的绑定放在 reactive(),而视图的更新则统一放在 watch() 当中进行。

 

你可能感兴趣的:(vue)