LifeCycle Hooks
In the new version of the lifecycle functions, they can be imported into components on demand and can only be used in setup() functions.
import { onMounted, onUnmounted } from 'vue'; export default { setup () { onMounted(()=>{ // }); onUnmounted(()=> { // }); }};Copy the code
Life cycle 2. mapping between X and Composition
-
beforeCreate -> use setup()
-
created -> use setup()
-
beforeMount -> onBeforeMount
-
mounted -> onMounted
-
beforeUpdate -> onBeforeUpdate
-
updated -> onUpdated
-
beforeDestroy -> onBeforeUnmount
-
destroyed -> onUnmounted
-
errorCaptured -> onErrorCaptured
setup
understand
The setup() function is a special new method in VUe3 that can be understood as an entry point to the Composition Api.
Execution time
Execute after beforecreate and beforecreate.
Receiving props data
export default { props: { msg: { type: String, default: () => {} } }, setup(props) { console.log(props); }}Copy the code
context:
The second argument to setup() is a context object that roughly contains these properties. Note: This is not accessible in the setup() function
const MyComponent = {
setup(props, context) {
context.attrs
context.slots
context.parent
context.root
context.emit
context.refs
}
}
Copy the code
reactive
Reactive is used to create a reactive object, equivalent to the ue. Observable of 2.x. See the demo below for details.
<template> <div> <p @click="incment()"> click Me! </p> <p> <p> {{state.addCount}} </p> </div> </template> <script> import {reactive} from 'vue'; Export default {setup () {const state = reactive({count: 0, addCount: 0}); function incment () { state.count++; state.addCount = state.count * 2; } return { state, incment }; }}; </script>Copy the code
ref
The basic grammar
The ref() function creates a responsive data object for the given value, and the return value of ref() is an object that contains only a.value attribute. Here are the basic data type creation steps.
import { ref, defineComponent } from 'vue';
export default defineComponent ({
setup () {
const valueNumber = ref(0);
const valueString = ref('hello world!');
const valueBoolean = ref(true);
const valueNull = ref(null);
const valueUndefined = ref(undefined);
return {
valueNumber,
valueString,
valueBoolean,
valueNull,
valueUndefined
};
}
});
Copy the code
Access the reactive data created by ref in the template
import { ref } from 'vue'; export default { setup () { const value = ref(1); return { value, msg: 'hello world! '}; }}; <template> <p> {{ value }} {{ msg }} </p> </template>Copy the code
Mount REF responsive data to Reactive
When a value created by ref() is mounted directly to Reactive (), the reactive data object is automatically expanded to its original value and can be accessed directly without requiring a. Value.
import { ref, reactive } from 'vue'; export default { setup () { const count = ref(1); const state = reactive({ count }); console.log(state.count); State.count ++; //1 can be accessed directly, without passing.value; console.log(count.value); Return {count}; }};Copy the code
The new ref overwrites the old ref, as shown in the following example:
import { ref, reactive } from 'vue';
export default {
setup () {
const count = ref(1);
const state = reactive({
count
});
const newCount = ref(9);
state.count = newCount;
state.count++;
console.log(state.count, newCount, count);// 10 10 1
return {
count
};
}
};
Copy the code
We find that the original count value is 1, because the new newCount replaces and overwrites the previous count value.
isRef
Used to determine whether a value is an object created by ref().
import { ref, isRef } from 'vue'; export default { setup () { const count = ref(1); const unwrappend = isRef(count) ? count.value : count; return { count, unwrappend }; }};Copy the code
toRefs
The torefs() function transforms a reactive object created by Reactive () into a normal object, except that each attribute node on the object is reactive data of type REF ()
<template> <p> <! </p> </template> <script> import {ref, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive, reactive toRefs } from 'vue'; export default { setup () { const state = reactive({ count: 0, value: 'hello', }) return { ... toRefs(state) }; }}; </script>Copy the code
toRef
Concept: Create a REF object for an attribute on a source responsive object that internally operates on the same data value and is updated synchronously. Equivalent to a shallow copy of a property.
Ref: A copy of new data is operated separately and does not affect each other.
Scenario: toRef is useful when passing the REF of a prop to a composite function.
import { reactive, ref, toRef } from 'vue' export default { setup () { const m1 = reactive({ a: 1, b: 2 }) const m2 = toRef(m1, 'a'); const m3 = ref(m1.a); const update = () => { // m1.a++; // when m1 changes, m2 also changes // m2.value++; // m1 changes when m2 changes m3.value++; } return {m1, m2, m3, update}}}Copy the code
computed
Computed () is used to create computed properties, and the return value is an instance of ref.
Create a read-only compute property
import { ref, computed } from 'vue'; export default { setup () { const count = ref(0); const double = computed(()=> count.value + 1); //1 double++; //Error: "double" is read-only return { count, double }; }};Copy the code
Create computable properties that are readable and writable
During the use of computed functions, passing in an object containing the get and set functions yields a readable and writable computed property
// Create a const count = ref(1) // Create a computed property const plusOne = computed({get: () => count. Value + 1, // set: Val => {count. Value = val - 1}}) The count value is updated console.log(count.value) // to print 8Copy the code
watch
The watch() function is used to monitor changes in certain data items to trigger specific actions. In this case, it listens for changes in count in real time. Check out the official documentation API
import { ref, watch } from 'vue';
export default {
setup () {
const count = ref(1);
watch(()=>{
console.log(count.value, 'value');
})
setInterval(()=>{
count.value++;
},1000);
return {
count,
};
}
};
Copy the code
Listens for the specified data source
Monitor data changes to Reactive
import { watch, reactive } from 'vue'; export default { setup () { const state = reactive({ count: 0 }) watch(()=>state.count,(count, prevCount)=>{ console.log(count, prevCount); }) setInterval(()=>{state.count++; }, 1000); return { state }; }};Copy the code
Listen for data changes of type REF
import { ref, watch } from 'vue'; export default { setup () { const count = ref(0); watch(count,(count, prevCount)=>{ console.log(count, prevCount); }) setInterval(()=>{count.value++; }, 1000); return { count }; }};Copy the code
Listens for multiple specified data changes
Monitor changes in data of the Reactive type
import { watch, reactive } from 'vue';
export default {
setup () {
const state = reactive({
count: 0,
msg: 'hello'
})
watch([()=> state.count, ()=> state.msg],([count, msg], [prevCount, prevMsg])=>{
console.log(count, msg);
console.log('---------------------');
console.log(prevCount, prevMsg);
})
setTimeout(()=>{
state.count++;
state.msg = 'hello world';
},1000);
return {
state
};
}
};
Copy the code
Listen for ref type data changes
import { ref, watch } from 'vue';
export default {
setup () {
const count = ref(0);
const msg = ref('hello');
watch([count, msg],([count, name], [prevCount, prevname])=>{
console.log(count, name);
console.log('---------------------');
console.log(prevCount, prevname);
})
setTimeout(()=>{
count.value++;
msg.value = 'hello world';
},1000);
return {
count,
msg
};
}
};
Copy the code
Removal of monitoring
Watch monitoring, created within the setup() function, stops automatically when the current component is destroyed. If you want to explicitly stop a monitoring, you can simply call the return value of the watch() function
Const stop = watch(() => {/*... */}) // Call the stop function to clear the corresponding monitor stop()Copy the code
Clear invalid asynchronous tasks
The cleanup registrator function is provided in the watch callback function when the value monitored by watch() changes and we expect to cleanup invalid asynchronous tasks
-
scenario
-
Watch is repeated
-
Watch forced stop()
watchEffect
New API in vue3 for attribute listening.
How is it different from the Watch?
-
WatchEffect does not need to specify listening properties and can automatically collect dependencies. As long as responsive properties are referenced in the callback, the callback will be executed when these properties change, while watch can only listen on the specified properties and make changes (V3 can listen on multiple properties at the same time).
-
Watch gets new and old values, but watchEffect does not
-
WatchEffect performs a callback on component initialization similar to computed, but only after a dependency change is collected, which is not required by Watch unless specified parameters are set.
Basic usage
import { watchEffect, ref } from 'vue' setup () { const userID = ref(0) watchEffect(() => console.log(userID)) setTimeout(() => { userID.value = 1 }, 1000) /* * LOG * 0 * 1 */ return { userID } }Copy the code
Stop listening
If watchEffect is registered with setup or lifecycle, it will stop automatically when unhung.
Const stop = watchEffect(() => {/*... */ }) // later stop()Copy the code
Disable side effect
What is Side effect? An unpredictable interface request is a Side effect. Let’s say we’re looking for details about a user using a user ID, and then we listen for that user ID, and when the user ID changes we make a request. You can do that with the Watch. But if our user ID changes multiple times in the process of requesting data, we will make multiple requests, and the last one will overwrite all the user details we previously returned. Not only is this a waste of resources, but there is no guarantee of the order in which watch callbacks are executed. With watchEffect we can do just that.
The callback passed in by onInvalidate(fn) is executed when watchEffect is restarted or stopped.
WatchEffect (() => {// Asynchronous API call, Const apiCall = someAsyncMethod(props. UserID) onInvalidate(() => {// Cancel the async API call. apiCall.cancel() }) })Copy the code
shallowReactive
Concept: Only responsivity (shallow responsivity) of the outermost property of the object is handled, so if the outermost property changes, the view is updated, and other layer properties change, the view is not updated.
Scenario: If the data structure of an object is deep, but the change is only the outermost attribute.
import { shallowReactive } from 'vue'
export default {
setup() {
const obj = {
a: 1,
first: {
b: 2,
second: {
c: 3
}
}
}
const state = shallowReactive(obj)
function change1() {
state.a = 7
}
function change2() {
state.first.b = 8
state.first.second.c = 9
console.log(state);
}
return { state }
}
}
Copy the code
shallowRef
Concept: Only value responses are processed, and reactive objects are not processed.
Scenario: If there is an object data, a new object replacement is generated later.
import { shallowRef } from 'vue'
export default {
setup () {
const m1 = shallowRef({a: 1, b: {c: 2}})
const update = () => {
m1.value.a += 1
}
return {
m1,
update
}
}
}
Copy the code
customRef
Create a custom REF with explicit control over its dependency trace and update trigger.
Scenario: Use customRef to stabilize input boxes
<template> <div> <input V-model ="keyword" placeholder=" search keywords "/> <p>{{keyword}}</p> </div> </template> <script> import { customRef } from 'vue' export default { setup () { const keyword = useDebouncedRef('', 500) console.log(keyword) return { keyword } } } function useDebouncedRef(value, delay = 200) { let timeout; Return customRef((track, trigger) => {return {get() {// tell Vue to track() return value}, Set (newValue) {clearTimeout(timeout) timeout = setTimeout(() => {value = newValue // tell Vue to trigger the interface to update trigger()}, delay) } } }) } </script>Copy the code
Custom Hook functions
Custom hooks are applied to mixin technology in VUe2.
Advantages: clearly know the source of code, easy to reuse
Example: Collect the coordinates of the page that the user clicked on
hook/useMousePosition.js
import { ref, onMounted, onUnmounted } from "vue"; Export default function useMousePosition() {const x = ref(-1); const y = ref(-1); // Function to collect click event coordinates const updatePosition = e => {x.value = e.pagex; y.value = e.pageY; }; / / mount after binding to click to monitor onMounted (() = > {document. AddEventListener (" click ", updatePosition); }); / / remove unbundling before clicking to monitor onUnmounted (() = > {document. The removeEventListener (" click ", updatePosition); }); return { x, y }; }Copy the code
The template uses hook functions
<template>
<div>
<p>{{ x }}</p>
<p>{{ y }}</p>
</div>
</template>
<script>
import useMousePosition from '@/hook/useMousePosition'
export default {
setup () {
const {x, y} = useMousePosition();
return {
x,
y
}
}
}
</script>
Copy the code
Readonly and shallowReadonly
-
readonly:
-
Deep read only data
-
Gets an object (reactive or pure) or ref and returns the read-only proxy of the original proxy.
-
A read-only proxy is deep: any nested property accessed is also read-only.
-
shallowReadonly
-
Shallow read-only data
-
Create an agent that makes its own property read-only but does not perform deep read-only conversion of nested objects
-
Application Scenarios:
-
In certain cases where we may not want to update the data, we can wrap to generate a read-only proxy object to read the data without modifying or deleting it
Template refs
Ref () can also refer to elements or components on the page.
Element reference
Use the ref() function to create a DOM reference. Obtain the DOM reference in onMounted.
<template> <div> <p ref="dom">hello</p> </div> </template> <script> import { ref, onMounted } from 'vue'; export default { setup () { const dom = ref(null); OnMounted (()=> {console.log(dom.value)// Current DOM element}); return { dom } } }; </script>Copy the code
A component reference
<template> <div> <Test ref="comRef"/> </div> </template> <script> import { ref, onMounted } from 'vue'; import Test from "./test2"; export default { components: { Test }, setup () { const comRef = ref(null); onMounted(()=> { comRef.value.coun; // Get the subcomponent value comref.value.handle (); // Call the subcomponent function}) return {comRef}}; </script>Copy the code
-
test2
createComponent
This function is not necessary unless you want to integrate TypeScript’s type inference perfectly with your project development
Scenario: This function only provides type inference. It provides complete type inference for props in the setup() function.
import { createComponent } from 'vue'
export default createComponent({
props: {
foo: String
},
setup(props) {
props.foo // <- type: string
}
})
Copy the code
getCurrentInstance
Description: We can get an instance of the current component and then get the current context through the CTX property, so we can use router and vuex in steup.
<script> import {getCurrentInstance} from 'vue' export default {setup () {//getCurrentInstance CTX is equivalent to Vue2's this, // But special attention should be paid to the fact that CTX replaces this only in the development stage, and it will be wrong when you run it on the server. Const {props, proxy, Emit} = getCurrentInstance () to the console. The log (value) proxy. $router. CurrentRoute. / / / / the current path with this before things getting prototype of / / proxy. $parent $store VueX // ts (proxy as any)}} </script>Copy the code
Teleport
Description: The portal component provides a concise way to specify the parent element of the content in it, allowing us to control which parent node in the DOM renders the HTML for the nested content of ‘Teleport’ without resorting to global state or splitting into two components.
-
To String Mandatory attribute
-
to=”#last”
-
to=”.last”
-
to=”[data-teleport]”
-
Disabled Boolean Indicates the optional attribute
-
The function used to disable teleport means that the contents of the slot will not be moved to any location, but rendered at the location specified by the parent component.
.model { position: absolute; left: 0; top: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, .3); display: flex; align-items: center; justify-content: center; } .model-body { width: 300px; height: 250px; background: #fff; }
With the ‘Teleport’ component, the props’ to ‘property specifies that the rendering position of the component is under the body, but the state of the component’ modelOpen ‘is controlled by the vUE internal component.
Fragments
Description: Fragments, one of vue3’s new features, allow a component to have multiple root nodes.
<template> <header>... </header> <main v-bind="$attrs">... </main> <footer>... </footer> </template>Copy the code