Get this
In Vue2, this is used in each component, which points to the current component instance, and this also contains global mounts. Everyone knows thatEverything
There is no this in Vue3. If you want a similar usage, there are two types of usages. One is to get the current component instance, and the other is to get the global instance. You can print it out as follows.
<script setup> import { getCurrentInstance } from 'vue' // proxy is the current component instance, which can be understood as this at the component level, without global, routing, state management, etc.const { proxy, appContext } = getCurrentInstance() // This global is a global instanceconst global = </script>
Global registration (properties/methods)
In Vue2, we want to mount things globally, usually as follows, and then all components can be passed.Get it
= xxx
This cannot be written in Vue3. It is replaced with a global object that can be accessed by all components, which is the object of the global instance mentioned above. For example,Do global registration
// import { createApp } from 'vue' import App from './' const app = createApp(App) // Add global properties = 'Mu Hua'
Called in other components
<script setup> import { getCurrentInstance } from 'vue' const { appContext } = getCurrentInstance() const global = () // Mu Hua</script>
Get DOM
<template> <el-form ref="formRef"></el-form> <child-component /> </template> <script setup lang="ts"> import ChildComponent from './' import { getCurrentInstance } from 'vue' import { ElForm } from 'element-plus' // Method 1, this variable name and the ref attribute on the DOM must have the same name, and it will automatically form a binding.const formRef = ref(null) () // This gets the DOM // Method 2const { proxy } = getCurrentInstance() proxy.$((valid) => { ... }) // Method 3, for example, in ts, you can directly obtain the component type// This is how the subcomponents can be obtainedconst formRef = ref<InstanceType<typeof ChildComponent>>() // You can also get the component type of element ui in this wayconst formRef = ref<InstanceType<typeof ElForm>>() ?.validate((valid) => { ... }) </script>
initialization
In Vue2, you will request an interface or some other initialization operations when entering the page, which is usually placed increated
ormounted
, and in Vue3beforeCreated
andcreated
You don't need these two hooks, because if you execute the setup before these two, you will be extravagant if you want them.
So, as long as you used itbeforeCreated / created / beforeMounted / mounted
The contents of these hooks are either placed in Vue3setup
or putonMounted
inside
<script setup> import { onMounted } from 'vue' // Request interface functionconst getData = () => { (() => { ... }) } onMounted(() => { getData() }) </script>
Unbind
In Vue2, there are two methods to clear timers, monitors and other operations:
- One is to use
$once
Matchhook: BeforeDestroy
Used, this Vue3 is no longer supported - The second is to use
beforeDestroy / deactivated
These two hooks were just renamed in Vue3
<script setup> import { onBeforeUnmount, onDeactivated } from 'vue' // Before uninstalling the component, the corresponding beforeDestroy of Vue2onBeforeUnmount(() => { clearTimeout(timer) ('...') }) // Exit the cache component, corresponding to the deactivated of Vue2onDeactivated(() => { clearTimeout(timer) ('...') }) </script>
ref and reactive
Both of these are used to create responsive objects.ref
Usually used to create basic types,reactive
Usually used to create responsive forms, which is officially recommended, and is not the case in reality. Some people also use it.ref
To define an array, some people define only one componentreactive
, all the data is put inside, just like Vue2'sdata
Likewise, some people use it
There are two things to know:
-
ref
If the reference type is passed in, the internal source code will also be calledreactive
To achieve -
ref
The returned attribute istemplate
Use it directly, but if you use it in JS, you need to pass it.value
Get it as follows. Because ref returns a wrapper object
<template> <div>{{ count }}</div> </template> <script setup> import { ref, reactive } from 'vue' const count = ref(1) // Someone uses it like thisconst arr = ref([]) () // [] // Some people use it like this. All the properties in a component are defined in one object, which has a bit of Vue2 data.const data = reactive({ name: 'Mu Hua', age: 18, ... }) () // Mu Hua // There is also some component that uses both ref and reactive, you can do whatever you want</script>
Whyref
Want to return a wrapper object? In Vue2, data returns an object.
Because object reference type can be used as proxy or hijacking. If you only return the basic type, it will be stored in the stack and recycled after execution in the stack. There is no way to add proxy or hijacking, so you will naturally not be able to track subsequent changes, so you have to return an object so that you can have a responsive
toRef and toRefs
These two common points are used to create responsive references. They are mainly used to retrieve attributes in responsive objects or deconstruct responsive objects. The deconstructed attribute value is still responsive attributes. If these two are not directly deconstructed, the responsive effect will be lost.
It is mainly to facilitate us to use direct variablesxxx
, without needing. And we modify
xxx
When it comes to modify the source object properties directly
The difference between these two: with s and without s, it is just singular and plural, which means taking one and a bunch.
<script setup> import { reactive, toRef, toRefs } from 'vue' const data = reactive({ name: 'Mu Hua', age: 18 }) // Although you can get name/age in this way, it will become a normal variable and there is no responsive effectconst { name, age } = data // Take out a responsive attributeconst name = toRef(data, 'name') // All properties deconstructed in this way are responsiveconst { name, age } = toRefs(data) // Whether it is toRef or toRefs, this modification will change the name in data// It will change the source object properties, which is what the responsive form should look like = 'Mu Muhuahua' </script>
watch
Watch is used to listen for an existing property and do certain operations when changes occur. There are three common writing methods in Vue2.
watch: { userId: 'getData', userName (newName, oldName) { () }, userInfo: { handler (newVal, newVal) { () }, immediate: true, deep: true } }
The way to write monitoring in Vue3 is much richer
Vue3's watch is a function that can receive three parameters. The first is the monitoring attribute, the second is the callback function that receives new and old values, and the third is the configuration item
<script setup> import { watch, ref, reactive } from 'vue' const name = ref('Mu Hua') const data = reactive({ age: 18, money: 100000000000000000000, children: [] }) // Listen to the ref attributewatch(name, (newName, oldName) => { ... }) // This is true for monitoring other attributes, routes or state managementwatch( () => , (newAge, oldAge) => { ... } ) // Listen to multiple attributes, put multiple values in the array, and the returned new and old values are also in the form of an arraywatch([, ], ([newAge, oldAge], [newMoney, oldMoney]) => { ... }) // The third parameter is an object, which is a configurable item, with 5 configurable propertieswatch(, (newList, oldList) => { ... }, { // These two are the same as Vue2, nothing to say immediate: true, deep: true, // The execution time of the callback function is called by default before the component is updated. After update, the call is changed to post flush: 'pre', // The default value is pre, which can be changed to post or sync // The following two are for debugging onTrack (e) { debugger } onTrigger (e) { debugger } }) </script>
Regarding side effects, the third parameter can be received in the watch callback function. It is a function that clears side effects. Its execution mechanism is called by default before update. For example, the following code will be printed first when the key triggers an update.222
Print againMuhua
, if you need to call it after update, you can add it in the third configuration item of watchflush: post
,
// The callback function receives a parameter to clear side effectswatch(key, (newKey, oldKey, onInvalidate) => { ('Mu Hua') // Get the DOM by default, the DOM is obtained before the update. If it is flush: post, you can get the updated DOM ('DOM Node:', ) onInvalidate(() => { (2222) }) })
The monitoring is not over yet
You Da: Hehe~
watchEffect
In addition to watch, a watchEffect is also added to Vue3. The difference is:
- watch is to listen on one or more incoming values. When triggered, it will return new and old values, and will not be executed for the first time by default.
- watchEffect is to pass in an immediate execution function, so it will be executed for the first time by default, and there is no need to pass in the listening content. The data source in the function will be automatically collected as a dependency. When the dependency changes, the function will be re-executeed (a bit like computed) and will not return new and old values.
- The refresh time for clearing side effects and side effects is the same. The difference is that it will be passed in as the third parameter of the callback, and the first parameter of the callback function in watchEffect
- Under normal circumstances, these two will automatically stop listening after component destruction/uninstallation, but there are also examples, such as asynchronous method.
setTimeout
The listening created in the source needs to be stopped manually. The stop method is as follows
// Stop monitoringconst unwatch = watch('key', callback) const unwatchEffect = watchEffect(() => {}) // Stop monitoring manually when neededunwatch() unwatchEffect()
watchEffect uses:
<script setup> import { watchEffect } from 'vue' // Normal usewatchEffect(() => { // It will automatically collect the properties used by this function as dependencies for monitoring // It is the attribute that is listened to, and it will not listen to userInfo () }) // There are two parameters, one is to trigger the monitoring callback function, and the other is to optional configuration itemswatchEffect(() => {...}, { // Here are configurable items, which means the same as watch, but there are only 3 configurable items flush: 'pre', onTrack (e) { debugger } onTrigger (e) { debugger } }) // The callback function receives a parameter to clear side effects, the same as the watchwatchEffect(onInvalidate => { ('Mu Hua') onInvalidate(() => { (2222) }) }) </script>
watchEffect If you need to modify the configuration item flush to post or sync, you can use the alias directly, as follows
watchEffect(() => {...}, { flush: 'post', }) // It's the same as the one belowwatchPostEffect(() => {}) ----------------------------- watchEffect(() => {...}, { flush: 'sync', }) // It's the same as the one belowwatchSyncEffect(() => {})
computed
The most common usage scenarios of computered in Vue2 are:mapGetters/mapState
Get the attributes of state management, get the attributes on the url, conditional judgment, type conversion, etc., and supports two ways of writing functions and objects.
And in Vue3computed
It is no longer an object, but a function. The usage is basically the same. The first parameter of the function is the listener source, which is used to return the calculated new value, and also supports object writing. The second parameter can be used for debugging.
<script setup> import { computed } from 'vue' // Get the type attribute on the urlconst type = computed(() => Number(this.$ || '0')) // Object writingconst visible = computed({ get () { return }, set (val) { this.$emit('input', val) } }) // The second parameter is also an object, used for debuggingconst hehe = computed(Both parameters are available, { onTrack (e) { debugger } onTrigger (e) { debugger } }) </script>
nextTick
nextTick
The usage method is not available exceptthis
The others are exactly the same as Vue2, but there are three ways
<script setup> import { nextTick} from 'vue' // Method 1const handleClick = async () => { await nextTick() ('Mu Hua') } // Method 2nextTick(() => { ('Mu Hua') }) // Method 3nextTick().then(() => { ('Mu Hua') }) </script>
mixins and hooks
The extraction and multiplexing of logic in Vue2 generally uses mixins, and there are three disadvantages:
- Without a separate namespace, mixins will cause naming conflicts with the component inside.
- I don't know what is in the mixins introduced if I don't flip through the code
- When introducing multiple mixins, I don't know which mixins I am using.
The hooks syntax of logical extraction and multiplexing in Vue3 is actually a function that can be passed through parameters and used with the return value. Or you can understand it like this: How do you write the method you want to encapsulate publicly? How to write in Vue3
// expport const getData = () => {} export default function unInstance () { ... return {...} } // import unInstance, { getData } from '' const { ... } = unInstance() onMounted(() => { getData() })
About hooks how to write more elegant code, it also requires more writing and practice
Component communication
There are several ways to communicate with Vue3 components.
- props + defineProps
- defineEmits
- defineExpose / ref
- useAttrs
- v-model (supports multiple)
- provide / inject
- Vuex / Pinia
Regarding the use of Vue component communication, I wrote an article last year, which listed them in detail, so I won't move it here.
8 types of Vue3 and 12 types of Vue2's components
Multiple v-models
Only one v-model can be written on each component in Vue2, and the child component is not written.model
If so, the default isprops
take overvalue
Just modify itthis.$emit('input')
event
Each component in Vue3 supports writing multiple v-models on each component, but there is no more.sync
andmodel
There is no need to rename the operation. When writing v-model, you need to write the naming together, as follows:
// Parent component writing method<template> <child v-model:name="name" v-model:age="age" /> </template> <script setup> import { ref } from "vue" const name = ref('Mu Hua') const age = ref(18) </script> // Subcomponents<script setup> const emit = defineEmits(['update:name', 'update:age']) const handleClick = () => { ('Clicked') emit('update:name', 'This is the new name') } </script>
Status Management
Needless to say, if Vuex knows, just learn Pinia if you don’t know.
I have written an article before and I won't move it here.
Get started with Vue's new status management Pinia, one article is enough
routing
In Vue2$route
and$router
As follows, you can print it out and see it yourself
<script setup> import { useRoute, useRouter } from "vue-router" // route corresponds to this.$routeconst route = useRoute() // router corresponds to this.$routerconst router = useRouter() </script>
template
There can only be one root node in Vue2, while Vue3 supports multiple root nodes, which everyone knows.
In fact, each component of Vue3 is still a root node, because the DOM tree can only be a tree-like structure. However, Vue3 has added a new judgment in the compilation stage. If the current component has more than one root element, add one.fragment
The component wraps up these multiple components, which means that the component still has only one root node.
<template> <div>1</div> <div>2</div> </template>
CSS Style Penetration
Vue2 is inscoped
Modify the component styles in the subcomponent or component library. If they cannot be changed, you can use the style to penetrate it, no matter if it isLess
stillSASS
All use/dee/ .class {}
To do style penetration, but it is not supported in Vue3/deep/
I've written it, change it to:deep(.class)
<style scoped> // If this write does not work.el-form { .el-form-item { ... } } // This is written in Vue2/deep/ .el-form { .el-form-item { ... } } // This is written in Vue3:deep(.el-form) { .el-form-item { ... } } </style> // Stop adding a style tag without scoped like this, all of them are added to the global// <style lang="scss"> // .el-form { // .el-form-item { ... } // } // </style>
CSS binding JS variables
That is, JS variables can be used in CSS to assign values, as follows
<template> <div class="name">Muhua</div> </template> <script setup> import { ref } from "vue" const str = ref('#f00') // Red</script> <style scoped lang="scss"> .name { background-color: v-bind(str); // Color value variable in JS #f00 is assigned here}</style>
The above is the detailed content shared by the nanny-level Vue3 development tutorial. For more information about Vue3 development documents, please pay attention to my other related articles!