Changes brought by Vue3:

  • Vue2 uses Object.defineProperty to hijack getters and setters of data. One drawback of this approach is that it cannot hijack or listen when adding or removing attributes to objects
  • Vue3 uses proxy to implement data hijacking

Vue creates the project

NPM install@vue /cli -g // Upgrade vue CLI NPM update @vue/cli -g // Create a project using vue commands vue create a project nameCopy the code

Arrow functions cannot be used:

  • The Vue source code traverses all functions in methods and binds this with bind, whereas the arrow function does not have this

V-bind binds the class attribute to the tag:

// Object syntax // The first active is a string with or without a semicolon, isActive is a variable <div :class="{active: IsActive} "> < / div > / / array syntax < div: class =" [' ABC 'isActive?' active ':'] "> < / div >Copy the code

V-bind dynamic binding properties:

 <div :[name]='value'></div> 
Copy the code

V-bind Binds an object:

<div v-bind='info'></div> <div :='info'></div>Copy the code

V-on modifier:

  • .stop Calls Event.stopPropagation () to stop bubbling
  • .prevent calls event.preventDefault() to prevent the default behavior
  • .once – Only one callback is triggered.
  • .self – The callback is triggered only if the event is triggered from the listener bound element itself.

V-on parameter transfer

  • This method does not need arguments, so the () after the method can be omitted
  • If the method requires an argument and the method is not followed by a (), the event argument is automatically passed in
  • If multiple parameters require event to be, pass in $event

Key functions in V-for:

  • In Vue, template -> VNode -> real DOM
  • <div class='title' style="font-size: 30px; color: red;" > </div> // const vNode = {type: 'div', props: {class: 'title', style: {'font-size': '30px', color: 'red',}}, children: 'hahaha'}Copy the code

The computed:

// If you want to set the value of computed, computed: {fullname: {fullname: {fullname: Set (value) {get() {return}, set(value) {//Copy the code

watch

// Watch: {message(newValue, oldValue) {// This function is used when message changes}} // Watch: {info: Handler (newValue, oldValue) {handler(newValue, oldValue) {// Enter this function when info changes}, deep: true, // Enable deep listening immediate: Function (newValue, oldValue) {}} function(newValue, oldValue) {}}Copy the code

$watch

created() {
    this.$watch('message', (newValue, oldValue) => {
​
    }, { deep: true, immediate: true })
}
Copy the code

v-model

< INPUT V-model ='searchText' /> // equivalent to <input :value="searchText" @input="searchText = $event.target.value" /> // modifier .lazy // v-model binds to an input event, which synchronizes the latest value with the bound attribute each time the content is entered. Number // The value bound by the V-model will always be string. If you want to convert to a number, use the. Number modifier. Trim // to remove whitespaceCopy the code

Certified components

CreateApp (App) const App = vue.createApp (App) app.component.ponent (' component name ', {component object})Copy the code

Parent-child component communication

// Props: ['title', 'content'] // Props: {title: String, // type require: True, // Whether the value is mandatory default: 'hahaha' // Default if type is reference type default is a function} // Note: The HTML attribute name is case-insensitive, and the browser will interpret all uppercase characters as lowercase characters. Therefore, in the tag, the props name needs to use kebab-case(short line split name) // pass the child to the parent through the emit // emits in the child component: ['add'] // array writing emits: {// Use object writing to verify the passed parameters add: null, addTen(payload) { if (payload === 10) { return true } return false } } methods: {increment() {this.$emit('add', pass parameter)}}Copy the code

The Attribute of the prop

  • When we pass a component an Attribute that does not define props or emits, we call it a non-prop Attribute. Common examples include class, style, and ID

  • Attribute inheritance. When a component has a single root node, non-prop attributes are automatically added to the attributes of the root node

  • If you don’t want the component’s root component to inherit attributes, you can set inheritAttrs: false in the component

  • All non-prop attributes can be accessed with $attrs

    <div :class='$attrs.class'></div>
    Copy the code

Dojo.provide and Inject

Provide: {name: 'cf', age: {name: 'cf', age: {name: 'cf', age: {name: 'cf', age: This return {name: 'cf', age: 18, length: This.names. length // If names is changed, the child component uses a non-responsive length: Computed (() => this.names.length) // Use computed functions to return a ref object that is responsive}} // The component that receives data inject: ['name', 'age', 'length']Copy the code

Global event bus Mitt

Eventbus.js Import mitt from 'mitt' const emitter = mitt() export default emitter Create () {emitters from './eventBus' Emitters. Emit (' emitters ', 'emitters ',' emitters ', emitters from './eventBus' Emitters. (parameters) = > {}) emitter. On (' * '(type, parameters) = > {/ / monitor all events, Function onFoo() {} Emitter.all. Clear () function onFoo() {} Emitter.on ('foo', OnFoo) // Monitoring emitter. Off ('foo', onFoo) // Canceling monitoringCopy the code

slot

<slot> default content </slot> // Display default content when using this component and no content is inserted // named slot // a slot with no name, Default <slot name='left'></slot> // When inserting content into the named slot <template v-slot:left> // V-slot: </ / Insert what you want here </template> // Dynamic slot name <slot :name='name'></slot> // Where name is passed in via props <template V-slot :[name]></template> // render scope: everything in the parent template is compiled in the parent scope; Everything in a subtemplate is compiled in a subscope; // Usage, <slot :item='item' :index='index'></slot> <template V-slot :default='slotProps'> // SlotProps can be named as anything. Item slotProps. Index </template>Copy the code

Dynamic components

< Component :is=' Component name (lowercase) '></component> // Dynamic component passing and listening directly on componentCopy the code

Keep-alive cache component

<component :is=' component name (lowercase) '></component> </keep-alive> // exclude Created and Mounted life cycle functions are not executed when a component is re-entered and re-entered. Activated and deactivated can be used to monitor when a component is re-entered and when a component is removedCopy the code

Asynchronous components

  • If our project is too big and we want to load components asynchronously (so we can subcontract them), we have a function in Vue: defineAsyncComponent.
// defineAsyncComponent takes two types of arguments: // Type 1: factory function that returns a Promise object Import {defineAsyncComponent} from 'vue' // During webpack, modules imported by the import() function are packaged separately, And the function returns a Promise object const AsyncHome = defineAsyncComponent(() => import('./ asynchome.vue ')) // Type const AsyncHome = defineAsyncComponent({ loader: () => import('./AsyncHome.vue'), loadingComponent: Loading, // errorComponent: Error displayed during Loading, // component displayed when Loading failed // and some other properties})Copy the code

suspense

Suspense is a built-in global component that has two slots // default: If default can be displayed, then display the contents of default // fallback: If default cannot be displayed, < girl > < girl > < girl > < girl > < girl > < girl > < girl > < girl > < girl > </suspense>Copy the code

The use of $refs

// Get the element object or child component instance // get the parent element and root element with $parent and $rootCopy the code

Life cycle function

The component of v – model

<my-cpn v-model='message' /> // equivalent to <my-cpn :model-value='message' @update:model-value='message = $event' />Copy the code

mixin

Import mixinObj from 'path' export default {mixins: // Create a mixin object that can contain all the attributes of a component. [mixinObj]} // Mixin merge rules // If it is a data return value object, it will be merged by default. If there is a conflict of properties, the component's own data will be retained. // Const app = createApp(app); // Const app = createApp(app); App. Mixin (} {mixin object)Copy the code

The setup function

Arguments to the setup function (without this) :

  • The first parameter, props(reactive), if destructed, eliminates the reactive of prop
  • The second argument context
  • Context (not reactive) is also called setupContext and contains three properties
  • Attrs: All non-prop attributes
  • Slots: Slots passed by the parent component
  • Emit: Emits an event within the component

The return value of the setup function can be used in the template

reactive Api

Const state = reactive({name:); // To provide reactive properties for data defined in setup, use reactive(). 'cf'}) // Dependencies are collected when data is used again. // When data changes, all dependencies are collected for reactive operations. // In fact, the data option is handed to reactive internallyCopy the code

ref Api

// ref returns a mutable response object (ref object) whose internal value is maintained in the value property of ref const message = ref('hello ref') // In template vue does shallow unpack for us, Value is still a reference to ref. Value in the setup function, so if you place a ref object in a reactive property, Ref <h2 ref='titleRef'></h2> setup() {const titleRef = ref(null) return {titleRef}}Copy the code

readonly Api

// Readonly returns a read-only proxy for the native object (still a proxy, which is a proxy whose set method has been hijacked and cannot be modified) // Readonly usually passes three types of parameters // Common object type 2: Reactive returns object type 3: Ref object const state = readonly(info) // The state of the object returned after readonly is not allowed to be changed, but the info can be changed, and the object returned after info changes readonly is also changedCopy the code

toRefs Api

Const {name, age} = toRefs(state) const {name, age} = toRefs(state) Changing either name.value or state.name causes changes to the otherCopy the code

toRef Api

// if you want to convert only one of the attributes of a responsive object toRef, then you can use the toRef method const name = toRef(state, 'name') // name.value and state.name to establish a connectionCopy the code

unref Api

// If you want to get a value from a ref reference val = isRef(val)? Val.value: val unref() is the syntax sugar aboveCopy the code

computed Api

// When some of our attributes depend on other states, we can use computed attributes to handle // How to use computed // Method one: Receives a getter function that returns a value, Returns a constant ref object const fullName = computed(() => firstname.value + "+ lastname.value) // Receives an object with get and set, Returns a mutable (read-write) ref object const fullName = computed({get() {return firstname.value + "+ lastname.value}, Set (newValue) {// newValue is the newValue}})Copy the code

watchEffect Api

// The watchEffect function is executed immediately, and dependencies are collected during execution. When the collected dependencies change, the watchEffect function is executed again. Const stopWatch = watchEffect(() => {}) // watchEffect clears the side effect // The function we passed to watchEffect gets a callback: Const stopWatch = watchEffect((onInvalidate) => {console.log(...)) . OnInvalidate (() => {// The watchEffect will be executed first})}) // When the setup function is executed, the watchEffect will be executed immediately by default. If you do not want to execute it immediately, WatchEffect (() => {}, {flush: 'post' // default pre})Copy the code

watch Api

// Compare to watchEffect // Lazy execution side effects (not executed the first time) // Can be more specific to those state changes that trigger the execution of the listener // Can access the value of the state changes before and after the listening // There are two types of listening for a single data source // Type one: Watch (() => state.name, (newValue, oldValue) => {}, {deep: true, immediate: True}) // Watch option configuration Just write a responsive object, Reactive watch(name, (newValue, oldValue) => {}) watch([name, age], (newValue, OldValue) => {}) // If we want to listen for an array or object, we can use a getter function, Watch (() => [...names], (newValue, oldValue) => {})Copy the code

Setup life cycle function

  • BeforeCreate and created are written directly inside the setup function body

Dojo.provide function

Provide (' provided attribute name ', 'provided attribute value ')Copy the code

Inject function

Const counter = inject(' Inject attribute name ', 'default value ')Copy the code

H function

// the h function is a function used to create a vnode. The more accurate name is createVNode. Vue simplifies this function to the h function, which takes three arguments: It can be a String, Object, or Function, an HTML tag name, a component, or a functional component. // The second argument can only be an Object, corresponding to attribute, prop, or event, optional. // The third argument: can be string, array, object, the contents of the label body, optional h('div', {class: Render () {return h('div', {class: 'app' }, 'hello App') } setup() { return h('div', { class: 'app' }, 'hello App') }Copy the code

Custom instruction

// Customize local directives: The component uses the cache option, only for the current component. Cache: {focus: V -focus Mounted (el, binding, vnode, prevNode) {}}} The directive method for app, Directive ('focus', {mounted(el, binding, vnode, prevNode) {}}) directive('focus', {el, binding, vnode, prevNode) {}}) Aaa, BBB is the modifier <div V-focus :info.aaa. BBB ></div> // The parameters and modifiers can be obtained via the directive's lifecycle parameter bindingCopy the code

The life cycle of an instruction

teleport

// This isa built-in component provided by vue, similar to the React portals // with two properties // to: Specify to move its contents to the target element, you can use the selector // disabled: Whether to disable teleport <teleport > <div> cf </div> </teleport>Copy the code

vue-router

The Url hash:

  • The HASH of the URL, also known as the anchor point (#), essentially changes the href attribute of window.location
  • You can change the href by assigning location.hash directly, but the page does not refresh

HTML5’s History interface has six modes for changing urls without refreshing the page:

  • ReplaceState: replaces the original path
  • PushState: Uses the new path
  • PopState: rollback of a path
  • Go: Changes the path forward or backward
  • Forward: changes the path forward
  • Back: Changes the path backwards
// Install vue-router 4.0 NPM install vue-router@4 // In router/index.js import {createRouter, createWebHashHistory, createWebHistory } from 'vue-router' const routes = [ { path: "/", redirect: '/home' // redirect}, {path: '/home', component: () => import('../pages/ home.vue ') // router lazy loading // router lazy loading makes components subcontract when packaging // Can use magiccomments to name packaged files // import(/* webpackChunkName: "The home - the chunk" * / ".. / pages/home ')}, {path: '/ user / : id', / / dynamic routing component: () = > import ('... ')}, {path: '/:pathMatch(.*)', // Not Found page route match // or path: '/:pathMatch(.*)*' // a *(will not parse '/') and **(will parse '/') will get a different parameter // $route.params.pathMatch will get the parameter passed to component: () => import('...') } ... ] Const router = createRouter({routes, history: createWebHashHistory() // hash mode history: CreateWebHistory () import router from './router' app.use(router) import router from './router' app.use(router) <router-view></router-view> </router-view> </template> // router-view in app. vue v-slot <router-view v-slot="{ Component }" > <component :is='Component' ></component> </router-view> // <router-link></router-link> Components can change paths <router-link to='/home'> home </router-link> // router-link attribute // to attribute: The // replace property: if set, router.replace() is called when clicked, instead of router.push() // active-class: Set the class name of the component of the active route object. The default is router-link-active // exact-active-class: Unlike active-class, router-link-exact-active // Router-link v-slot // Router-link tags can write labels and components. By default, write tags or components are wrapped with an A tag, {href, route, navigate, if desired, add the custom attribute <router-link to='/about' V-slot ="props"> // props to the router-link tag. IsActive, isExactActive} // href: parsed URL // route: parsed normalized route object // navigate: // isActive,isExactActive: </router-link> // route object and router object // <template>{{$route.params: {$route.params: {$route.params: {$route.params: {$route.params: {$route.params: {$route.params: {$route.params: {$route.params: { }}</template> // In optionsApi this.$route.params. $router.push('/profile') // This.$router.push({// This.$router.push({// This.$router.push({// This.$router.push({// This.$router.push({// This. Query: {name: 'cf', age: }}) // In compositionApi, UseRouter () import {useRoute, useRouter } from 'vue-router' setup() { const route = useRoute() const router = useRouter() route.params. } // Add router/ / add router. AddRoute in router/index.js // Add a children route to the route Router. AddRoute (route name, route object) // Dynamically delete the route // Method 1: Add a route with the same name (the name attribute must be unique), which overwrites the route. Router. RemoveRoute ('about') // Callback const removeRoute = router.addroute ('about') removeRoute() // Remove the route if it exists // add another route method Router.hasroute () // checks if the route exists router.getroutes () // gets an array of all the route records // Route navigator // Global front-guard beforeEach is called back when navigation is triggered Route. beforeEach(to, from, next) {// to: entering route object // From: leaving route object // next: leaving route object Vue3 is controlled by return value, it is not recommended to use this parameter // Return value: false Cancel current navigation, // do not return or undefined for default navigation // Return a route address: a string path or an object}Copy the code

vuex

// vuex NPM install vuex@next // createStore folder // index. HTML import {createStore} from 'vuex' const store =  createStore({ namespaced: Actions, mutations, and getters are registered in the global namespace by default, which causes multiple modules to respond to the same action or mutation or getter. State () {return {}}, mutations: {// must be a synchronization function, Increment (state, payload) {increment(state, payload) {increment(state, payload) { Use mutations only to change the method in mutations. This. codestore.com ('increment', parameter)}}, getters: {total(state, getters) {// Getters is similar to calculating properties. // Getters can get other getters for getters. // Functions in getters can return a function, // The advantage of returning a function is that it can be called with arguments}}, actions: Increment (context, payload){increment(context, payload){increment(context, payload){ $increment. dispatch('increment', {parameter}); $increment. dispatch('increment', {parameter}) Commit this.$store.dispatch({type: 'increment', argument}) // Return a Promise object // If the action in the submodule wants to modify or send the root context.com MIT (' event name ', null if no parameter is specified, {root: True}) context.dispatch(' event name ', null, {root: true})}}, modules: {moduleA, // moduleA and moduleB are both an object moduleB, // Get the status of the submodule, store.state.a // For mutations and getters properties inside the module, The first argument received, state, is a local state object. // Getters can also receive a third argument, rootState}, }) export default store // in main.js import store from './store' app.use(store) // use store object in template {{$store.state.counter}} // Use the store object in optionsApi this.$store.state.counter // Use the store object in compositionApi import { UseStore} from 'vuex' const store = useStore() import {mapState, mapGetters } from 'vuex' computed: { ... MapState (['state ', ']]) {// You can pass object {name(state => state.name}... MapGetters (['getters ']); mapGetters({ finalPrice: 'totalPrice' }) }, methods: { ... mapMutations([]), ... MapMutations ({信 息 链 接 : 'increments'}) MapActions ([]) // the same usage as mapMutations} // return {... Mapstate ([])} // Because of mapState,mapGetters returns an object, each attribute of which is a function, Import {useStore, mapState, mapGetters } from 'vuex' import { computed } from 'vue' export funcion useState(mapper) { const store = useStore() const  storeState = mapState(mapper) Object.keys(storeState).beforeEach(fnKey => { storeState[fnKey] = computed(storeState[fnKey].bind({$store: store})) }) return storeState } setup() { return { ... MapMutations ([]) // open easily}} // module auxiliary function // if divided module // method 1: through the complete module space search, for example... MapState (['moduleA/counter']) // Method 2: Pass the first argument to the module space name followed by the attribute to be used... MapState ('moduleA', []) // Generate a module helper function at createNamespacedHelpers const {mapState,... } = createNamespacedHelpers('moduleA'Copy the code

nexttick

Nexttick (() => {}) nexttick(() => {}) nexttick() => {}) At this time, the callback function of the microqueue has not been executed and the interface has not been refreshed, so it cannot be obtained. However, the callback of Nexttick will be placed in the last position of the microqueue, so accurate data can be obtained in the callback function of NexttickCopy the code

Manually configure Webpack to handle.vue files

Vue source package
  • Install vue, currently NPM install vue@next (wait until the official vue default version is set to 3, directly vue can be used)

  • Write vUE code

    import { createApp } from 'vue' createApp({ template: {return {title: '123'}}}).mount('#app').Copy the code
  • After packaging, we find that there is no rendering on the interface, and we check the console to find the following warning message

Vue is packaged and resolved for different versions
  • vue(.runtime).global(.prod).js:

    • The version referenced directly through the script tag in the browser
    • The VUE version imported and downloaded through the CDN is this version
    • A global VUE is exposed for use
  • vue(.runtime).esm-browser(.prod).js:

    • For import use via native ES module (for use via browser)

  • vue(.runtime).esm-bundler.js:

    • For build tools such as Webpack, rollup, and Parcel
    • Build tools in the default is to use vue. Runtime. Esm. Bundler. Js (so it has the template interface can not display)
    • If we need to parse the template, we need to specify vue.esm-bundler.js manually
  • vue.cjs(.prod).js:

    • Server side rendering use
    • Used in Node.js by require ()

runtime-only VS runtime-compiler
  • There are three ways to write DOM elements in VUE development

    • Mode 1: Template Indicates the template mode
    • Method 2: the way of the render function, using h function to write the content of the render
    • Method 3: Use template in the.vue file to write templates
  • How are their templates handled?

    • The h function of method 2 can directly return a virtual node, namely a VNode node

    • Both approaches one and three require specific code to parse them

      • Template in vue file can be compiled and processed by vue-loader
      • The template in method 1 must be compiled using part of the source code
  • So, VUE is divided into runtime+compiler vs Runtime-only when it lets us choose the version.

    • The Runtime +compiler contains compiled code for the Template template, which is more complete, but also larger
    • Run-time only contains no compiled code for the template version, which is smaller
Configuration of global identifiers:
  • We’ll find another warning on the console

The instructions can be found in the documentation on GitHub:

  • This is a sign of two features, one is to use vue options, and the other is to support devTools in production mode
  • Although they all have default values, it is highly recommended that we configure them manually
Webpack configuration. Vue file
  • Install vue-loader, NPM install vue-loader@next -d

  • Do this in the template rule with WebPack

    {
        test: /.vue$/i,
        loader: 'vue-loader'
    }
    ​
    Copy the code
  • Install @vue/ compiler-sFC, essentially vue-loader also uses @vue/ compiler-sFC to parse

    • npm install @vue/compiler-sfc -D
  • Configure the corresponding VUE plug-in

    const { VueLoaderPlugin } = require('vue-loader')
    ​
    new VueLoaderPlugin()
    Copy the code