Vue.js- state management and Vuex

Learning notes:State Management and Vuex

State Management and Vuex

Non-parent and child components (cross-level components and sibling components) communicate using thebus(Central Event Bus) A method used to trigger and receive events to further communicate.

A component can be divided into data (model) and views (view), the view will be updated automatically when the data is updated. Another event can be bound in the view, which triggersmethodsThis is the basic operation mode of a component.

const store = new Vuex.Store({});

WarehousestoreIt contains the data (state) and operation process of the application. The data in Vuex are responsive, and any component uses the samestoreThe data, as long asstoreThe corresponding components will also be updated immediately if the data of the.

The data is saved in the Vuex option’sstateWithin the field.

const store = new Vuex.Store({
    state: {
        count: 0
    }
});

Within any component, it can be directly passed through$store.state.countRead.

<template>
    <div>
        <h1>首页</h1>
        {{$store.state.count}}
    </div>
</template>

Direct unloadingtemplateIt seems a bit messy in the, can use a calculation attribute to display:

<div>
    <h1>首页</h1>
    {{count}}
</div>

export default {
    computed: {
        count() {
            return $store.state.count;
        }
    }
}

From within the assemblystoreThe data of can only be read and cannot be modified manually.storeThe only way to do this is to submit the data explicitlymutations.

mutationsIs Vuex’s second option, used to modify directlystateThe data in.

Within the assembly, bythis.$store.commitMethod to executemutations.

mutationsYou can also accept the second parameter, which can be a number, string or object.

ES6 grammar

The parameter of the function can be set to a default value, and the set value is used when the parameter is not passed in.

increment(state,n=1)等同于:
    increment(state,n){
        n=n||1;
    }

SubmitmutationsAnother way to do this is to directly use thetypeThe object of the property.

mutationsTry not to operate the data asynchronously in the, otherwise the component is in thecommitAfter the data cannot be changed immediately, and do not know when will change.

Advanced usage

Vuex has 3 other options available:getteractionsmodules.

getterAbility tocomputedThe method of extraction, can also rely on othergetter, putgetterAs the second parameter.

actionAndmutationMuch like, the difference isactionWhat is submitted inside ismutationAnd can operate business logic in one step.

actionThrough within the assembly$store.dispatchTrigger.

modulesUsed to transferstoreDivided into different modules, when the project is large enough,storeFrom insidestategettersmutationsactionsWill be very much, usemodulesYou can write them to different files.

moduleThemutationAndgetterFirst parameter receivedstateIs the status of the current module. InactionsAndgettersYou can also receive a parameter inrootStateTo access the state of the root node.

Actual Combat: Central Event Bus Plug-invue-bus

Central event busbusAs a simple component transfer event, it is used to solve the problem of communication between cross-level and sibling components.

vue-busThe plug-in adds an attribute to Vue$busAnd agent$emit$on$offThree ways.

ES6 grammar

emit(event,..args)hit the target...It is the deconstruction of function parameters. Because I don’t know how many parameters the component will pass in, use...argsYou can get from the current parameter to the last parameter.

Usevue-busThere are two points to note:

  1. The first is$bus.onShould be increatedUsed in hooks, if used inmountedUsing, it may not receive other components fromcreatedIncidents from hooks;
  2. The second point is the use of$bus.onInbeforeDestroyThe hook should be reused$bus.offRemove, because after the component is destroyed, there is no need to store the monitored handle in thevue-busChina.

Vue plug-in

Registering plug-ins requires an open methodinstall, its first parameter is Vue constructor, and its second parameter is an optional option object.

< pdata-height = “350” data-theme-id = “0” data-slug-hash = “rjvoxd” data-default-tab = “js” data-user = “whjin” data-embedded-version = “2” data-pen-title = “vue plug-in” class=”codepen”>See the PenVue plug-inby whjin (@whjin) onCodePen.</p>
<script async src=”https://static.codepen.io/ass …; ></script>

Front-end routing andvue-router

The core of SPA is front-end routing. For a website address, every GET or POST request has a special regular configuration list on the server side, and then after matching to a specific path, it is distributed to different Controller for various operations. Finally, it willhtmlOr data is returned to the front end, thus completing an IO.

Front-end routing, that is, the front-end maintains a routing rule. There are two ways to implement it.

  1. One is to useurlThehash, is often said to anchor (#), JavaScript passeshashChangeEvent to monitorurlThe change of;
  2. The other is HTML5historyMode, which enablesurlIt looks like an ordinary website to/Split, no#However, using this mode requires the support of the server, which points to the same one after receiving all the requests.htmlFile, otherwise it will appear404.

Therefore, there is only one SPAhtml, the entire website all content in thishtml, through JavaScript to deal with.

If you want to independently develop a front-end route, you need to consider the pluggable page, life cycle, memory management and other issues.

vue-router

vue-routerThe realization principle andviaisFeatures Implement Dynamic ComponentsIn fact, routing different pages is to dynamically load different components.

Create an array to specify a route match list, one component for each route map:

const Routers = [
    {
        path: '/index',
        component: (resolve) => require(['./views/index.vue'], resolve)
    },
    {
        path: '/about',
        component: (resolve) => require(['./views/about.vue'], resolve)
    }
];

For each item in RouterspathProperty is to specify the current matching path.componentIs a mapped component.

webpackEach route will be packed into onejsFile, when requesting the page, to load the pagejs, that is, lazy loading (on-demand loading) implemented asynchronously. The advantage of this is that it does not need to load all the contents of the page when opening the first page, but only when accessing.

After using asynchronous routing, change thejsIt’s all calledchunk(Block), their naming defaults to0.main.js1.main.js
Can be found inwebpackConfigured exitsoutputThrough settingchunkFilenameField modificationchunkNaming.

output: {
    publicPath: "/dist/",
        filename: "[name].js",
        chunkFilename: "[name].chunk.js"
}

i’ve got itchunkAfter that, on each page (.vueThe style written in the file) will not be packaged until it is configured.main.cssOtherwise, it will still be created dynamically through JavaScript<style>Write in the form of a tag.

const RouterConfig = {
    //使用HTML5的History路由模式
    mode: 'history',
    routes: Routers
};

const router = new VueRouter(RouterConfig);

new Vue({
    el: "#app",
    router: router,
    render: h => {
        return h(App)
    }
});

Set in RouterConfigmodeForhistoryThe History routing mode of HTML5 will be turned on, and through/Set the path. If not configuredmode, will use the#To set the path.

The History route must be configured in the production environment to point all routes to the same route.html, or settings404Page, otherwise the page will appear when refreshed.404.

In the routing list, you can add a new item at the end. When the access path does not exist, redirect to the home page:

{
    path: '*',
    redirect: '/index'
}

Of the routing listpathYou can take parameters, such as/user/123, where user ID123It is dynamic, but they are routed to the same page, where you expect to get this ID, but fight each other to request relevant data.

Jump

vue-routerThere are two ways to jump to a page, the first one is built-in<router-link>Component, which will be rendered as a<a>Label.

<template>
    <div>
        <h1>首页</h1>
        <router-link to="/about">跳转到about</router-link>
    </div>
</template>

Its usage is the same as that of common components.toIs aprop, specify the path to jump, or use thev-bindDynamic settings.

Use<router-link>In the History mode of HTML5, clicking will be blocked to prevent the browser from reloading the page.

< router-view > there are othersprop, commonly used are:

  • tagYou can specify what labels to render, such as<router-link to="/about" tag="li">The result of rendering is<li>Instead of<a>
  • replaceUsereplaceNo History record will be left, so you cannot use the back key to return to the previous page after navigation, such as<router-link to="/about" replace>
  • active-classWhen<router-link>When the corresponding route matches successfully, the current element will be set with a name ofrouter-link-activeTheclass, settingsprop:active-classYou can modify the default name. When making similar navigation bars, you can use this function to highlight the navigation bar item corresponding to the current page, but it will not be modified in general.active-class, directly using the default valuerouter-link-active.

Sometimes, jumping pages may need to be done in JavaScript, similar towindow.location.href. In this case, you can use the second jump method, usingrouterThe method of the instance.

<template>
    <div>
        <h1>介绍页</h1>
        <button @click="handleRouter">跳转到user</button>
    </div>
</template>

<script>
    export default {
        methods: {
            handleRouter() {
                this.$router.push('/user/123');
            }
        }
    }
</script>

$routerThere are other ways:

  • replacesimilarly<router-link>ThereplaceFunction, it will not tohistoryAdd a new record and replace the current onehistoryRecords such asthis.$router.replace('/user/123')
  • gosimilarlywindow.history.go()InhistoryHow many steps forward or backward in the record, the parameter is an integer

Advanced usage

In SPA project, how to modify the title of the webpage?

When routing changes occur on the page, the settings are unified.

vue-routerNavigation hooks are providedbeforeEachAndafterEach, they will be triggered immediately before and after the route changes, so set the title can be inbeforeEachHook complete.

< pdata-height = “365” data-theme-id = “0” data-slug-hash = “gklam” data-default-tab = “js” data-user = “whjin” data-embedded-version = “2” data-pen-title = “vue-router navigation hook” class=”codepen”>See the PenVue-router navigation hookby whjin (@whjin) onCodePen.</p>
<script async src=”https://static.codepen.io/ass …; ></script>

Navigation hook has 3 parameters:

  • toThe routing object of the destination to be entered
  • fromThe current navigation will leave the route object
  • nextYou cannot enter the next hook until you call this method.

Of the routing listmetaField can customize some information, will each page’stitleWritemetaFor unified maintenance,beforeEachHooks can route objects fromtoGet inmetaInformation, thus changing the title.

Some pages need to check whether they are logged in. If they are logged in, they can be accessed; otherwise, they jump to the login page. vialocalStorageTo simply determine whether to log in.

router.beforeEach((to, from, next) => {
    if (window.localStorage.getItem('token')) {
        next()
    } else {
        next('/login')
    }
});

next()The parameter of is set tofalse, can cancel navigation, set to specific path can navigate to the specified page.

Build using webpack

The main application scenario of webpack is single page rich application (SPA). SPA passes through ahtmlFiles and a pile of on-demand loadsjsComposition of documents.

exportAndimportIt is used to export and import modules. One module is onejsFile, it has an independent scope, the variables defined inside cannot be obtained outside.

InmoduleObject’srulesProperty can specify a series ofloadersEachloaderAll must includetestAnduseTwo options.

WhenwebpackEncountered during compilationrequire()OrimportStatement to import a suffix named.cssThe file, first pass it throughcss-loaderConversion, then throughstyle-loaderConvert and continue packaging.useThe value of the option can be an array or a string. If it is an array, its compilation order is from back to forth.

The main core parts of the webpack includeEntryExportLoadersPlugin.

Single file components andvue-loader

<style>Label usagescopedProperty, indicating that the current CSS is only valid for this component, if not, namedivThe style of is applied to the entire project.

Use.vueFiles need to be installed first.vue-loadervue-style-loaderWait for the loader and configure it. If you want to use ES6 syntax, you also need to installbabelAndbabel-loaderWait for the loader.

<p data-height=”465″ data-theme-id=”0″ data-slug-hash=”NzjNgp” data-default-tab=”js” data-user=”whjin” data-embed-version=”2″ data-pen-title=”Vue-webpack.config.js” class=”codepen”>See the PenVue-webpack.config.jsby whjin (@whjin) onCodePen.</p>
<script async src=”https://static.codepen.io/ass …; ></script>

New.babelrcFile, and write tobabelThe webpack will rely on this configuration file to usebabelCompile ES6 code.

{
  "presets": ["es2015"],
  "plugins": ["transform-runtime"],
  "comments": false
}

Each ...vueA file represents a component that can depend on each other.

ES syntax:

=>Is an arrow function

render: h=>h(App)等同于
    render: function(h) {
        return h(App)
    }
    
也等同于:
    render: h=>{
        return h(App)
    }
    

In the arrow functionthisPointing to is different from ordinary function, arrow function bodythisThe object is the object at the time of definition, not the object at the time of use.