Cover image from the Internet, delete
Future-oriented Programming, vuE-function-API provides developers to develop applications using Vue3 syntactic logic in Vue2. X. (Denoted as Vue2 for convenience)
This article will not explain much about the documentation API, but only the problems encountered in project practice. Comparing the difference between the two is the fastest understanding of the writing method of Vue3. The following is the difference between Vue2 and Vue3 by comparing the same function.
The scenario is as follows: a list page, the top part of which is a filter, the bottom part of which is a table, and the table row will be deleted and modified (displayed as a dialog). The template section is the same, so I won’t go into details here.
The preparatory work
Install the vue function – API
npm install vue-function-api --save
#or
yarn add vue-function-api
Copy the code
Introduce main.js in your project
import Vue from 'vue'
import Element from 'element-ui'
import { plugin } from 'vue-function-api' // <-- introduce vue-function-api
import App from './App'
import router from './router'
import store from './store'
Vue.use(Element)
Vue.use(plugin) // <-- this allows you to use functional apis in single-file components
Vue.config.productionTip = false
new Vue({
router,
store,
render: h= > h(App),
}).$mount('#app')
Copy the code
After the preparation, you can do the comparison in peace.
data
In Vue2, we first define data. In Data, we define a Query object for the condition filtering, citys for the city in the condition filtering (dynamic get drop down), statusMap for the state in the condition filtering, list for the table.
export default {
data() {
return {
query: {
city: null.name: null.status: null
},
citys: [].list: [].statusMap: [{
value: 1.label: 'enable'
}, {
value: 2.label: 'disabled'}}}]Copy the code
This is defined in Vue3
import { value } from 'vue-function-api'
export default {
setup() {
const query = value({
city: null.name: null.status: null
})
const citys = value([])
const list = value([])
const statusMap = value([{
value: 1.label: 'enable'
}, {
value: 2.label: 'disabled'
}])
return {
query,
citys,
list,
statusMap
}
}
}
Copy the code
If you’re careful, you’ll notice that after setup, you need variables defined by return. You don’t need to put all variables in return, you put them in return so that you can use them in template. That is, only the dependent variable in the return template
computed
As mentioned above, table has deletion and editing functions. In normal systems, such functions need to be operated by people with permissions. Here, we assume that permissions have been stored in VUex. The permissions need to be retrieved by mapGetters (for example, normal permissions are more complex).
It’s written like this in Vue2
import { mapGetters } from 'vuex'
export default {
// The data part is omitted here...computed: { ... mapGetters(['permissions']),
canUpdate() {
return this.permissions.includes('update')
},
canDelete() {
return this.permissions.includes('delete')}},// ...
}
Copy the code
Vue3: Currently vuE-function-API does not support vuex map to export state in vuex. Here we extract store data from vue root
import { computed } from 'vue-function-api'
export default {
setup(props, ctx) {
const { $store } = ctx.root
// The data part is omitted here...
const permissions = computed((a)= > $store.getters.permissions)
const canUpdate = (a)= > permissions.includes('update')
const canDelete = (a)= > permissions.includes('delete')
return {
canUpdate,
canDelete // <-- export template dependency only}}}Copy the code
In template, add v-if=”canUpdate” and v-if=”canDelete” to the edit and delete buttons, respectively.
methods & lifecycle
Based on the description above, lifecycle will be compared with Lifecycle as it is a list page.
In Vue2
export default {
// ...
methods: {
async fetchCity() {
const response = await fetchCityApi()
this.citys = response.data
},
async fetchList() {
const response = await fetchListApi(this.query)
this.list = response.data
},
async delete(id) {
const response = await deleteItem(id)
const { status, msg } = response.data
if(status ! = ='ok') return this.$message.error(msg)
this.$message({
type: 'success'.message: 'Deleted successfully'
})
},
confirm(id) {
this.$confirm('Confirm deletion'.'tip', {
confirmButtonText: 'sure'.cancelButtonText: 'cancel'.type: 'warning'
}).then((a)= > {
this.delete(id)
}).catch((a)= > {
this.$message({
type: 'info'.message: 'Cancelled'
})
})
},
detail(id) {
this.$router.push({
path: '/detail'.query: { id }
})
}
}
}
created() {
this.fetchCity()
this.fetchList()
}
}
Copy the code
Next, look at the Vue3 implementation
import { computed, onCreated } from 'vue-function-api'
export default {
setup(props, ctx) {
const { $message, $router, $confirm, $store } = ctx.root // <-- setup() cannot use this to access the current component instance. You can use context, the second argument to setup, to access properties on the instance in the vue2.x API.
// The data part is omitted here...
// method
const fetchCity = async() = > {const response = await fetchCityApi()
citys.value = response.data / / < - highlighted by the value (wrap) initialize variables in the setup of the internal reference value to add or modify values. The value
},
const fetchList = async() = > {const response = await fetchListApi(query.value)
list.value = response.data
},
const delete = async id => {
const response = await deleteItem(id)
const { status, msg } = response.data
if(status ! = ='ok') return $message.error(msg)
$message({
type: 'success'.message: 'Deleted successfully'
})
},
confirm(id) {
$confirm('Confirm deletion'.'tip', {
confirmButtonText: 'sure'.cancelButtonText: 'cancel'.type: 'warning'
}).then((a)= > {
delete(id)
}).catch((a)= > {
$message({
type: 'info'.message: 'Cancelled'
})
})
},
detail(id) {
$router.push({
path: '/detail'.query: { id }
})
}
// lifecycle
onCreated((a)= > {
fetchCity()
fetchList()
})
return {
fetchCity,
fetchList,
confirm,
detail // <-- export template dependency only}}}Copy the code
Does it feel like switching to Vue3 isn’t that hard
watch
The watch example might not have any usage scenarios in a list page, but the list page has a condition filter, a city drop down, a state drop down, and of course normally we call the fetchList with the change event of the select, so I’m just going to write this for example, Actual projects weigh their own pros and cons.
In Vue2
export default {
// ...
watch: {
query: {
handler: function(val) {
this.fetchList()
},
{ deep: true}}}// Or take the trouble to write...
watch: {
'query.city': function(val) {
this.fetchList()
},
'query.name': function(val) {
this.fetchList()
},
'query.status': function(val) {
this.fetchList()
}
}
// ...
}
Copy the code
In Vue3
import { watch } from 'vue-function-api'
export default {
setup() {
// ...
watch(
query,
val => {
fetchList()
},
{ deep: true})/ / or
watch(
(a)= > query.value,
val => {
fetchList()
},
{ deep: true})// ...}}Copy the code
Vue3 is a list page. It doesn’t use provide, inject, and state, which is equivalent to vue.Observable.
Compare complete code
Vue2
export default {
data() {
return {
query: {
city: null.name: null.status: null
},
citys: [].list: [].statusMap: [{
value: 1.label: 'enable'
}, {
value: 2.label: 'disabled'}}},computed: {
...mapGetters(['permissions']),
canUpdate() {
return this.permissions.includes('update')
},
canDelete() {
return this.permissions.includes('delete')}},methods: {
async fetchCity() {
const response = await fetchCityApi()
this.citys = response.data
},
async fetchList() {
const response = await fetchListApi(this.query)
this.list = response.data
},
async delete(id) {
const response = await deleteItem(id)
const { status, msg } = response.data
if(status ! = ='ok') return this.$message.error(msg)
this.$message({
type: 'success'.message: 'Deleted successfully'
})
},
confirm(id) {
this.$confirm('Confirm deletion'.'tip', {
confirmButtonText: 'sure'.cancelButtonText: 'cancel'.type: 'warning'
}).then((a)= > {
this.delete(id)
}).catch((a)= > {
this.$message({
type: 'info'.message: 'Cancelled'
})
})
},
detail(id) {
this.$router.push({
path: '/detail'.query: { id }
})
}
},
created() {
this.fetchCity()
this.fetchList()
},
watch: {
query: {
handler: function(val) {
this.fetchList()
},
{ deep: true}}}Copy the code
Vue3
import { value, computed, onCreated } from 'vue-function-api'
export default {
setup(props, ctx) {
const { $store, $message, $router, $route } = ctx.root
// reactive state
const query = value({
city: null.name: null.status: null
})
const citys = value([])
const list = value([])
const statusMap = value([{
value: 1.label: 'enable'
}, {
value: 2.label: 'disabled'
}])
// computed
const permissions = computed((a)= > $store.getters.permissions)
const canUpdate = (a)= > permissions.includes('update')
const canDelete = (a)= > permissions.includes('delete')
// method
const fetchCity = async() = > {const response = await fetchCityApi()
citys.value = response.data
},
const fetchList = async() = > {const response = await fetchListApi(query.value)
list.value = response.data
},
const delete = async id => {
const response = await deleteItem(id)
const { status, msg } = response.data
if(status ! = ='ok') return $message.error(msg)
$message({
type: 'success'.message: 'Deleted successfully'
})
},
confirm(id) {
$confirm('Confirm deletion'.'tip', {
confirmButtonText: 'sure'.cancelButtonText: 'cancel'.type: 'warning'
}).then((a)= > {
delete(id)
}).catch((a)= > {
$message({
type: 'info'.message: 'Cancelled'
})
})
},
detail(id) {
$router.push({
path: '/detail'.query: { id }
})
}
// watch
watch(
query,
val => {
fetchList()
},
{ deep: true})// lifecycle
onCreated((a)= > {
fetchCity()
fetchList()
})
return {
query,
citys,
list,
statusMap,
canUpdate,
canDelete,
fetchCity,
fetchList,
confirm,
detail
}
}
}
Copy the code
The last
Context, the second parameter in setup, has properties that are a subset of vue instance properties in 2.x. Complete property list:
- parent
- root
- refs
- slots
- attrs
- emit
Like other libraries vuex, VUe-Router, ElementUI some $methods are available from root
export default {
setup(props, ctx) {
const { $store, $router, $route, $message, $confirm } = ctx.root
}
}
Copy the code
The last
The author has used the formal environment, so far there is no problem, citing the official description of vue-function-API
Vue-function-api will always be compatible with vue3.x, and you can seamlessly replace the library when 3.0 is released. The implementation of vue-function-API only depends on vue2. x itself. Whether vue3. x is released or not, it will not affect your normal use of the library. Due to the limitations of Vue2. X’s public API, vue-function-API inevitably imposes some additional memory load. If your application does not work in an extreme memory environment, don’t worry about this.
The Vue Function API uses function-based apis to reuse component logic