简体   繁体   中英

How to add vanilla JavaScript to vue.js project?

Good Day, I'm very new to vue.js and want a navbar, which ist transparent by default, but changes its background on scrolling. Unfortunately, it does not work. I tried a fe solutions, but none of this worked. So this JavaScript code is an example from Stack Overflow, which works in a Fiddle. If you need more information and/or code, please let me know.

Navigation.vue

<template>
    <div id="navigation"> 
        <nav class="nav-items"> 
            <router-link class="item" to="/home">Home</router-link>
            <router-link class="item" to="/about">About</router-link>
            <router-link class="item" to="/japan">Japan</router-link>
        </nav> 
    </div>
</template>

<script>
export default {
    name: 'navigation'
}

import scroll from '../assets/js/scroll.js';

</script>

scroll.js

const navbar = document.querySelector('#navigation')

window.addEventListener('scroll', function(e) {
  const lastPosition = window.scrollY
  if (lastPosition > 50 ) {
    navbar.classList.add('colored')
  } else if (navbar.classList.contains('colored')) {
    navbar.classList.remove('colored')
  } else {
    navbar.classList.remove('colored')
  }
})

navigation.scss

FYI: I've removed uneccessary code here.

#navigation {
    background: transparent;

    .colored {
        background: #fff;
        transition: 0.3s;
    }

}

Note: To view how to import custom code in a Vue component (general case), scroll down past the last <hr> .


Vue is a JavaScript framework and therefore you can insert vanilla code anywhere in it and it will run perfectly fine.

IMHO, you issue is not about importing vanilla code. It's about running it at the correct moment.

You have to run your code inside mounted() hook, because that's when #navigation exists in DOM:

 Vue.config.devtools = false; Vue.config.productionTip = false; Vue.component('navigation', { template: '#navigationTemplate', mounted() { window.addEventListener('scroll', () => document.querySelector('#navigation') .classList.toggle('colored', window.scrollY > 50) ) } }) new Vue({ el: '#app' });
 #app { min-height: 200vh; background: url("https://picsum.photos/id/237/1024/540") no-repeat center center /cover; } #navigation { background: transparent; position: fixed; top: 0; padding: 1rem; transition: 0.3s; width: 100%; box-sizing: border-box; color: white; } #navigation.colored { background: rgba(255, 255, 255, .85); color: black; } body { margin: 0; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <script id="navigationTemplate" type="text/template"> <div id="navigation"> <nav class="nav-items"> <a class="item" to="/home">Home</a> <a class="item" to="/about">About</a> <a class="item" to="/japan">Japan</a> </nav> </div> </script> <div id="app"> <navigation /> </div>


  1. your scroll.js can safely be written as:
window.addEventListener('scroll',
  () => document.querySelector('#navigation')
  .classList.toggle('colored', window.scrollY > 50)
)
  1. Your SCSS seems incorrect:
#navigation {
  .colored {
    declaration
  }
}

will apply declaration to any element with a class of .colored that's inside an element with the id of navigation . But your code toggles the class colored on #navigation . Therefore your SCSS should look like this:

#navigation {
  &.colored {
    declaration
  }
}

Might not seem like much, but the & makes your code apply (or not).

  1. You probably want to apply transition to #navigation , as it should apply when it has the colored class and when it doesn't . If you don't, the return transition (from .colored to :not(.colored) ) will not be animated.

For the record and to also answer your initial question, the proper way to import custom code into a Vue component is:

a) export your code as a function:
(in scroll.js)

export function menuScroll = function() {
  /* your custom code here */
}

b) import it:
(in your component)

import { menuScroll } from 'path/to/scroll'

c) run it exactly where you need it:
(ie: in mounted)

export default {
  name: 'navigation',
  mounted() {
    menuScroll();
  }
}

Obviously, you want to rename the function in accordance with its purpose/role and the project's naming conventions.

Last, but not least, if your function needs to take params, you might want to use it as a method:

export function someName = function(...args) {
  /** do stuff with args **/
}

... and, in component:

import { someName } from 'path/to/it'

export default {
  name: 'whatever',
  methods: {
    someName,
    /* more methods... */
  }
}

just like that

<template>
   .... your HTML
</template>

<script>
  export default {
    data: () => ({
      ......data of your component
    }),
    mounted() {
      let recaptchaScript = document.createElement('script')
      recaptchaScript.setAttribute('src', 'https://www.google.com/recaptcha/api.js')
      document.head.appendChild(recaptchaScript)
    },
    methods: {
      ......methods of your component
    }
  }
</script>

source : Link

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM