在vue2中使用vue3的核心功能(渐进式升级vue版本)
学了真香的vue3语法,但目前的vue2项目中短期内不会再升级了,空有屠龙之术无法施展?来试试以下的解决方案,让你在vue2项目中也能用上vue3的核心语法
一、前言
学了真香的vue3语法,但目前的vue2项目中短期内不会再升级了,空有屠龙之术无法施展?来试试以下的解决方案,让你在vue2项目中也能用上vue3的核心语法-组合式API。
二、选项式API vs 组合式API
选项式API
vue单文件组件中,一段逻辑(比如更新用户信息)被各种生命周期、methods、data、props等不同的选项分离到不同的部分,维护时需要在不同的选项中找到与这段逻辑相关的代码进行修改,从而造成功能难以维护。这种将一段逻辑分割为不同选项的编写方式就叫选型式API。
组合式API
vue3中,你可将一段逻辑都放在setup模块下,包括数据引用、生命周期中执行操作、watch监听、computed计算、return方法或数据给template使用,这种将一段逻辑组合到一起编写的方式就叫组合式API。
Vue3 composition-api 有哪些劣势?
这是知乎上的一个对于composition-api
优劣的讨论,对比了vue2的选项式API和react-hooks两种方案。
简单的说组合式API在设计理念上是最棒的一种,高内聚低耦合。缺点主要是:逻辑都放在setup中,看起来乱了(个人觉得比起之前的结构要清晰不少)。当然,仁者见仁智者见智~
vue2中也能使用组合式API,是真的吗?
这个问题不用去知乎提问了,是真的,接下来就是我们的主角登场。
三、环境配置
1. 安装
首先安装@vue/composition-api
,这个是vue2版本支持组合式API的插件
npm install @vue/composition-api
# or
yarn add @vue/composition-api
2. 引入
一般在初始化vue配置的main.js
文件中,加入如下配置
import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'
Vue.use(VueCompositionAPI)
四、使用
例子很简单,别被一段代码给吓跑了
接下来的以vue官方文档给出的demo为例,以下是vue2中很常见的一段选项式API代码。
export default {
components: { RepositoriesFilters, RepositoriesSortBy, RepositoriesList },
props: {
user: {
type: String,
required: true
}
},
data () {
return {
repositories: [], // 1
filters: { ... }, // 3
searchQuery: '' // 2
}
},
computed: {
filteredRepositories () { ... }, // 3
repositoriesMatchingSearchQuery () { ... }, // 2
},
watch: {
user: 'getUserRepositories' // 1
},
methods: {
getUserRepositories () {
// 使用 `this.user` 获取用户仓库
}, // 1
updateFilters () { ... }, // 3
},
mounted () {
this.getUserRepositories() // 1
}
}
注意: 代码备注中的1、2、3,分别代表了用户仓库获取、查询以及筛选检索三种功能对应的逻辑。当组件中逻辑越来越多,可能一段逻辑相关的代码会被分割为更多选项,难以维护。接下来我们尝试用composition-api
改造。
1. ref设置数据为响应式
组合式api中data里面的数默认为响应式数据,而组合式api setup 中的数据默认为非响应式,要想转化为响应式,需要使用vue3(或compositin-api)中暴露出的ref,让ref包裹这个变量。
要想在template中使用setup中定义的对象或方法,需要return出来。
import { ref } from '@vue/composition-api'
export default {
- data () {
- return {
- repositories: [], // 1
- },
- },
+ setup () {
+ let repositories = ref([])
+ return { repositories }
+ }
}
2. methods处理
setup第一个参数为传入的props,接下来只需要将methods中的函数放入setup并改造为普通函数即可。
import { ref } from '@vue/composition-api'
export default {
- setup () {
+ setup (props) {
let repositories = ref([])
+ const getUserRepositories = async () => {
+ repositories = await fetchUserRepositories(props.user)
+ }
- return { repositories }
+ return { repositories, getUserRepositories }
},
- methods: {
- getUserRepositories () {
- // 使用 `this.user` 获取用户仓库
- }
- }
}
3. 生命周期处理
使用on加上生命周期名称即可在setup中使用生命周期函数。
- import { ref } from '@vue/composition-api'
+ import { ref, onMounted } from '@vue/composition-api'
export default {
setup (props) {
let repositories = ref([])
const getUserRepositories = async () => {
repositories = await fetchUserRepositories(props.user)
}
- mounted () {
- this.getUserRepositories()
- }
+ onMounted(getUserRepositories)
return { repositories, getUserRepositories }
}
}
4. watch监听处理
- 需要响应式引用props中的数据,需用到
toRefs
- watch和toRefs同样需要从vue中导出
- setup中使用某个对象的值时,需要加上对象
.value
- import { ref, onMounted } from '@vue/composition-api'
+ import { ref, onMounted, watch, toRefs } from '@vue/composition-api'
export default {
setup (props) {
+ const { user } = toRefs(props)
let repositories = ref([])
const getUserRepositories = async () => {
- repositories = await fetchUserRepositories(props.user)
+ repositories = await fetchUserRepositories(user.value)
}
onMounted(getUserRepositories)
+ watch(user, getUserRepositories)
return { repositories, getUserRepositories }
}
- watch: {
- user: 'getUserRepositories' // 1
- }
}
用户仓库获取部分改造后的完整代码如下,是不是很简单?
import { ref, onMounted, watch, toRefs } from '@vue/composition-api'
export default {
setup (props) {
const { user } = toRefs(props)
let repositories = ref([])
const getUserRepositories = async () => {
repositories = await fetchUserRepositories(user.value)
}
onMounted(getUserRepositories)
watch(user, getUserRepositories)
return { repositories, getUserRepositories }
}
}
五、Q&A
1. 选项式API与组合式API能否共存?
可以,所以你可以渐进式的重构你的代码。
2. template和setup中数据的引用有什么不同?
- template中可以直接使用
- setup中需要加
.value
3. 如何使用vue2里this暴露出一些方法(比如 this.$forceUpdate
, this.$emit
)?
使用setup的第二个参数,示例如下
import { ref } from 'vue'
setup (props, context) {
context.$emit('update')
}
4. 使用composition-api
重构项目后,vue版本升级到3.x怎么办?
直接将@vue/composition-api
替换为vue的引入即可。
- import { ref, onMounted, watch, toRefs } from '@vue/composition-api'
+ import { ref, onMounted, watch, toRefs } from 'vue' // vue版本需要3.X
END
更多推荐
所有评论(0)