It is half way through the disastrous 2020. One of the few things to be happy about is the official beta release of Vue 3.0.

This article does not discuss what performance improvements Vue 3.0 will bring or whether it is necessary to upgrade to Vue 3.0. Vue 2.x uses composition-API to solve option-base pain points.

My understanding of composition-API

For business development, it is common to face single-file-component after single-file-component. Why do we like using Vue? Because Vue helps us take a high-speed train between Javascript and Views. We can change the view by changing the state of the data in Vue by responding to changes in the view. As a result, the logic we need to implement to take advantage of Vue’s responsive nature must be in the Vue File. Some simple and commonly used logic can only be copied into each Vue File.

Compostion-api extends this responsiveness beyond Vue files. Allows us to reuse copy paste work.

A common business implementation controls the display hiding of a Dialog

Typically, controlling the display hiding of a Dialog is as simple as defining a showDialog state in data, and then writing a method to change the state.

// option-base
<template>
	<dialog :visible="showDialog"></dialog>
</template>

<script>
export default {
	data() {
  	return {
    	showDialog: false}},methods: {
    toggleDialog() {
    	this.showDialog = !this.showDialog
    }
  }
}
</script>
Copy the code

If the page has only one dialog to control, the code is as simple as above. But, to exaggerate, a page has 10 different dialog classes to interact with, and for such simple logic, copy is done. So the code will look like this

// option-base
<template>
	<dialog0 :visible="showDialog0" @close="toggleDialog0"></dialog0>
  <dialog1 :visible="showDialog1" @close="toggleDialog1"></dialog1>
  <dialog2 :visible="showDialog2" @close="toggleDialog2"></dialog2>.<dialog9 :visible="showDialog9" @close="toggleDialog9"></dialog9>
</template>

<script>
export default {
    data() {
        return {
            showDialog0: false.showDialog1: false.showDialog2: false.// ...
            showDialog9: false,}},methods: {
    toggleDialog0() {
    	this.showDialog0 = !this.showDialog0
    },
    toggleDialog1() {
    	this.showDialog1 = !this.showDialog1
    },
    toggleDialog0() {
    	this.showDialog2 = !this.showDialog2
    },
    // ...
    toggleDialog0() {
    	this.showDialog9 = !this.showDialog9
    },
  }
}
</script>
Copy the code

Thus, you can control the interaction of the class 10 Dialog on a single page. Logic is too simple to help copy 😳

Because of the responsiveness of data, I can’t abstract a logic externally to declare show states and return a method to change states. These logics are the simplest code in option-base thinking. Of course, arrays can be used to optimize this set of states, but these methods also work with composition-API, so they are not included in the comparison. Let’s show how composition-API can reuse reactive states

UseToggle logic

// reuse logic
export function useToggle(initState = false) {
	const state = ref(initState)
  const toggle = function(outerState) {
  	if (typeof outerState === 'boolean') {
    	state.value = outState
    } else{ state.value = ! state.value } }return {
  	state,
    toggle
  }
}
Copy the code

Business use

// compostion-api
<template>
	<dialog0 :visible="showDialog0" @close="toggleDialog0"></dialog0>
  <dialog1 :visible="showDialog1" @close="toggleDialog1"></dialog1>
  <dialog2 :visible="showDialog2" @close="toggleDialog2"></dialog2>.<dialog9 :visible="showDialog9" @close="toggleDialog9"></dialog9>
</template>

<script>
export default {
  setup() {
    const { state: showDialog0, toggle: toggleDialog0 } = useToggle()
    const { state: showDialog1, toggle: toggleDialog1 } = useToggle()
    const { state: showDialog2, toggle: toggleDialog2 } = useToggle()
    // ...
    const { state: showDialog9, toggle: toggleDialog9 } = useToggle()
    
    return {
    	showDialog0,
      showDialog1,
      showDialog2,
      // ...
      showDialog9,
      toggleDialog0,
      toggleDialog1,
      toggleDialog2,
      // ...
      toggleDialog9,
    }
  },
}
</script>
Copy the code

As you can see, the composition-API gracefully reuses this simple logic, but nothing changes for vue-Template. So I prefer to think of composition-API as a more flexible way to use Vue, rather than a syntactic change to Vue 3.0 code. It just happened to show up with Vue 3.0.

This is a state reuse. If the interactive logic such as loading, success and error of asynchronous operation is displayed when loading is triggered, data is displayed when callback succeeds, and failed copywriting is displayed when callback fails, such logic is also very common. However, it can only be reimplemented again and again because it is not difficult. And it’s hard to reuse in option-base. So if you look at this and think about how you can reuse this logic.

In addition to pagination operation logic, need total, currentPage, pageSize, data several states, at the same time need to switch page number update data method, although a complex to lose, but also can only be repeated over and over again. Using the thinking of composition-API, you can reuse this logic, not just within a project, but throughout the Vue ecosystem. A solid reminder of the efficiency of business development.

How to use composition-API

Vue 3.0 is in the BATA phase and is not well suited for production on corporate applications. But it wasn’t the performance optimization of Vue 3.0 that made me scream “sweet.” It was the composition-API solution that came with it. So the vue/ composition-API library is a good choice. You can familiarize yourself with the syntax of Vue 3.0 in advance, and you can also see solid efficiency hints in development, provided that you are familiar with the syntax of composition-API.

I stepped on the pit, let us take a little less detour

How to get $style from csS-Module

Issue: github.com/vuejs/compo…

import { getCurrentInstance } from '@vue/composition-api';

export default {
  setup () {
     const { $style } = getCurrentInstance()
  }
}
Copy the code

Note that this method is not available in Vue 3.0, but if you need to use JS to get csS-Module injected variables, you need to use this method. If you use $style directly in template, you do not need to call this method

How do I get a dom reference using template ref

Since the underlying layer is Vue 2.x, the actual logic of this is different from the RFC of Vue 3.0. See the official documentation for details

And here’s how I use it

const Demo = defineComponent({
  setup(props, ctx) {
    const [count, { inc, dec, set, reset }] = useCounter();
    // useClickAway returns a ref
    const { element } = useClickAway((a)= > inc());
    return {
      element,
      count,
      inc,
      dec,
      set,
      reset,
    };
  },

  render(this: Vue & Inject) {
    const { count } = this;
    return (
      <div>
        click outside the button to increase counter
        <br />
        <button ref="element">count: {count}</button>
      </div>); }});Copy the code

This is an implementation that triggers an event when clicking outside the button. You can usually implement logic like clicking outside the Dialog to close the dialog.

How do I get a responsive route

How do I get the router and route from the document

export default {
	setup(props, ctx) {
  	const { $router, $route } = ctx.root
    // Now I want to listen for params id on route
   	// First attempt
    const id = computed((a)= > {
    	return route.params.id
    })
    
    watchEffet((a)= > {
    	console.log(id)
    })
  }
}
Copy the code

The above code does not respond to changing the route params by printing the id. Because route is just an ordinary object, it is not handled in a responsive manner. The following code can also trigger a response if the route changes

export default {
	setup(props, ctx) {
    const route = computed((a)= > ctx.root.$route)
    const id = computed((a)= > {
    	return route.value.params.id
    })
    
    watchEffet((a)= > {
    	console.log(id)
    })
  }
}
Copy the code

Several hooks libraries are recommended

  • Vue – use – web: github.com/Tarektouati…

It encapsulates some common browser apis such as FullScreen, VisibilityChange, etc

  • U3u/vue – hooks: github.com/u3u/vue-hoo…

Note the hooks that encapsulate router and vuex

Because the author of U3U/VUe-hooks was slow to respond, I forked out the repository and planned to add some business hooks in the near future, as well as update the latest composition-API. We can come to demand github.com/lianghx-319…

If the author of U3U/VUe-hooks sees this, please reply to me that he still wants to maintain the original warehouse