Giter VIP home page Giter VIP logo

vue-tree-navigation's Introduction

vue-tree-navigation

Version Node.js CI Build Vue codecov

Vue.js tree navigation with vue-router support

For more detailed information see documentation/demo

Features

  • unlimited number of levels
  • optional vue-router support (v2.0.0 or higher)
  • generate navigation items automatically from vue-router routes or define them manually
  • define a default open level
  • auto-open a level when a corresponding URL visited
  • focused on core functionality, only necessary styles included
  • elements are provided with meaningful classes to make customizations comfortable (for example NavigationItem--active, NavigationLevel--level-1, NavigationLevel--closed)

Example

1. Navigation items generated from vue-router routes

Let's suppose you use vue-router with the following routes definition

const routes = [
  {
    name: 'Home',
    path: '/',
  },
  {
    name: 'Running',
    path: '/running',
    children: [
      {
        name: 'Barefoot',
        path: 'barefoot',
      },
    ],
  },
  {
    name: 'Yoga',
    path: '/yoga',
    children: [
      {
        name: 'Mats',
        path: 'mats',
      },
      {
        name: 'Tops',
        path: 'tops',
      },
    ],
  },
  {
    name: 'About',
    path: '/about',
    children: [
      {
        name: 'Career',
        path: 'career',
        children: [
          {
            name: 'Design',
            path: 'design',
          },
        ],
      },
    ],
  },
];

Then simply include vue-tree-navigation

<template>
  <vue-tree-navigation />
</template>

and it will generate the following menu:

- Home          // --> /
- Running       // --> /running
  - Barefoot    // --> /running/barefoot
- Yoga          // --> /yoga
  - Mats        // --> /yoga/mats
  - Tops        // --> /yoga/tops
- About         // --> /about
  - Career      // --> /about/career
    - Design    // --> /about/career/design

Do not forget to use named routes since vue-tree-navigation uses name field to label navigation items.

2. Menu items defined manually

The following configuration

<template>
  <vue-tree-navigation :items="items" />
</template>

<script>
  export default {
    data() {
      return {
        items: [
          { name: 'Products', children: [
            { name: 'Shoes', path: 'shoes' }
          ]},
          { name: 'About', path: 'about', children: [
            { name: 'Contact', path: 'contact', children: [
              { name: 'E-mail', element: 'email' },
              { name: 'Phone', element: 'phone' }
            ]},
          ]},
          { name: 'Github', external: 'https://github.com' },
        ],
      };
    },
  };
</script>

will generate

- Products     // category label
  - Shoes      // --> /shoes
- About        // --> /about
  - Contact    // --> /about/contact
    - E-mail   // --> /about/contact#email
    - Phone    // --> /about/contact#phone
- Github       // --> https://github.com

For more examples see documentation/demo

Installation

NPM

$ npm install vue-tree-navigation

main.js

import VueTreeNavigation from 'vue-tree-navigation';

Vue.use(VueTreeNavigation);

Include with a script tag

<script src="https://unpkg.com/[email protected]/dist/vue-tree-navigation.js"></script>

<script>
  Vue.use(VueTreeNavigation)
</script>

Example

<div id="app">
  <vue-tree-navigation :items="items" :defaultOpenLevel="1" />
</div>

<script>
  Vue.use(VueTreeNavigation)

  const app = new Vue({
    el: '#app',
    data: {
      items: [
        ...
      ],
    }
  })
</script>

Requirements

Developers

$ yarn dev

$ yarn build

$ yarn prettier
$ yarn lint

$ yarn unit
$ yarn unit --verbose

$ yarn e2e

vue-tree-navigation's People

Contributors

chellem avatar dependabot[bot] avatar misrob avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-tree-navigation's Issues

router integration

Is there a way to integrate router functionality? Instead of using plain old a tags?
Otherwise a very promising library.

Explore the possibility to generate the menu from routes directly

I am not sure about this but a little experiment would be useful because when someone needs the navigation based on routes only (no elements), routes config structure must be projected to items structure and they are very similar. The optional auto mode could solve the issue with two (almost) same arrays and save maintenance time spent on projects using the tree nav.

Error: Component is missing template or render function

I try to use the tree-navigation-component.
I include it via the script tag at the end of the body in the html
`<script src="https://unpkg.com/vue@latest"></script>
<script src="https://unpkg.com/[email protected]/dist/vue-tree-navigation.js"></script>

<script src="assets/js/vue-app-uebung.js"></script>`

In vue-app.uebung.js, when I say
console.log(VueTreeNavigation.template)
it gives me undefined.

When I include the component somewhere, it give me the error Component is missing template or render functioin.

When I add the line
VueTreeNavigation.template = "<div>Hello, my name is Florian</div>
then the error disappears.

I am using Vue3. What do I do wrong?

compatibility to VueRouter is challenging

hi, thanks for this great work - I like it a lot even though it has some challenges because its lacking a closer integration with VueRouter. Background : I construct my VueRouter and vue-tree-navigation items dynamically from a simple JSON object. Doing so reveals the following issues

  • the vue-tree-navigation module uses a property route as routing context, VueRouter uses path - please align this to also use path
  • wouldnt it be great if vue-tree-navigation could be initialized in a way to pickup its items from VueRouter ? This would eliminate the steps to create config thats in sync for both

Thanks

Combining icon style into items

Hi, I wonder is there a simple way to add icon styling into these items links. I use vue-awesome but didn't know how to combine them, any suggestion to make the links look prettier, thanks.

Explore possibilities of customizing the ">" icon

It would be good not force anyone to use the ">" icon:

.navigation-toggle {
  position: relative;
  top:      -3px;
  padding:  6px;
  cursor:   pointer;

  .navigation-toggle-icon {
    display:      inline-block;
    padding:      3px;
    border:       solid #000;
    border-width: 0 2px 2px 0;
    transform:    rotate(45deg);
  }

  &.closed {
    .navigation-toggle-icon {
      transform: rotate(-45deg);
    }
  }
}

This should be documented so people can override it easily + other possibilities of injecting custom icons to menu should be explored.

Absolute paths

How can I specify that paths are absolute and not relative vue-router paths when programmatically generating the items?

Remove bold items

Items with children are styled as bold by default.

I would like to remove it because it is not needed and assign a class to all items having children instead. The class should be documented so people can style these items easily.

Links from paths do not link

When returning more than one document in a 'Tree' collection, the link does not link to the view. When returning one document from the collection, the link to the view works as expected. Interestingly, after I click on the link within the tree, and then reload the page I am taken to the correct view.

Expanding / collapsing the tree on mobile should not close the navigation

Clicking on the green arrow to expand or collapse tree children closes the menu on the mobile phone.

Is this intentional? I would prefer if the menu would not close on mobile after expanding the tree, because then you have to open it again to access the expanded children.

I would very much like to use your tree navigation as it is the best I have found for vue.js after several hours of searching.

native js usage (like jquery cdn)

It is possible to use a native browser installation ?
Via simple browser include ?

<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>

Level won't render as open when the app is served at a different path than root

When I serve an application at a different path than root e.g. http://example.com/somePath, matching levels won't render as open even tough they are matching to the correct hash path.

Example using the dev setup

When I change the webpack-dev-server test to start with the following parameter:

--public-path somePath

Which will serve the app not on the root (/) but on the somePath route
And I remove the defaultOpenLevel prop from the App.vue file so that it becomes:

<template>
  <div id="app">
    <vue-tree-navigation :items="items"/>

And open the following URL: http://localhost:8080/somePath#/products/shoes, whereby port 8080 matches to the webpack-dev-server port that's currently used, it's clear that I am currently on the products/shoes route but the navigation menu does not expand.

See image below:
image

Expected behavior

The image below shows the expected behavior for the tree navigation.
image

Some kind of solution

When I go to the core.js file and change some of the functionality in the renderLevelAsOpen function to the following:
From:

  const currentUrl = getRelativeUrl(
    window.location.href,
    window.location.origin
  );

  if (
    parentItem.meta.target !== '' &&
    startsWithUrl(currentUrl, parentItem.meta.target) === true
  ) {
    return true;
  }

To:

  const currentUrl = sanitizeRoute(window.location.hash.replace('#/', '/'));

  if (
    parentItem.meta.target !== '' &&
    startsWithUrl(currentUrl, parentItem.meta.target) === true
  ) {
    return true;
  }

I get the same implementation like you designed it, but it's also working for different paths (e.g. / and /somePath).

Personally I don't understand the need for the getRelativeUrl function because the 'window.location' object already contains the key for the hash part of the URL.

Component Registration Issue

I followed the installation instructions and used the sample content provided. Is there something I am missing? I have not had this issue with any other components.
There are no build errors but the console reads:
[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.

This is what I have in my package.json for versions.
"dependencies": {
"axios": "^0.18.0",
"gsap": "^2.0.1",
"lodash": "^4.17.10",
"vee-validate": "^2.1.0-beta.1",
"vue": "^2.5.16",
"vue-content-loading": "^1.5.0",
"vue-router": "^3.0.1",
"vuetify": "v1.0.19",
"vuex": "^3.0.1"
},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-plugin-add-filehash": "^6.9.8",
"babel-plugin-transform-imports": "^1.5.0",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-2": "^6.24.1",
"cross-env": "^5.1.6",
"css-loader": "^0.28.11",
"eslint": "^4.19.1",
"eslint-plugin-vue": "^4.5.0",
"file-loader": "^1.1.11",
"mdi": "^2.2.43",
"n": "^2.1.11",
"node-sass": "^4.9.0",
"sass-loader": "^7.0.3",
"style-loader": "^0.21.0",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.2",
"url-loader": "^1.0.1",
"vue-loader": "^14.2.2",
"vue-style-loader": "^4.1.0",
"vue-template-compiler": "^2.5.16",
"vue-tree-navigation": "^3.0.0",
"vuex-undo-redo": "^1.0.5",
"webpack": "^4.11.1",
"webpack-cli": "^3.0.3",
"webpack-dev-server": "^3.1.4"
}

Add option to activated item on certain url

It will be great if we can add option to activate item that match with certain URL that not define in list of item 'name' props

the default:

  export default {
    data() {
      return {
        items: [
          { name: 'Products', 
             children: [
                { 
                    name: 'Shoes', 
                    path: 'shoes' ,
                 }
             ]
          },
        ],
      };
    },
  };

what if we want 'Shoes' item active if current URL is eg('shoes/detail/1358993' or '/shoes/popular'), maybe with settings like this:

  export default {
    data() {
      return {
        items: [
          { name: 'Products', 
             children: [
                { 
                    name: 'Shoes', 
                    path: 'shoes' ,
                    otherPaths:[
                        'shoes/detail/[\\d]{1,20}', //using regex
                        'shoes/popular',
                    ],
                 }
             ]
          },
        ],
      };
    },
  };

[Electron Vue] Failed to mount component: template or render function not defined.

Hi

I am developing a desktop application based on Electron-vue and I am trying to use VueTreeNavigation on my app, however cannot solve this problem.

I see this warning message on Console of Electron application window.

[Vue warn]: Failed to mount component: template or render function not defined.

I have searched a lot on the internet to find a solution, but no success. And I even copied the source itself to my project and tried to run with it and again no success.

I saw some people saying that Vue project/modules for pure(?)/web are not suitable with Electron applications.

Can anyone give me a solution with this problem? or At least tell me a reason why it does not work?

Thank you

Allow for a link to be cloned in to the child tree

Hello,

thank you for the great plugin.

I have one feature request and that is to allow for a link to become disabled and cloned into the child tree.

What I mean by this is a situation, when the vue-tree-navigation is used as a navigation on mobile devices. How do you open a child tree of a link, which is actually a link itself? On desktop that's not a problem but on mobiles, as soon as you click on the link to open the child tree, a page belonging to the link will load.

I don't think that's desirable. What I suggest is a prop or a setting, which will mark that "parent" link to be disabled (and becomes a toggler) and cloned in to the child tree. So when you actually click on it, the child tree will open and the "parent" link will sit on top acting as a normal link.

Thanks

It should be possible to open a group by clicking on the text

Now you need to click on the ">" icon. This is not very suitable for mobile devices where the icon is small.
The group should open and the user should be redirected to the location at the same time. This should be a default behaviour. I'm not sure if this should be the only option available or whether people should have a possibility to change the behaviour.

Question: Expand a group when url is typed on the browsers url

First of, this one is excellent tree-nav , you have kept it to minimal and added only the absolute functionality needed. I was making one for myself as i didn't find any good ones, but yours is excellent.

One use case, that I am after is, lets say, there is a route under a group which is not expanded. Now upon typing this link on the browser's url, will the corresponding group containing the route get expanded ?
I just looked at documentation, did not played with it, if its a easy question for you can you tell me the current behavior?

TreeNavigation doesn't expand when directly visited URL is nested two or more layers

This seems like a continuation of issue #5:

Suppose I have a structure like this:

  • Parent Group
    • Leaf Item no. 1
    • Child Group
      • Leaf Item no. 2

When visiting Leaf Item no. 1 directly by entering its URL in the browser, Parent Group is automatically expanded as I would expect.
When visiting Leaf Item no. 2 directly, nothing is expanded. I would expect both Parent Group and Child Group to be expanded.
When I set autoOpenLevel to 1, Child Group gets expanded correctly. If I had other groups next to parent group, they would get expanded as well which is not what I want.

I am using manually defined items.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.