npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

vue-soppy

v1.4.7

Published

Keeping your vue-cli app soppy by hydrating on each routing update

Downloads

80

Readme

vue-soppy

npm version

What and Why?

Check out this article on Medium to get a better understanding why vue-soppy exists.

How to setup

NOTE: This setup assumes you're using a vue-cli project with vue-router and vuex.

$ vue create my-project && cd my-project/
$ npm install vue-soppy

src/router/routes.json - Ideally, this file is auto-generated by some external script or command (check out laravel-soppy for the Laravel setup for vue-soppy)

[
  {
    "name": "app.welcome",
    "path": "/",
  }
]

NOTE: It's recommended to set up a file dedicated to the soppy instance. We put it in src/vendor/soppy.js but feel free to put it where you like. Just remember to change the references accordingly in the code snippets below.

src/vendor/soppy.js

import Soppy from 'vue-soppy';
import routes from '@/router/routes.json';

const soppy = new Soppy(routes, {
  enableSoppyLoadbarComponent: true,
});

export default soppy;
export const soppyRoutes = soppy.soppyRoutes;
export const soppyRouter = soppy.soppyRouter;
export const soppyActions = soppy.soppyActions;
export const soppyMutations = soppy.soppyMutations;
export const soppyState = soppy.soppyState;
export const soppyModules = soppy.soppyModules;

src/main.js

import Soppy from '@/vendor/soppy';
Vue.use(Soppy);

NOTE: We're importing from our dedicated vendor soppy instance and not the vue-soppy package. This is the same in the setup files below.


public/index.html (optional)

<script>
  window.SoppyState = <% if (NODE_ENV === 'production') { %>@json(array_merge($data, []))<% } else { %>{}<% } %>;
</script>

You can replace @json(array_merge($data, [])) with whatever your framework can inject data with if you're not using laravel-soppy


src/store/index.js

import Vue from 'vue';
import Vuex from 'vuex';
import { soppyState, soppyMutations, soppyActions, soppyModules } from '@/vendor/soppy';


Vue.use(Vuex);

export default new Vuex.Store({
  state: soppyState({
    // Your custom root state
  }),

  getters: {
    // Your custom root getters
  },

  actions: soppyActions({
    // Your custom root actions
  }),

  mutations: soppyMutations({
    // Your custom root mutations
  }),

  modules: soppyModules({
    // Your custom modules
  }),
});

NOTES: The second and third argument for soppyActions can optionally be setSoppyStateCallback and setSoppyPreloadStateCallback respectively.


src/router/index.js

import Vue from 'vue';
import VueRouter from 'vue-router';
import { soppyRoutes, soppyRouter } from '@/vendor/soppy';

Vue.use(VueRouter);

const routes = soppyRoutes([
  {
    name: 'app.custom.modal',
    path: '{app.custom}/modal',
    meta: {
      soppy: {
        get path() {
          return window.location.pathname.replace('/modal', '');
        },
      }
    },
    components: {
      default: () => import('@/views/Promo.vue'),
      modal: () => import(/* webpackChunkName: "custom-modal-view" */ '@/views/custom/Modal'),
    },
  },
  {
    name: 'app.notFound',
    path: '*',
    components: {
      default: () => import(/* webpackChunkName: "not-found-view" */ '@/views/NotFound'),
    },
  },
]);

const router = new VueRouter({
  // mode: 'history',
  // base: process.env.BASE_URL,
  routes,
});

export default soppyRouter(router);

NOTES:

  • Pass in any vue-specifc routes or route overrides to the soppyRoutes method. These will be merged with the routes from your routes.json that you passed in to the Soppy class in @/vendor/soppy.js.
  • Pass in an object of any overrides you want on every route as the second argument to soppyRoutes
  • Each route's components property is generated dynamically from the route's name from the routes.json. By default, for example, the component property for app.welcome will be { default: () => import('@/views/Welcome.vue') }; or for nested routes like app.user.settings, { default: () => import('@/views/user/Settings.vue') }. To change the naming convention used here, override the component or components property as explained above OR pass in your own naming function as the third argument to soppyRoutes. NOTE: All component paths will be prepended with '@/' after your naming function to bypass some dynamic import limitations.
  • The first route we're passing in the above example, app.custom.modal is how you might implement a child route of sorts.
    • The path includes curly brackets around another route's name: {app.custom}. This will be replaced by the actually path from app.custom found in routes.json
    • get path() in a route's meta.soppy object will override the path that will be called to fetch data. In the example case above, we want the same data that fetched in the parent route.
    • The SoppyApp component has two router views: 1 is default and the other is named: modal. This way you can show multiple views (e.g. a parent and a child) at the same route.

Your app needs to be wrapped in the <soppy-app> component like this:

src/App.vue

<template>
  <soppy-app
    id="app"
    :view-not-found="notFound"
    :view-server-error="serverError"
    :view-attrs="{ class: 'mt-7 leading-6' }"
  >
    <!-- optionally include the soppy-loadbar component -->
    <soppy-loadbar></soppy-loadbar>

    Header / Anything before router-view
    
    <template v-slot:after>
      Footer / Anything after router-view
    </template>
  </soppy-app>
</template>

<script>
export default {
  name: 'App',

  data() {
    return {
      notFound: () => import(/* webpackChunkName: "not-found-view" */ '@/views/NotFound'),
      serverError: () =>
        import(/* webpackChunkName: "server-error-view" */ '@/views/ServerError'),
    }
  }
}
</script>

NOTES:

  • If you want to show a specific view when a soppy request returns a 401, 404, or 500, you can add the :view-unauthorized, :view-not-found, :view-server-error attributes respectively.
  • :view-attrs will be bound to the default component slot which is <router-view> by default
  • View the SoppyApp component for more details
  • Use <soppy-link> to take advantage of extra functionality like preloading data on link hover. Use it like <router-link> and check out the component file for more details.
  • <soppy-loadbar> is a tailwindcss-styled component showing the load progress of the soppy page requests. Check out the component file for more details.