Vue

Personal website is constantly updated

Changes to Vue2.0 and Vue3.0

DefineProperty in Vue2.0 and Proxy in Vue3.0

let obj = { name: []};// proxy
obj = new Proxy(obj, {
    get(target, prop) {
        return target[prop]
    },
    set(target, prop, val) {
        target[prop] = val
    }
})
// Object.defineProperty
let newObj = JSON.parse(JSON.stringify(obj))
Object.defineProperty(obj, 'name', {
    get() {
        return newObj.name
    },
    set(val){ newObj.name ! == val && (obj.name = val) } })Copy the code

In Object. DefineProperty, you need to recursively listen for each attribute, which not only wastes performance, but also can’t listen if there is no attribute defined in the initial value. This means that new attributes in Vue2.0 will not change in view. Hence the need to use $set for new attributes


Vue2.0

Why does the virtual DOM perform better

Virtual DOM is equivalent to using JS to construct the page into a DOM tree with object structure. When changes occur, the old DOM tree will be compared with the new DOM tree to find out the differences, and finally render the real DOM

Why is data a function

If two instances refer to the same object, when the properties of one instance change, the properties of the other instance also change. Only when the two instances have their own scope can they not interfere with each other, that is, there is no variable pollution

Why does Vue use asynchronous rendering

The fundamental reason is to improve performance. To put it simply, when data changes, the data is not immediately updated, but temporarily stored in asynchronous functions. After the synchronization operation is completed, the asynchronous operation is performed to process the data, and finally the valid data is updated to the view.

The principle of two-way data binding, how to customize v-Model

Vue2.0: Data hijacking combined with the publiser-subscriber pattern, using Object.defineProperty() to hijack the setter and getter of each attribute, publish the message to the subscriber when the data changes, and trigger the corresponding listener callback

Implement two-way data binding

  • Custom v – model

    <! -- Parent component register and use -->
    <k-input v-model="search" placeholder="Please enter your search terms"></k-input>
    <! -- Subcomponent -->
    <input type="text" :value="value" @input="handleInput" />
    Copy the code
    / / child component
    export default {
      name: "kInput".model: {
        prop: "value".event: "input",},props: ["value"].methods: {
        handleInput(e) {
          this.$emit("input", e.target.value); ,}}};Copy the code

The principle of event binding

The difference between watch and computed

  • Watch: The listening attribute depends on the cache and is recalculated only when the dependency changes. Recommended for listening on multiple data at the same time
    • Immediate: Executes immediately
    • “Deep” : deep listening
  • Computed: Computed attribute data changes are triggered immediately

Component communication

  • Parent-child component communication

    • Parent —–> child: props passes the value, the child props receives the value, and the ref can be used to obtain the data and methods of the child component
    • Child —–> parent: $emit() calls the method passed by the parent component and carries arguments to the parent component
  • Non-parent component communication

    • Bus Event bus

    • provide / inject

      // Ancestor component
      provide: {provideData:"hello"
      }
      // Descendant components
      / / 1.
      inject: ["provideData"]
      / / 2.
      inject: {provideData: {from:"provideData".default:"hello"}}Copy the code
    • Vuex

Route Configuration

import Vue from "vue";
import vueRouter from "vue-router";
Vue.use(vueRouter);

// Nested by
routes: [{
    path: '/offerreward'.name: 'offerreward'.component: () = > import('path'),
    children: [{
      path: 'rewIndex'.name: 'rewardIndex'.component: () = > import('path'),}}]]// Route redirection
{ path: 'Current route'.redirect: 'Redirect destination route'}
// For vue-Router 4.0, it matches an unfound route notation
{ path: '/:pathMatch(.*)*'.redirect: "/ 404" }
// Dynamic routing
{ path: 'Current route /:id'.component: () = > import('path')}
// The address bar can match the current route with the current route /123. The page can obtain the ID through params
// Route parameters are transmitted
// The page can be passed query or params to receive arguments through this.$route
Copy the code

Route guard and execution order

  • Routing guard
    • beforeEach: Global front guard
    • beforeResolve: Global parsing guard
    • beforeEnter: Route exclusive guard
    • afterEach: Global rear guard
    • beforeRouteEnter: component internal guard, called until the corresponding route to render the component has been confirmed, cannot access this, can pass a callback to Next to get the component instance (also the only hook that can pass a callback to Next)
    • beforeRouteUpdate: internal component guard, called when the current route has changed but the component is being reused
    • beforeRouteLeave: Guard inside a component, called when navigating away from the corresponding route of the component
  • Execution order
    • Navigation is triggered.
    • Called in a deactivated componentbeforeRouteLeaveThe guards
    • Call globalbeforeEachThe guards
    • Called in a reused componentbeforeRouteUpdateThe guards
    • Called in the routing configurationbeforeEnter
    • Parse the asynchronous routing component
    • Called in the active componentbeforeRouteEnter
    • Call globalbeforeResolveThe guards
    • Navigation confirmed
    • Call globalafterEachHook.
    • Trigger a DOM update.
    • Call with the created instancebeforeRouteEnterGuard passnextThe callback function of

Programmatic and declarative navigation

  • Programmatic navigation:router.replace(...)
  • Declarative navigation:<router-link :to="..." replace>
    • How to pass parameters:to="{path:'/test',query:{name:id}}
  • The difference between Push and replace:
    • Push adds a new record to history

How do I manage rights

  • Menu management

    • Front-end management: Set meta labels in the route, set role array, save the user’s permission during login for judgment, and hide or display the menu bar
    • Combination of the front and back ends: Sometimes the menu is returned to the back end, and the administrator has the ability to modify permissions
    • Of course, in both ways, the route guard needs to determine whether the current route to be entered has the corresponding permission. If not, the route is redirected to the corresponding route
  • Operation management (front-end only, not back-end)

    • Determine the route permission based on the route configuration

What are the routing modes? What are the differences? How do they work?

  • Hash: the character after #. Changing the hash will not rehash the HTTP request
  • History: Refreshing the page if there is no back-end configuration, the page will be treated as a GET request, resulting in an error

A route is a router

  • The router is an instance of the VueRouter and contains properties and methods
  • Route is the current route object, including name, Path, and Query

mixin

Event modifier

  • .stop: Prevents bubbles
  • .once: The command is executed only once
  • .native: Listens for the native event of the component root element

The life cycle

  • beforeCreate: called after instance initialization, data observation and before event/ Watcher event configuration.
  • createdData observation and event/watcher events were completed, and $el could not be retrieved
  • beforeMount: called before the mount begins: relevantrenderThe function is called for the first time
  • mountedWhen the instance is mounted, the DOM is the first to be retrieved$nextTick()I can do it up here
  • beforeUpdate: Called when data is updated
  • updated: after the virtual DOM is re-rendered due to data changes
  • activated : called when activated by a keep-alive cached component
  • deactivated : called when a component cached by keep-alive is disabled
  • beforeDestroy: called before instance destruction
  • destroyed : called after instance destruction

Difference between V-if and V-show

V-if: No render, meaning there is no element at all

v-show: display:none

The priority of V-if and V-for? Why is that?

V-for has a higher priority

Why is the key passed in v-for

When v-for is used for list rendering, it defaults to the “update in place” strategy. Adding key is equivalent to adding ID to each node, so that diff algorithm can find nodes faster and more accurately for rendering

Make cross-domain requests in Vue

proxyTable: { 
  '/api': {  // Use "/ API "instead of "http://xxxx"
    target: 'http://xxxx'./ / the source address
    changeOrigin: true./ / change the source
    pathRewrite: { 
      '^/api': 'http://xxxx' // Path overwrite}}}Copy the code

NextTick principle

A deferred callback is performed after the next DOM update loop ends

Vuex

  • Introduction: Vue’s state management system, state is used to define data, actions is used to trigger the creation of mutations, mutations modify data, notify Vue to update the view

  • Usage (modular)

    • The file directories are as follows:

    • Store code

      // store/index.js
      import Vue from 'vue'
      import Vuex from 'vuex'
      import About from './about'
      Vue.use(Vuex)
      
      export default new Vuex.Store({
        modules: {
          About // The module used}})// store/about/index.js
      import state from './state'
      import actions from './actions'
      import mutations from './mutations'
      import getters from './getters'
      export default {
        namespaced: true.// Enable the namespace
        state,           // Define data
        mutations,       // Create the action
        actions,         // Trigger action
        getters          // Get data
      }
      
      // store/about/state.js
      const state = {
        count: 0
      }
      export default state
      
      // store/about/type.js
      export const ADD_COUNT = "ADD_COUNT"
      
      // store/about/actions.js
      import * as type from './type'   // The type of action
      const actions = {
        addCount({ commit }, payload) {
          commit(type.ADD_COUNT, payload)   // Commit triggers the mutations action. If the data is changed asynchronously, the results must be placed in actions. Payload is the data transmitted on the page}}export default actions
      
      // store/about/mutations.js
      // Only synchronous code can be executed
      import * as type from './type'
      const mutations = {
        [type.ADD_COUNT](state, payload) {
          state.count = payload   // Payload Is the data transmitted by the action}}export default mutations
      
      // store/about/getter.js
      const getters = {
        count: state= > state.count
      }
      export default getters
      Copy the code
    • Use in pages

      <div class="about">
          <button @click="ADD_COUNT(8)">+</button>
          <! -- <button @click="addCount(8)">+</button> -->
          <br />
          {{ count }}
          <! {{$store.state.count}} -->
       </div>
      Copy the code
      // If the namespace is not enabled:
      Vuex provides four methods to facilitate writing
      import { mapActions, mapGetters, mapMutations, mapState } from "vuex";
      export default {
        computed: {
          / /... MapState (["count"]),// Get state equal to $store.state.count. mapGetters(["count"]), // Getting the getter is equivalent to $store.getter.count
        },
        methods: {
      	The second argument is the data passed to vuex
          // this.$store.dispatch('addCount',8) corresponds to actions
          $store.com MIT ('addCount',8) corresponds to mutations. mapActions(["addCount"]),
          ...mapMutations(["ADD_COUNT"]),}};Copy the code
      // If the namespace is enabled
      import { mapActions, mapGetters, mapMutations, mapState } from "vuex";
      export default {
        computed: {
          / /... mapState("About", ["count"]),. mapGetters("About"["count"]),},methods: {
          ...mapActions("About"["addCount"]),
          ...mapMutations("About"["ADD_COUNT"]),}};Copy the code

The diff algorithm

Encapsulate custom directivesdirective

Slot and scope slots

<! -- Child -->
<template>
  <div>
    <div class="header">
      <slot name="header" ></slot>
    </div>
    <slot name="body" :scope="{a:52}"></slot>
  </div>
</template>
Copy the code
<Child>
    <template #header>I am a header</template>
    <template v-slot:body="{scope}">I am a body<div>{{scope}}</div>
    </template>
</Child>
<! {" A ": 52} -->
Copy the code

White during solve

  • An error hang
    • PublicPath set
    • Route mode, app is hash
    • Other issues (packaging configuration, resource references…)
  • The home screen is blank for a long time
    • The home page loads too much data
    • Join the loading
    • Route lazy loading

Environment Variable Configuration

  • .env.development
  • .env.production
  • NODE_ENV= Process.env.node_env gets script –mode development from package.json

The MVC and MVVM

  • MVVM ([implementation](Object.defineProperty in #Vue2.0 and proxy in Vue3.0))
    • Model: Data Model
    • View: View
    • ViewModel: The model is bound to the view
  • MVC
    • Model: Data Model
    • View: View
    • Controller: Bridge layer between data model and View

There is not much difference between MVVM and MVC, which are both design ideas. Controller in MVC is transformed into viewModel in MVVM. MVVM mainly solves a large number of DOM operations in MVC, which reduces page rendering performance, slows down data loading and affects user experience.

keep-alive

Cache inactive component instances

  • includeComponents with matching names are cached.
  • excludeComponents with matching names are not cached.
  • max– digital. Maximum number of component instances can be cached.

The difference between assets and static


Vue3.0

Modular API

setup
  • Two parameters: props,context
  • Used before the component is created
  • accessthisThe outputundefined
  • portal
Provide/Inject optimization

To a certain extent, an alternative to Vuex might be considered

Usage:

//1. Ancestor component

/ / setup
import { provide , readonly } from 'vue'
const location = reactive({
    count: 1.name: "remons"});// Set it to reactive, with the first argument: the name of the injection; Second argument: the value of the injection
provide("location", location);
// provide("location", readonly(location)); This ensures that the value will not change
// The way vUE officially recommends changing Provide is that descendant components call ancestral component methods
const changeLocation = () = > {
    location.count++
};
provide('changeLocation',changeLocation)


//2. Descendant components:
import { inject } from 'vue'
// Get the ancestor passed value. The first argument is the name of the ancestor passed value. Second argument: default value
const location = inject("location");
// If you change the value here, the parent value will also change
const changeLocation = () = > {
    location.count++;
};
// Vue officially recommends using the method of changing the value passed to call the ancestor component
// const changeLocation = inject(changeLocation)
Copy the code

Responsive API

reactive
readonly

Object read-only proxy (deep level)

ref

Returns a reactive and mutable REF object

Value can be used in the template, and reactive is automatically unnested

toRefs

Convert reactive objects to normal objects

Computed with the watch
  • computed

    import { computed } from 'vue'
    const plusOne = computed(() = > count.value + 1)
    Copy the code
  • watch

    const state = reactive({ count: 0 })
    watch(
      () = > state.count,
      (count, prevCount) = > {
        / *... * /})Copy the code

    Note: If watch listens for vuEX values, write watch before computed

watchEffect

Executes a function passed in immediately, tracing its dependencies in a responsive manner, and stops automatically when the component is unloaded

The life cycle

In addition to adding on, the destruction hook has the following transformations, which are introduced when used, and are included in setup

  1. beforeDestroy => onBeforeUnmount
  2. destroyed => onUnmounted

Add two debug hooks

  1. onRenderTracked
  2. onRenderTriggered

High order Component (HOC)

The optimization of Vue3

Other changes

teleport

To: Render node: sort of like a slot

Suspense
<Subpense>
	<template #default>
        <! -->
    </template>
    <template #fallback>
        <! -- display before loading -->
    </template>
</Subpense>
Copy the code

Vue3.0 combined with Vuex 4.0

// There is no big difference in the usage. When created, it is the same as vex3.0
import { createStore } from 'vuex';
export default createStore({
  modules: {
    // The module used}})/ / components
import { useStore, mapState, mapGetters, mapMutations, mapActions } from "vuex";
import { computed } from "vue";
export default {
  setup() {
    const store = useStore();
    // Common usage
    let detailCount = computed(() = > store.state.detail.detailCount).value,
      listCount = computed(() = > store.state.list.listCount).value;
    const addDetailCount = (val) = >
      store.dispatch("detail/addDetailCount", val);
    const addListCount = (val) = > store.dispatch("list/addListCount", val);
    // Use mapState, mapGetters, mapMutations, mapActions
    // const listState = mapState("list", ["listCount"]);
    // const detailState = mapState("detail", ["detailCount"]);
    // let listCount = computed(listState.listCount.bind({ $store: store }));
    // let detailCount = computed(detailState.listCount.bind({ $store: store }));
    return{}; }};Copy the code