Vue3.0
Vue3 is compatible with the way components are defined in Vue2, so simply replace the code that creates Vue instances in the entry file main.js with the createApp method introduced in Vue3 to create application instances. Vue 2 main. Js:
import Vue from 'vue'
import App from './App.vue'
new Vue({
render: h => h(App),
}).$mount('#app')
Copy the code
Vue 3 main.js
:
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
Copy the code
New features of Vue 3.0:
Composition API:
As components get larger, the list of logical concerns grows (the file structure is complex). Components that are difficult to read and understand (constantly “jumping” between options blocks of related code when working with a single logical concern) Composition API: configures together code related to the same logical concern. The location where you use the Composition API is called setup (using the Composition API in setup)
Makes most of the component configurable through the setup() method
Setup component options
The Setup component option is executed before the component is created, once the props is resolved, and acts as an entry point to the composition API.
Note: Because the component instance has not been created when setup is executed, there is no this in the Setup option. That is, no properties declared in the component are accessible except props ———— local state, computed properties, or methods, etc
Import {APIName} from '@/ API 'import {ref, OnMounted} from 'vue' // in our Component export default {setup (props) {const repositories = ref([]) // Define a const repository GetUserRepositories = async () => {// Define a method repositories.value = await APIName(functions.user)} OnMounted (getUserRepositories) // Life cycle hook getUserRepositories // Return a data getUserRepository // Return a method}}}Copy the code
Single-file component Composition API syntax
Setup is often the only component property used when a component can use the composition API, so use syntax sugar to simplify setup writing
<script setup>
import { ref } from 'vue'
export const count = ref(0)
export const inc = () => count.value++
</script>
Copy the code
Usage Scenarios:
In VUE 2.0, component data and methods are used to define some current component data. In VUE 3.0, reactive objects are created by ref or reactive. Methods are also written in setup and return.
import {ref,reactive} from 'vue' setup(){ const name = ref('test') const state = reactive({ list: []}) const md = () => {console.log(' method to throw child component ')} return {name, state, md}}Copy the code
Ref creates a reactive data object with a given value and assigns an initial value, and Reactive can directly define complex reactive objects
Unable to use EventBus:
Vue 2.0 uses EventBus for component communication: Vue’s quad-core event methods $ON, $emit, $OFF, $once
var EventBus = new Vue() Vue.prototype.$EventBus = EventBus this.$EventBus.$on('eventName', (val) => { this.modifyNodeHandle(value); }) this.$EventBus.$emit('eventName', { data: result, type: $on() use this.$root.$off('eventName', cb) // cb Optional, remove an event from the event center, $once('eventName', cb) // this.$root.$once('eventName', cb) // same as $onCopy the code
$root, $parent, $refs, $children: Vue child components can access the properties and methods of the parent component instance via the $root attribute. If there are multiple levels of child components, $parent accesses the nearest parent and $root accesses the root parent), so using this.$root.$on allows you to listen directly for vue instances without creating new vue instances
Instead of using mitt scheme in setup, :
Import mitt from 'mitt' const emitter = mitt(). On ('foo', e => console.log('foo', E) // Use emitter. Emit ('foo', {a: 'b'})Copy the code
Vue 3.0 no longer support the prototype of the way to the vue binding static methods that can be achieved by the app. Config. GlobalProperties. Mitt = () = > {}
Setup () uses props and this:
In VUE 2.0, this can be used to obtain the instance of the current component, and perform data variable modification, method call, component communication, etc. In VUE 3.0, setup() has been called in the beforeCreate and created opportunity, so this cannot be used in 2.0. However, you can get props and instances of the current component by receiving setup(props, CTX)
props: {
name: String,
},
setup(props,ctx) {
console.log(props.name)
ctx.emit('event')
},
Copy the code
CTX is not exactly the same as this in 2.0. CTX selectively exposes some properties (attrs, emit, slots).
Watch in the child component to listen for object changes
In 2.0, you can use Watch to listen for changes in object properties; In Setup (), you can use watch to listen;
import {watch} from 'vue'
setup(){
let state = reactive({
name: 'a'
})
watch(
() => state.name,
(val, oldVal) => {
console.log(val)
}
)
state.name = 'b'
return {
state
}
}
Copy the code
If watch is an array object, calling.push to add data does not trigger the watch method, and the array must be reassigned
Using computed properties in setup:
const storeData = computed(() => store.state.storeData)
return { storeData }
Copy the code
conclusion
The code is completely divided into multiple management classes based on business logic, and Setup is only responsible for loading and integrating, and setup doesn’t have a lot of code in it. For example, define in a separate JS file:
Import {ref} from 'vue' export function manageArticleForm () {const modelForm = ref({title: }) return {articleForm: modelForm,}}Copy the code
Then reference it in the child component:
Import {manageArticleForm} from './ bbs-Managearticleform.js' setup() {// form const {articleForm} = ManageArticleForm () return view return {articleForm}}Copy the code
Single-file component status-driven CSS variables:
Component state-driven CSS variables (Style Vars)
Styles can be dynamically updated at run time based on component state (passing parameters to CSS)
<template>
<div class="text">hello</div>
</template>
<script>
export default {
data() {
return {
color: 'red'
}
}
}
</script>
<style vars="{ color }">
.text {
color: var(--color);
}
</style>
Copy the code
Single-file component (style scoped) contains global rules or rules for slot content only:
Style with scoped is no longer scoped to the current single-file component, but has the ability to change other scoped styles through the depth selector, slot selector, and global selector.
<style scoped> /* deep selectors, Styles will take effect in child components */ :: V-deep (.foo) {} /* Dictate */ :deep(.foo) {} /* Targeting Slot content, Use to replace elements that are placed in HTML templates */ :: V-slotted (.foo) {} /* Individuals */ :slotted(.foo) {} /* One-off global rule, Effective global * / : : v - global (. Foo) {} / * shorthand * / : global (. Foo) {} < / style >Copy the code
Major changes in Vue 3.0
The introduction of createApp
There is no concept of “app” in VUe2, and the application we define is just a root Vue instance created with new Vue(). Each root instance created from the same Vue constructor shares the same global configuration, so global configuration makes it easy to accidentally contaminate other test cases during testing. Care needs to be taken to store the original global configuration (e.g., restore after each test, e.g., reset vue.config.errorHandler). Some apis like vue. use and vue. mixin don’t even have recovery effects, making testing involving plug-ins tricky.
// createApp: import {createApp} from 'vue' const app = createApp({})Copy the code
The createApp call returns an application instance that exposes a subset of the current global API, and any global changes to the Vue’s behavior API are moved to the application instance. Other global apis that do not globally change behavior are named exports. Global and internal apis have been refactored to tree-shakable
Tree shaking is a term commonly used to describe the action of removing unreferenced code from a JS context. It relies on the import and export statements in ES6 to detect whether code modules are exported, imported, and used by JS files in modern JS applications. Automatically removes unreferenced code when packaging multiple JS files into a single file using module packaging (Webpack or Rollup). Is the final file structure and minimum size.
2.0 grammar
// Global API vue.nexttick () cannot tree-shaking import Vue from 'Vue' vue.nexttick (() => {// something about DOM})Copy the code
The 3.0 syntax global API can only be accessed as named exports of ES module builds, and if the module binder supports tree-shaking, unused global apis in Vue applications will be eliminated from the final bundle for optimal file size.
Import {nextTick} from 'vue' nextTick(() => {// something DOM related})Copy the code
The affected apis include:
- Vue.nexttick - Vue.Observable (replaced by vue.reactive) - vue.version - vue.compile - vue.set-vue.deleteCopy the code
Vue.observable
Vue.observable: Manages status. As components are refined, multiple component states can be shared, which can be addressed by Vuex, but for small references, Vuex can lead to code fragmentation redundancy. The Addition of the Observable API to Vue2.6 allows you to handle simple cross-component data state sharing. Observable () method, which sets monitoring properties to monitor property values in the viewModule, dynamically changing the value of an element. The type invariant of a monitoring property is a function that returns a function to the property in the viewModule to monitor the property.
Store.js is established in the SRC directory, and the provided store and mutation methods are used in the component to realize the sharing of data state among multiple components.
//store.js import Vue from 'vue'; Export let store = Vue. Observable ({count:0,name:' l '}); export let mutations={ setCount(count){ store.count = count; }, changeName(name){ store.name = name; }} // Import HomeHeader from '.. /components/HomeHeader' import {store,mutations} from '@/store' export default {data () {return {name1:' name'}}, Computed :{count(){return store.count}, name(){return store.name}}, methods:{// SetCount: mutations. SetCount, changeName: Mutations. ChangeName} // HTML <button @click="setCount(count+1)">+1</button @button ="setCount(count-1)"> 1</button> </button @click="changeName(name1)"> </button <div>store name: {{name}}</div> // // displays the name value in the storeCopy the code
The vue version of the current project is lower than 2.6. To use vue.Observable (), upgrade vue and vue-template-compiler must be synchronized.
NPM update vue-s or YARN add vue-s NPM update vue-template-compiler-d or YARN add vue-template-compiler-d 'Copy the code
Vue.version
Provides the Vue installation version number as a string. (Useful for plug-ins and components in the community, which can adopt different policies based on different version numbers)
var version = Number(Vue.version.split('.')[0])
if (version === 2) {
// Vue v2.x.x
} else if (version === 1) {
// Vue v1.x.x
} else {
// Unsupported versions of Vue
}
Copy the code
Vue.compile
Mutate a template string into a render function. $mount(el); $mount(el); $mount(el); $mount(el); EMount) and Runtime /index.js (rMount for short). Use: compile the template string and return the object containing the rendering function. Only available in the full version (not all vue.js builds exist in vue.pile).
var res = Vue.compile('<div><span>{{msg}}</span></div>');
new Vue({
data:{
msg:'hello'
},
render:res.render
})
Copy the code
2, implementation: Vue.compile method only need to call the compiler can be implemented. Vue.compile = compileToFunctions; The compileToFunctions method can compile templates into three steps of rendering function compilation:
- Parse: Template needs to be converted into an abstract syntax tree (AST).
- Optimizer: Mark this abstract syntax tree with static nodes to optimize the rendering process.
- GenerateCode: Generates a render function string based on the abstract syntax tree (AST).
The parser
There is a very important concept in the parser (AST)
There are several different types of AstNodes,Parse the following code:
<div id="demo">
<h1>Latest Vue.js Commits</h1>
<p>{{1 + 1}}</p>
</div>
Copy the code
The following AST is generated:Within the parse function, a number of global properties and functions are defined, and then parseHTML is called. The function parses the template, populates root, and returns root(AST).
parseHTMLThe most important is the code in the while loop, where html.indexof (‘<‘) is used to match:
- __ equals 0: __ represents comment, transpose comment, docType, start tag, end tag
- If the value is greater than or equal to 0, the value is a text or an expression
- __ less than 0: __ indicates that the HTML tag has been parsed and some text or expressions may be left behind
The parse function does this over and over again, converting the Template into an AST and optimizing the whitespace between tags (some elements are useless)
The optimizer
The purpose of the optimizer is to find pure static subtrees in the AST: promote pure static subtrees to constant, so that no new nodes need to be created each time you re-render, and they can be skipped during patch. The first iteration: mark static nodes; Second pass: mark static root node (can’t be leaf node, need to have child node and be static – if a static node has only one half-child node and the child node is a text node, do not do static processing and render directly)
Code generator
Convert AST to render function string. The most important one, the genElement function, selects different code generation functions for different instructions and attributes. Finally, a string is concatenated according to the AST generation.
The core of VUE can be divided into three chunks: data processing and bidirectional binding, template compilation, and virtual DOM
vue.use
Vue.use(plugin); Vue.use(VueLazyLoad, {error: './static/error.png', // Loading: './static/loading.png'});Copy the code
1, Usage: install vue. js plug-in, if the plug-in is an object, must provide the install method. If the plug-in were a function, it would be passed as the install method, and when the Install method is called, Vue is passed as an argument. If the install method is called multiple times by the same plug-in, the plug-in will only be installed once. 2. Function: To register the plug-in, just call install and pass in vue as a parameter. Note: The type of the plug-in can be an install method or an object containing the install method. Plug-ins can be installed only once to ensure that there are no duplicate plug-ins in the plug-in list. 3. Realization:
Vue. Use = function(plugin){// Add the use method to vue.js and accept a plugin. const installedPlugins = (this._installedPlugins || (this._installedPlugins = [])); If (installedplugins.indexof (plugin)>-1){if(installedplugins.indexof (plugin)>-1){if(installedplugins.indexof (plugin)>-1){ } <! // Use the toArray method to get arguments. Const args = toArray(arguments,1); // Then add Vue to the top of the args list. The goal is to ensure that the install method is executed with Vue as the first parameter and the remaining parameters passed in when the plug-in is registered. args.unshift(this); // Since the plugin parameter supports object and function types (objects provide install methods and functions are treated as install methods), the plugin. Install and plugin are functions. If (typeof plugin.install === 'function'){plugin.install.apply(plugin,args); }else if(typeof plugin === 'function'){ plugin.apply(null,plugin,args); } // Add plugins to installedPlugins to ensure that the same plugins are not registered repeatedly installedplugins.push (plugin); return this; }Copy the code
Vue.mixin
Vue.mixin(mixin); 1. Usage:
- Globally register a mixin that affects every vue.js instance created thereafter
- Plugin authors can use interfuse to inject custom behavior into components (e.g., listening for lifecycle hooks)
2. Implementation:
options
Const VM = new Vue(options). Options contains five types of attribute data: Data, props, propsData, computed, and Watch; DOM: el, template, render, renderError; Declare periodic hooks: BeforeCreate, Created, beforeMount, Mounted, beforeUpdate, updated, Activated, deactivated, beforeDestroy, destroyed, and errorCapture d; Resources: Directives, filters, components; Combination: parent, mixins, extends, provide, Inject;
// mergeOptions merges the mixin passed in by the user with this.options into a new object, overwriting the this.options property. Options. // the mixin method modifies the vue. options property, which will be used by every instance created thereafter. Import {mergeOptions} from '.. /util/index' export function initMixin(Vue){ Vue.mixin = function(minxin){ this.options = mergeOptions(this.options,mixin); return this; }}Copy the code
Vue.delete
What is the difference between delete and vue. delete when deleting an array? Delete: Just delete the array member, change the element to empty/undefined, other elements remain unchanged. Vue.delete: Deletes the array members directly and changes the array’s key usage: the object is reactive, ensuring that deletion triggers an update to the view. This method is mainly used to get around the restriction that Vue cannot detect when a property is deleted
Vue.delete(this.namelist,'name'); / / the vue methodCopy the code
The usage of v-Models on components has changed
- When you customize the V-Model, the prop and event default names have been changed
- Prop: value -> modelValue
- Event: input -> update: modelValue
- The.sync and component model options have been removed and v-model can be used instead
- You can now use multiple V-Models on the same component for bidirectional binding;
- You can customize v-model modifiers, such as custom V-Model.capitalize, to bind to the uppercase of the first letter of a string
<template v-for>
And the v-for
The key usage on the node has changed
- Vue 2.0 recommends using keys in v-if/ V-else/V-else if branches. Vue3.0 works fine, but does not recommend it, because a unique key is automatically generated when no key is provided for conditional branches.
- Vue 2.0
<template>
Tags cannot have keys, which in Vue3.0 should be set to<template>
On the label.
The V-if and V-for priorities used on the same element have changed
- In Vue3.0, V-if will have a higher priority than V-for.
V-bind =”object” is now sort sensitive
- Vue2.0 If an element defines both v-bind= “object” and the same separate prototype, the separate property will always override the binding in object.
- The order in which Vue3.0 declares bindings determines how they are merged
<div id="red" v-bind="{id: 'blue'}"></div>Copy the code
Ref in V-for no longer registers the ref array
- In Vue2.0, when the ref attribute is used in v-for, the corresponding attribute retrieved from $refs is an array of refs.
- Vue3.0 binds ref to a more flexible function (ele) => {… // save ele}
<div v-for="item in list" :ref="setItemRef"></div>
import { ref, onBeforeUpdate, onUpdated } from 'vue'
export default {
setup() {
let itemRefs = []
const setItemRef = el => {
itemRefs.push(el)
}
onBeforeUpdate(() => {
itemRefs = []
})
onUpdated(() => {
console.log(itemRefs)
})
return {
itemRefs,
setItemRef
}
}
}
Copy the code