Original address http://www.liulongbin.top:8085
0. Basic requirements
- Understanding common ES6 new features
- ES6 import and export grammar
- Destructuring assignment
- Arrow function
- etc...
- Understanding the basic use of vue 2.x
- assembly
- Commonly used instructions
- Life cycle function
- computed, watch, ref, etc.
1. Relevant resources
- [Know - Vue Function-based API RFC] https://zhuanlan.zhihu.com/p/68477600
- [github - vuejs/composition-api]https://github.com/vuejs/composition-api
- [github - composition-api/CHANGELOG.md]https://github.com/vuejs/composition-api/blob/master/CHANGELOG.md
- [Open Source China-Youyuxi Publishes the Vue 3.0 Development Route: Rewriting 3.0 from scratch] https://www.oschina.net/news/100515/plans-for-the-next-iteration-of-vue-js
2. Initialization project
-
Install vue-cli3
npm install -g @vue/cli # OR yarn global add @vue/cli
-
Create project
vue create my-project # OR vue ui
-
Install composition-api in the project to experience new features of vue3
npm install @vue/composition-api --save # OR yarn add @vue/composition-api
-
Before using any @vue/composition-api capabilities, you must install them through Vue.use().
import Vue from 'vue' import VueCompositionApi from '@vue/composition-api' Vue.use(VueCompositionApi)
After installing the plug-in, you can use the new one Composition API It's time to develop components.
3. setup
The setup() function is a new property specifically provided for components in vue3. It provides a unified entry point for us to use the new features of the Composition API of vue3.
3.1 Opportunity for Implementation
The setup function is executed after before Create and before Create.
3.2 Receiving props data
-
Define in props the name of the parameter that the current component allows to be passed from the outside world:
props: { p1: String }
-
The props data is received by the first parameter of the setup function:
setup(props) { console.log(props.p1) }
3.3 context
The second parameter of the setup function is a context object, which contains some useful attributes that need to be accessed through this in vue 2.x. In vue 3.x, they are accessed as follows:
const MyComponent = { setup(props, context) { context.attrs context.slots context.parent context.root context.emit context.refs } }
Note: this cannot be accessed in the setup() function
4. reactive
The reactive() function receives a common object and returns a responsive data object.
4.1 Basic Grammar
Equivalent to the Vue.observable() function in vue 2.x, the reactive() function in vue 3.x is provided to create responsive data objects. The basic code examples are as follows:
import { reactive } from '@vue/composition-api' // Create a responsive data object that yields a state similar to that returned by data() in vue 2.x const state = reactive({ count: 0 })
4.2 Define responsive data for template use
-
Import the reactive function on demand:
import { reactive } from '@vue/composition-api'
-
In the setup() function, call the reactive() function to create the response data object:
setup() { // Creating responsive data objects const state = reactive({count: 0}) // return the responding data object in the setup function for template use return state }
-
Access response data in template:
<p> The current count value is: {count}</p>
5. ref
5.1 Basic Grammar
The ref() function is used to create a responsive data object based on the given value. The return value of the ref() function call is an object, which contains only one. Value attribute:
import { ref } from '@vue/composition-api' // Create a responsive data object count with an initial value of 0 const count = ref(0) // If you want to access the value of the responsive data object created by ref(), you must pass the. Value attribute. console.log(count.value) // Output 0 // Let count + 1 count.value++ // Print count again console.log(count.value) // Output 1
5.2 Accessing the responsive data created by ref in template
-
Create responsive data in setup():
import { ref } from '@vue/composition-api' setup() { const count = ref(0) return { count, name: ref('zs') } }
-
Access response data in template:
<template> <p>{{count}} --- {{name}}</p> </template>
5.3 Accessing the responsive data created by ref in the reactive object
When the responding data object created by ref() is mounted on reactive(), it automatically expands the responding data object into the original value, which can be accessed directly without passing. value, for example:
const count = ref(0) const state = reactive({ count }) console.log(state.count) // Output 0 state.count++ // There is no need to go through. value to access the original value directly. console.log(count) // Output 1
Note: The new ref overrides the old Ref. The sample code is as follows:
// Create ref and mount it into reactive const c1 = ref(0) const state = reactive({ c1 }) // Create ref again, named c2 const c2 = ref(9) // Replace old ref c1 with new ref c2 state.c1 = c2 state.c1++ console.log(state.c1) // Output 10 console.log(c2.value) // Output 10 console.log(c1.value) // Output 0
6. isRef
isRef() is used to determine whether a value is an object created by ref(); application scenario: when it is necessary to expand a value that may be created for ref(), for example:
import { isRef } from '@vue/composition-api' const unwrapped = isRef(foo) ? foo.value : foo
7. toRefs
The toRefs() function converts reactive() created responsive objects into ordinary objects, except that each attribute node on this object is ref() type responsive data. The most common application scenarios are as follows:
import { toRefs } from '@vue/composition-api' setup() { // Define responsive data objects const state = reactive({ count: 0 }) // Define the event handlers available on the page const increment = () => { state.count++ } // Return an object in setup for page use // This object can contain either responsive data or event handlers. return { // Converting each attribute on state to ref-like responsive data ...toRefs(state), // Self-Increasing Event Handling Functions increment } }
The response data return ed from setup() can be accessed directly on the page:
<template> <div> <p>Current count The value is:{{count}}</p> <button @click="increment">+1</button> </div> </template>
8. computed
computed() is used to create computational properties, and the return value of the computed() function is an instance of ref. You need to import on demand before using computed:
import { computed } from '@vue/composition-api'
8.1 Create read-only computational properties
During the call of the computed() function, a function function function is passed in, and a read-only computing property can be obtained. The sample code is as follows:
// Create a ref responsive data const count = ref(1) // Create a responsive computational attribute plusOne based on the value of count // It automatically calculates and returns a new ref based on the dependent ref const plusOne = computed(() => count.value + 1) console.log(plusOne.value) // Output 2 plusOne.value++ // error
8.2 Create Readable and Writable Computing Properties
During the call of the computed() function, an object containing get and set functions is passed in, and a readable and writable computing property can be obtained. The sample code is as follows:
// Create a ref responsive data const count = ref(1) // Create a computed computational property const plusOne = computed({ // Value function get: () => count.value + 1, // Assignment function set: val => { count.value = val - 1 } }) // The set function is triggered for the operation of calculating attribute assignment plusOne.value = 9 // When the set function is triggered, the count value is updated console.log(count.value) // Output 8
9. watch
The watch() function is used to monitor changes in certain data items, triggering certain operations that need to be imported on demand before they are used:
import { watch } from '@vue/composition-api'
9.1 Basic usage
const count = ref(0) // Define watch, which triggers a watch callback whenever the count value changes // watch is automatically invoked once when it is created watch(() => console.log(count.value)) // Output 0 setTimeout(() => { count.value++ // Output 1 }, 1000)
9.2 Monitor Designated Data Sources
Monitor data sources of type reactive:
// Define data sources const state = reactive({ count: 0 }) // Monitor the change of the state.count data node watch(() => state.count, (count, prevCount) => { /* ... */ })
Monitor data sources of ref type:
// Define data sources const count = ref(0) // Specify the data source to be monitored watch(count, (count, prevCount) => { /* ... */ })
9.3 Monitor Multiple Data Sources
Monitor data sources of type reactive:
const state = reactive({ count: 0, name: 'zs' }) watch( [() => state.count, () => state.name], // Object.values(toRefs(state)), ([count, name], [prevCount, prevName]) => { console.log(count) // New count value console.log(name) // New name value console.log('------------') console.log(prevCount) // Old count value console.log(prevName) // New name value }, { lazy: true // When a watch is created, the code in the callback function is not executed } ) setTimeout(() => { state.count++ state.name = 'ls' }, 1000)
Monitor data sources of ref type:
const count = ref(0) const name = ref('zs') watch( [count, name], // Multiple ref data sources that need to be monitored ([count, name], [prevCount, prevName]) => { console.log(count) console.log(name) console.log('-------------') console.log(prevCount) console.log(prevName) }, { lazy: true } ) setTimeout(() => { count.value++ name.value = 'xiaomaolv' }, 1000)
9.4 Clearance Surveillance
Watch monitoring created in the setup() function automatically stops when the current component is destroyed. If you want to stop a monitor explicitly, you can call the return value of the watch() function. The grammar is as follows:
// Create a monitor and get a stop function const stop = watch(() => { /* ... */ }) // Call the stop function to clear the corresponding monitoring stop()
9.5 Clear Invalid Asynchronous Tasks in watch
Sometimes, when the value monitored by the watch changes, or after the watch itself is stop ped, we expect to be able to clean up those invalid asynchronous tasks. At this point, a cleanup registrator function is provided in the watch callback function to perform the cleanup. This cleanup function is called in the following cases:
- watch is repeated
- watch was forced to stop
The code example in Template is as follows:
/* template Code in */ <input type="text" v-model="keywords" />
The code examples in Script are as follows:
// Define responsive data keywords const keywords = ref('') // Asynchronous Tasks: Printing User Input Key Words const asyncPrint = val => { // Print after 1 second delay return setTimeout(() => { console.log(val) }, 1000) } // Define watch listening watch( keywords, (keywords, prevKeywords, onCleanup) => { // Execute asynchronous tasks and get timerId to turn off asynchronous tasks const timerId = asyncPrint(keywords) // If the watch listener is repeated, the last unfinished asynchronous task is cleared first onCleanup(() => clearTimeout(timerId)) }, // watch is not executed when it was first created { lazy: true } ) // return the data needed in the template return { keywords }
10. LifeCycle Hooks
The new version of life cycle functions can be imported into components on demand and can only be used in setup() functions. The code examples are as follows:
import { onMounted, onUpdated, onUnmounted } from '@vue/composition-api' const MyComponent = { setup() { onMounted(() => { console.log('mounted!') }) onUpdated(() => { console.log('updated!') }) onUnmounted(() => { console.log('unmounted!') }) } }
The following list is the mapping between the life cycle function of vue 2.x and the new version of Composition API:
- beforeCreate -> use setup()
- created -> use setup()
- beforeMount -> onBeforeMount
- mounted -> onMounted
- beforeUpdate -> onBeforeUpdate
- updated -> onUpdated
- beforeDestroy -> onBeforeUnmount
- destroyed -> onUnmounted
- errorCaptured -> onErrorCaptured
11. provide & inject
provide() and inject() can achieve data transfer between nested components. These two functions can only be used in setup() functions. The parent component uses the provide() function to pass data downward; the child component uses inject() to get the data passed from the upper layer.
11.1 Sharing Common Data
App.vue root component:
<template> <div id="app"> <h1>App Root components</h1> <hr /> <LevelOne /> </div> </template> <script> import LevelOne from './components/LevelOne' // 1. Import provide on demand import { provide } from '@vue/composition-api' export default { name: 'app', setup() { // 2. App root component acts as parent component, sharing data to child component through provide function (unlimited level) // provide('the name of the data to be shared', the data to be shared) provide('globalColor', 'red') }, components: { LevelOne } } </script>
LevelOne.vue component:
<template> <div> <!-- 4. Set font color for labels by property binding --> <h3 :style="{color: themeColor}">Level One</h3> <hr /> <LevelTwo /> </div> </template> <script> import LevelTwo from './LevelTwo' // 1. Import inject as needed import { inject } from '@vue/composition-api' export default { setup() { // 2. When the inject function is called, the data shared by the parent is obtained by the specified data name. const themeColor = inject('globalColor') // 3. return the shared data received to Template for use return { themeColor } }, components: { LevelTwo } } </script>
LevelTwo.vue component:
<template> <div> <!-- 4. Set font color for labels by property binding --> <h5 :style="{color: themeColor}">Level Two</h5> </div> </template> <script> // 1. Import inject as needed import { inject } from '@vue/composition-api' export default { setup() { // 2. When the inject function is called, the data shared by the parent is obtained by the specified data name. const themeColor = inject('globalColor') // 3. return the shared data received to Template for use return { themeColor } } } </script>
11.2 Sharing ref responsive data
The following code realizes the function of point button to switch theme color. It mainly modifies the code in App.vue component. The code in LevelOne.vue and LevelTwo.vue is unchanged.
<template> <div id="app"> <h1>App Root components</h1> <!-- click App.vue The button in the sub-component to switch the color of the text in the sub-component --> <button @click="themeColor='red'">Red</button> <button @click="themeColor='blue'">blue</button> <button @click="themeColor='orange'">Orange</button> <hr /> <LevelOne /> </div> </template> <script> import LevelOne from './components/LevelOne' import { provide, ref } from '@vue/composition-api' export default { name: 'app', setup() { // Define ref responsive data const themeColor = ref('red') // Use ref data through subcomponents provided by provide provide('globalColor', themeColor) // The return data in setup is used by Template of the current component return { themeColor } }, components: { LevelOne } } </script>
12. template refs
You can also refer to elements or components on a page through ref().
12.1 Element Reference
The sample code is as follows:
<template> <div> <h3 ref="h3Ref">TemplateRefOne</h3> </div> </template> <script> import { ref, onMounted } from '@vue/composition-api' export default { setup() { // Create a DOM reference const h3Ref = ref(null) // After the DOM is first loaded, a reference to the element can be obtained. onMounted(() => { // Set font color for dom elements // h3Ref.value is a native DOM object h3Ref.value.style.color = 'red' }) // return the created reference return { h3Ref } } } </script>
12.2 Component Reference
The sample code in TemplateRefOne.vue is as follows:
<template> <div> <h3>TemplateRefOne</h3> <!-- 4. Click on the button to display the subcomponents count value --> <button @click="showNumber">Obtain TemplateRefTwo Medium count value</button> <hr /> <!-- 3. Adding components ref Quote --> <TemplateRefTwo ref="comRef" /> </div> </template> <script> import { ref } from '@vue/composition-api' import TemplateRefTwo from './TemplateRefTwo' export default { setup() { // 1. Create a ref reference for a component const comRef = ref(null) // 5. Show the count value in the subcomponent const showNumber = () => { console.log(comRef.value.count) } // 2. return the references created return { comRef, showNumber } }, components: { TemplateRefTwo } } </script>
Sample code in TemplateRefTwo.vue:
<template> <div> <h5>TemplateRefTwo --- {{count}}</h5> <!-- 3. Click on the button to let count Value increment +1 --> <button @click="count+=1">+1</button> </div> </template> <script> import { ref } from '@vue/composition-api' export default { setup() { // 1. Defining responsive data const count = ref(0) // 2. return the responsive data to Template return { count } } } </script>
13. createComponent
This function is not required unless you want to develop the project in perfect combination with type inference provided by TypeScript.
This function only provides type inference, which facilitates the complete type inference for props in setup() when writing code in combination with TypeScript.
import { createComponent } from 'vue' export default createComponent({ props: { foo: String }, setup(props) { props.foo // <- type: string } })