All Projects → geekytime → vuex-router

geekytime / vuex-router

Licence: other
Move a Vue app's location state into the Vuex store. Allows super-easy page-based routing with built-in slide transitions.

Programming Languages

javascript
184084 projects - #8 most used programming language
Vue
7211 projects
CSS
56736 projects

Projects that are alternatives of or similar to vuex-router

Vue Meteor
🌠 Vue first-class integration in Meteor
Stars: ✭ 893 (+4365%)
Mutual labels:  vue-components, vue-router
Vue3 News
🔥 Find the latest breaking Vue3、Vue CLI 3+ & Vite News. (2021)
Stars: ✭ 2,416 (+11980%)
Mutual labels:  vue-components, vue-router
Vuestic Admin
Free and Beautiful Vue 3 Admin Template
Stars: ✭ 8,398 (+41890%)
Mutual labels:  vue-components, vue-router
Vue Cnodejs
基于vue.js重写Cnodejs.org社区的webapp
Stars: ✭ 3,065 (+15225%)
Mutual labels:  vue-components, vue-router
Eth Vue
Featured in Awesome Vue [https://github.com/vuejs/awesome-vue], a curated list maintained by vuejs of awesome things related to the Vue.js framework, and Awesome List [https://awesomelists.net/150-Vue.js/3863-Open+Source/18749-DOkwufulueze-eth-vue], this Truffle Box provides everything you need to quickly build Ethereum dApps that have authentication features with vue, including configuration for easy deployment to the Ropsten Network. It's also Gravatar-enabled. Connecting to a running Ganache blockchain network from Truffle is also possible -- for fast development and testing purposes. Built on Truffle 5 and Vue 3, eth-vue uses vuex for state management, vuex-persist for local storage of app state, and vue-router for routing. Authentication functionalities are handled by Smart Contracts running on the Ethereum blockchain.
Stars: ✭ 171 (+755%)
Mutual labels:  vue-components, vue-router
Vue Project
基于vue-cli构建的财务后台管理系统(vue2+vuex+axios+vue-router+element-ui+echarts+websocket+vue-i18n)
Stars: ✭ 301 (+1405%)
Mutual labels:  vue-components, vue-router
Cordovue
A sample Apache Cordova application using VueJS.
Stars: ✭ 66 (+230%)
Mutual labels:  vue-components, vue-router
aura-admin
Aura Admin is the Web App that helps you to mange the Tech Communities like GDGs, DSCs or any other tech communities with Aura
Stars: ✭ 58 (+190%)
Mutual labels:  vue-components, vue-router
Vue Objccn
🔥 Use Vue.js to develop a cross-platform full stack application / 用 Vue.js 开发的跨三端应用
Stars: ✭ 1,993 (+9865%)
Mutual labels:  vue-components, vue-router
Vuejs2 Authentication Tutorial
Stars: ✭ 144 (+620%)
Mutual labels:  vue-components, vue-router
Vue Testing Examples
Advanced testing with vuejs. When you need to go beyond Getting started section and see some real world example with everything that proper tests should have.
Stars: ✭ 288 (+1340%)
Mutual labels:  vue-components, vue-router
Vuemmerce
👉 Responsive ecommerce template 🛒 built with Vue.js and Nuxt.js
Stars: ✭ 223 (+1015%)
Mutual labels:  vue-components, vue-router
Mui Vue2
mui+mint+vue2.x+vue-router+vuex+webpack最终打包成原生apk的app项目,样式使用vue移动端mint ui框架,原生手机能力偏重于mui框架,欢迎star!
Stars: ✭ 278 (+1290%)
Mutual labels:  vue-components, vue-router
Vue2
【🔥Vue.js资讯📚】目前web前端开发非常火爆的框架;定时更新,欢迎 Star 一下。
Stars: ✭ 395 (+1875%)
Mutual labels:  vue-components, vue-router
vue2
【🔥Vue.js资讯📚】目前web前端开发非常火爆的框架;定时更新,欢迎 Star 一下。
Stars: ✭ 415 (+1975%)
Mutual labels:  vue-components, vue-router
Vue Cnode
基于vue2 + vue-router + vuet + ES6 + less + flex.css重写vue版cnode社区,使用webpack2打包
Stars: ✭ 1,134 (+5570%)
Mutual labels:  vue-components, vue-router
Vue-3-Advance-CRUD
A Complete Single Page Application using Vue, Vue Router, Bootstrap-Vue, Vuex and all....
Stars: ✭ 41 (+105%)
Mutual labels:  vue-router, vuejs-router
special-vue-series-code-analyzing
「Vue生态库源码系列」,Vue、Vue-router、Vuex、Vue-cli、Vue-loader、Vue-devtools等
Stars: ✭ 15 (-25%)
Mutual labels:  vue-components, vue-router
Vue Shoppingcart
ShoppingCart (Ecommerce) 🛒 Application using Vuejs, + Node.js + Express + MongoDB 🚀🤘
Stars: ✭ 141 (+605%)
Mutual labels:  vue-components, vue-router
Web designer
网页设计器图形化工具,通过拖拽组件进行页面排版和生成页面代码
Stars: ✭ 219 (+995%)
Mutual labels:  vue-components, vue-router

vuex-router

CircleCI

Moves app location state into a router module in the Vuex store.

The store becomes the "source of truth" for location state within the app. Location state is changed by dispatching actions to the router module.

The browser location history is kept in sync with the store by the router module.

Why does that matter? Isn't the browser url the "source of truth" for location state?

The goal of Vuex is to move most/all of the non-trivial state of an app into the store, where it can be managed and safely shared across components. vuex-router provides a relatively painless way to safely manage the application state inside the store, along with the rest of the application state, using standard Vuex state, getters, actions, and mutations.

This is convenient from an API perspective, and allows for some very clean code. The location state is read and updated just like the rest of the application state, instead of requiring a separate routing API.

How is this different than vue-router with vuex-router-sync?

Even when used with vuex-router-sync, vue-router still uses the browser history as the "source of truth" for the location state.

vuex-router-sync does not fully manage location state inside the Vuex store. It copies the browser's location state into the store for convenience. vue-router provides a separate API, outside the Vuex store, to manage location state.

vuex-router Benefits

  • Provides a simple page-based router by default. pageRoutes are easy to configure, and suitable for many apps.
  • Fully functional page slide transitions are easily configured when using pageRoutes. (Other transitions are in the works.)
  • pageRoutes are optional. vuex-router manages the browser location history separate from the default routes, so any router can be used.
  • ViewModels only need access to the $store, as opposed to needing both a $store and a separate $router.
  • The included Pages and Page components still allow for easy setup of fixed headers, nav-drawers, etc.
  • The included Link component takes care of sending most user-interactions to the browser history.

Usage

Installation and project configuration

Install vuex-router with yarn or npm.

The easiest way to configure vuex-router is with WebPack and babel-loader. In most situations, babel-loader will find the .babelrc file in the vuex-router folder and use it to build vuex-router.

If there are questions about a specific configuration scenario, feel free to open an issue, or submit a PR with an example, even if it's only partly working.

A pre-transpiled version of vuex-router is included at dist/vuex-router-min.js in the npm package, but it has not been thoroughly tested. Please open an issue if there are any problems using it.

Configuring the Vuex store

We add the router module from vuex-router to our store, like this:

import { router } from "vuex-router"

const store = new Vuex.Store({
  modules: {
    router
  }
})

(Note, we can change the name of the router to whatever we want, but then we will need to dispatch actions using that name. The rest of these examples assume the default router namespace for the module. See Vuex - Modules - Namespacing to learn more.)

Initializing the router using pageRoutes

Before we can use the router, we need to initialize it by dispatching the router/init action on the store. The default page-router allows us to map our routes to simple page names. We supply our pageRoutes to the router/init action like this:

const pageRoutes = [{
  page: "home",
  path: ["", "/", "/home"],  
  transIndex: 0
},{
  page: "foo",
  path: "/foo",  
  transIndex: 1
},{
  page: "bar",
  path: ["/bar","/bar/:id"],  
  transIndex: 2
}]

store.dispatch("router/init", {pageRoutes})

(Notice above that we pass an object to the action, with pageRoutes as the key.)

See the pageRoutes section below for more details on how to configure pageRoutes.

Adding Page components to our app

Note: this guide assumes a basic understanding of how Vue components work. See Components Basics and Components In-Depth to learn more.

Once the router module is configured and initialized in the store, we can add vuex-router's Pages and Page components to our app, usually in our top-level app/root component.

We use Page and Pages like any other Vue components. import them, and add them to the components hash of our main App component.

javascript

import Bar from "./components/bar.vue"
import Foo from "./components/foo.vue"
import Home from "./components/home.vue"
import {Page, Pages} from "vuex-router"

export default {
  components: {
    Bar,
    Foo,
    Home,
    Page,
    Pages
  }
}

We assign a name attribute to each of our Page components. These names will match up with the page properties on our pageRoutes.

We can then slot our top-level components inside the Page components.

html

<div class="app">  
  <Pages> <!-- Root component to manage Page components -->
    <Page name="home"> <!-- `vuex-router` Page component with `name` set -->
      <Home /> <!-- The page we want to render when router page name is `home `-->
    </Page>
    <Page name="foo">
      <Foo />
    </Page>
    <Page name="bar">
      <Bar />
    </Page>
  </Pages>
</div>

Note: We may also "replace" the Page components with our components using the :is attribute, but this will result in page transitions being disabled. The wrapper Page components are necessary for transitions to work.

Initializing the router without pageRoutes

We don't have to use pageRoutes to use vuex-router. We can wire up our own router in a root component, or add a custom router module to our store.

We still need to initialize the router module before history any ctions will work. We simply dispatch the router/init action without any parameters:

store.dispatch("router/init")

API

router Vuex module

Actions

store.dispatch("router/init", options)

Initializes the router module that was added to the store, and tells it to start managing location state. After this action runs, browser location change events will be handled by the router, and we should use actions on the router to modify the location state.

store.dispatch("router/go", {steps})

Navigates the specified number of steps through the browser location history. For example, to go back one page:

store.dispatch("router/go", {steps: -1})

Or to go forward two pages:

store.dispatch("router/go", {steps: 2})

router/go is analogous to window.history.go.

store.dispatch("router/goBack")

Goes back one step in the browser location history. This works just like if the user presses the "back" button in the browser toolbar.

router/goBack is analogous to window.history.back.

store.dispatch("router/goForward")

Goes forward one step in the browser location history. This works just like if the user presses the "forward" button in the browser toolbar.

router/goForward is analogous to window.history.forward.

router/locationChange

Used internally by the router. Invoking this action from outside the router could result in the location state falling out of sync with the browser history.

store.dispatch("router/push", {path})

Sets the current location state to the specified path, and adds the new location to the browser history. So, to go back to the root location of our app:

store.dispatch("router/push", {path: "/"})

To go to our /blog page:

store.dispatch("router/push", {path: "/blog"})

Note: Relative paths can be pushed, and they will work as expected, but this can be tricky when using pageRoutes. Most apps using pageRoutes will probably want to stick to a "flat"-ish route design.

router/push is roughly analogous to window.history.pushState, but uses only the URL/path argument.

store.dispatch("router/replace", {path})

Works like the router/push action, but replaces the current location with the new path. To explain, suppose we run the following code:

store.dispatch("router/push", {path: "/"})
store.dispatch("router/push", {path: "/home"})
store.dispatch("router/replace", {path: "/blog"})
store.dispatch("router/goBack")

The user's location will be "/", because when we added "/blog", it replaced "/home" in the browser's history.

Learn more about browser history at [MDN - Adding and modifying history entries](window.history.pushState

router/transitionEnd

Called by Page components to let the router know when page transition is complete. Should not need to be called by applications.

State and Getters

state shape

The state stored by the router looks like this:

const state = {
  // The current page-based route.
  // A route includes a page name, and any URL parameters that are
  // defined as part of the path.
  currentRoute: false,
  // The previous route. Stored to help with transitions.
  lastRoute: false,
  // Transition data set while transitions are in progress.
  transition: false,
  // A map of pages and their last scroll position.
  // The scroll position is saved and restored as pages are hidden
  // and shown.
  scrollTops: {},
  // The current location of the page. Roughly analogous to the
  // `window.location` property in the browser.
  location: {
    pathname: "",
    search: "",
    hash: "",
    state: {},
    key: ""
  }
}

store.getters["router/currentPage"]

Returns the current page name as determined by the page-router.

A pageRoute maps a browser location to a page name. If pageRoutes are not being used, this property returns false.

store.getters["router/lastPage"]

Returns the most recent page that was displayed before the current page. This is used mainly to track transitions away from the last page.

store.getters["router/scrollTopForPage"](pageName)

Returns any previously saved scroll information for the page with the given name. Used by the Page component to restore page scroll state when pages are re-shown after being hidden.

store.getters[router/transitionForPage](pageName)

Returns the active transition that should be applied to a page. Used by the Page component to apply transition classes to pages.

Mutations

The mutations defined on the router module should be considered private for most implementations. Calling them from outside of the router actions could result in location state getting out of sync with the browser history.

pageRoutes

Here is an example pageRoutes array:

const pageRoutes = [{  
  page: "home",
  path: ["", "/", "/index", "/home"],  
  transIndex: 0
},{
  page: "about",
  path: "/about",  
  transIndex: 1
},{
  page: "blog",
  path: ["/blog", "/blog/:post"],  
  transIndex: 2
}]

A pageRoute is made of three properties:

  • page: the name of the page
  • path: a string, or array of strings that route to this page
  • transIndex: an integer used to
pageRoute.page

The page name can be any valid JS property string. This is the same name that we supply to the Page component, if we're using it.

pageRoute.path

Can be a string path, or an array of string paths. These paths will be matched against the browser's location to determine the current page and page parameters.

paths are passed to a specially configured universal-router instance, to handle matching and to parse url parameters. Url parameters are available in the currentRoute property of the state, and via the router/currentRoute getter.

For example, if we define a pageRoute like:

{
  page: "blog",
  path: "/blog/:postId"
}

And then go to the location /blog/14, then store.state.router.currentRoute will look like this:

{
  page: "blog",
  params: {
    postId: "14"  
  }
}

Note: that the url/path parameter value will always be a string.

Because we can define multiple paths for a page, we can use the same page to handle both the parameterized and parameter-less versions of the path, like this:

{
  page: "blog",
  path: ["/blog", "/blog/:postId"]  
}

Then inside our blog page, we can check whether we have a postId, and display the relevant sub-components like this:

Html

<div class="blog">
  <Post v-if="postId" :id="postId" />
  <RecentPosts v-else />  
</div>

Javascript

export default {
  computed: {
    postId () {
      return this.$store.getters["router/currentRoute"].params.postId
    }
  }
}
pageRoute.transIndex

The transIndex is optional. If supplied, it is used to determine the direction for the default page slide transitions.

Pages will slide to the left when the router transitions to a lower transIndex, and to the right when moving to a higher transIndex.

Pages and Page components

The Pages component provides basic default styling to handle full-page sliding page transitions.

The Page component handles the details of showing and hiding, and transitioning pages based on the defined pageRoutes and router state.

Apps should not need to use the APIs of these components directly. They can simply be added to application templates.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].