Can we use jquery in VUE.js - html

Hello guys i am a newbie to Vue.js My simple question is that can we use jquery in VUE.js. because some of my jquery script like addclasses or remove classes and sidemenu script i made that into jquery and want to use that if it is possible then let me know.
just want to run simple jquery function into vue.js
My Navbar Components
<template>
<div>
<b-navbar class="navbars" toggleable="lg" type="dark" variant="info">
<router-link to="/"><b-navbar-brand href="/" v-on:click="clickme()">Home</b-navbar-brand></router-link>
<b-navbar-toggle target="nav-collapse"></b-navbar-toggle>
<b-collapse id="nav-collapse" is-nav>
<b-navbar-nav>
<router-link to="/contact"><b-nav-item href="/contact">contact</b-nav-item></router-link>
<b-nav-item href="#" disabled>Disabled</b-nav-item>
</b-navbar-nav>
<!-- Right aligned nav items -->
<b-navbar-nav class="ml-auto">
<b-nav-form>
<b-form-input size="sm" class="mr-sm-2" placeholder="Search"></b-form-input>
<b-button size="sm" class="my-2 my-sm-0" type="submit">Search</b-button>
</b-nav-form>
<b-nav-item-dropdown text="Lang" right>
<b-dropdown-item href="#">EN</b-dropdown-item>
<b-dropdown-item href="#">ES</b-dropdown-item>
<b-dropdown-item href="#">RU</b-dropdown-item>
<b-dropdown-item href="#">FA</b-dropdown-item>
</b-nav-item-dropdown>
<b-nav-item-dropdown right>
<!-- Using 'button-content' slot -->
<template v-slot:button-content>
<em>User</em>
</template>
<b-dropdown-item href="#">Profile</b-dropdown-item>
<b-dropdown-item href="#">Sign Out</b-dropdown-item>
</b-nav-item-dropdown>
</b-navbar-nav>
</b-collapse>
</b-navbar>
</div>
</template>
MY MAIN .JS I have also external file of script.js which I imported here
import Vue from vue
import App from ./App
import router from ./router
import { BootstrapVue, IconsPlugin } from bootstrap-vue
import bootstrap/dist/css/bootstrap.css
import bootstrap-vue/dist/bootstrap-vue.css
//import $ from 'jquery
window.$ = require('jquery')
window.JQuery = require('jquery')
require('#/assets/style.css')
require('#/assets/script.js')
// Install BootstrapVue
Vue.use(BootstrapVue)
// Optionally install the BootstrapVue icon components plugin
Vue.use(IconsPlugin)
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
MY script.js file which is in assets
import $ from 'jquery'
$(window).on('scroll', () => {
if ($(this).scrollTop() > 100) { // Set position from top to add class
$('.navbars').addClass('header-appear');
}
else {
$('.navbars').removeClass('header-appear');
}
});
I Don't get any error but script is also not working

The issue with is the arrow function or what you expect this to be which is undefined in your code.
JQuery Fix
import $ from 'jquery'
$(window).on('scroll', function() {
if ($(this).scrollTop() > 100) { // Set position from top to add class
$('.navbars').addClass('header-appear');
}
else {
$('.navbars').removeClass('header-appear');
}
});
This is pretty easy to replicate with Vue and vanilla js so it would suggest this rather than JQuery.
<template>
...
<b-navbar :class="{'header-appear': activateClass }" class="navbars" toggleable="lg" type="dark" variant="info">
...
</template>
<script>
export default {
name: "App",
data() {
return {
activateClass: false,
};
},
created() {
window.addEventListener('scroll', this.onScroll)
},
beforeDestroy() {
window.removeEventListener('scroll', this.onScroll);
},
methods: {
onScroll() {
if (window.scrollY > 150) {
this.activateClass = true;
} else {
this.activateClass = false;
}
}
}
};
</script>

Related

How to Use Third Part Libraries like Vue3GoogleMap with Vue3 CDN Only

I am trying to implement a google map in a WordPress website through Vue3 Cdn. Following is my code:
<script src="https://unpkg.com/vue#3/dist/vue.global.js"></script>
<script src="https://unpkg.com/vue3-google-map"></script>
<div id="app">
<div>
{{ message }}
<GoogleMap api-key="<API_KEY_HERE>" style="width: 100%; height: 500px" :center="center" :zoom="15">
<Marker :options="{ position: center }" />
</GoogleMap>
</div>
</div>
<script>
const {
createApp
} = Vue
const {
GoogleMap
} = Vue3GoogleMap
const {
Marker
} = Vue3GoogleMap
createApp({
data() {
return {
message: 'Hello Vue!'
}
},
components: {
GoogleMap,
Marker
},
}).mount('#app')
</script>
I am unable to figure out how to use third party packages like vue3-google-map in this case where libraries are imported through CDN in the website. Please guide. Thanks

Vue.js: Dynamically render html in child component's slot

In my vue.js application, I am trying to render the html content dynamically in child component's slot. If I enter the text only then there is no issue, it works with fine.
Here is my code:
ChildComponent.vue
<template>
<div :class="type" class="message" v-if="type">
<slot />
</div>
</template>
<script>
export default {
...
props: ['type'],
...
}
</script>
ParentComponent.vue
<script>
import Alert from '#/Alert';
export default {
components: {
Alert,
},
data() {
return {
...
alert: {
error: '',
message: '',
}
};
},
created () {
this._onLoad()
},
methods: {
_onLoad() {
axios.get(`api.call.here`).then((res) => {
...
}).catch(error => {
this.alert.error = error.type;
this.alert.message = `<p>message here</p>`; // from response
});
},
}
}
</script>
Here is the screenshot of the issue:
What you trying to do can be achieved with v-html. You can use it while calling your ChildComponent.vue. This is a small example for your case:
<Alert>
<span v-html="alert.message"></span>
</Alert>

Import external component and loose reactivity in vue3

I have 2 projects/folders (with Lerna on the root).
The first one is uicomponents with some components and the second one is testing a simple app which uses some component from uicomponents.
I created a simple counter component (Counter.vue) :
<template>
<div>
<h3>Total clicks: {{ count }}</h3>
<div class="button-container">
<button class="inc" #click.prevent="increment">Add</button>
<button class="dec" #click.prevent="decrement">Subtract</button>
</div>
</div>
</template>
<script>
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'Counter',
props: {
startingNumber: {
type: Number,
required: false,
default: 0,
},
},
setup(props) {
const count = ref(props.startingNumber);
const increment = () => {
count.value += 1;
alert(count.value);
};
const decrement = () => {
count.value -= 1;
};
return {
count,
increment,
decrement,
};
},
});
</script>
And I import it in my app on a simple page :
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<counter :starting-number="5"></counter>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import Counter from '#uicomponents/counter';
export default defineComponent({
name: 'HelloWorld',
components: {
Counter,
},
props: {
msg: {
type: String,
required: false,
default: 'Me',
},
},
});
</script>
Lerna correctly replace all my components path and I retrieve my components Counter in my pages with all HTML. Buttons works well and my alert are displays with the correct value BUT my html are not refreshed.
This text <h3>Total clicks: {{ count }}</h3> stay "Total clicks: 0". My "count" ref is well updated because the alert displayed it correct but not in html.
I have a similar problem with lost reactivity. My setup is a bit different, but in the end it's the same result.
I'm trying to build a small plugin system which loads external components
Roughly I try to do this
// pluginSystem.js is accessible through window.myps
// ...
init(app) {
vueApp = app;
},
// ...
loadPlugin(data) {
vueApp.component(data.component.name, data.component);
}
And my external component looks like this
// main.js
import Counter from './components/Counter.vue';
window.myps.loadPlugin({
component: Counter,
});
Button click in counter, etc. works, console logging is fine as well, but component data is not updated.
I also tried defineComponent and defineAsyncComponent, but as you I had no luck with it...
Try it
import { defineAsyncComponent, defineComponent } from "vue"
components: {
Counter:defineAsyncComponent(() => import("#uicomponents/counter"))
}

How load html template in vuejs

I use vue.js and vue-router.js.
I added both of files to a html page
This is my component for load template...
const Dashboard = {template: "<strong>"}
But I want load html page dynamically and with HTTP URL.
const Dashboard = {template: "How load html page with url(http)"}
Can anyone guide me?
you could define a component similar to this
Vue.component('dynamic-component', {
props: {
contentURL: String,
},
template: `<div v-html='inner_html'></div>`,
computed: {
inner_html() {
return // http call to get html value utilizing this.contentURL
},
},
});
then from the router
{
path: '/path/option-a',
components: {
DynamicComponent
},
props: {
contentURL: `https://some-resource/option-a`
}
},
{
path: '/path/option-b',
components: {
DynamicComponent
},
props: {
contentURL: `https://some-resource/option-b`
}
}
For creating layers, you can create vue component and use slot
Layout.vue
<template>
Header
AnyComponents
<slot />
Footer
</template>
and in your page component you should import your layout and wrap
MainPage.vue
<template>
<MainLayout>
Here is your conntent of page or router
<router-view />
</MainLayout>
</template>
<script>
import MainLayout from 'layout.vue';
export default {
components: {
MainLayout
}
}
</script>
And now for render your page you should use your page in router
example of router.js
import Vue from 'vue';
import Router from 'vue-router'
import MainPage from 'MainPage.vue';
Vue.use(Router)
export default new Router({
routes: [{
path: '/',
component: MainPage,
}]
})
If you want to insert html to your page, use v-html
<div class="content" v-html="dashboard.template">
</div>

Show Hide Header based on their respective home page with vuejs

By default I have header-one which can be seen in all the pages. Then there comes header-two and header-three which are only shown when there respective home pages are been opened . Is there anyway we can do by condition if the path is '/home-one' not '/home-two' and '/home-three' then show header-v1
//App.vue//
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<v-app>
<header-v1></header-v1>
<header-v2></header-v2>
<header-v3></header-v3>
<router-view></router-view>
<emb-footer-V1></emb-footer-V1>
</v-app>
</template>
Several ways you could approach this using props, a route watcher, meta, etc.
Here's an example using meta on each route:
Vue.use(VueRouter)
const routes = [{
path: '/',
component: {
template: '<div>home page</div>'
}
}, {
path: '/home-one',
component: {
template: '<div>home page one</div>'
},
meta: {
header: 1
}
},
{
path: '/home-two',
component: {
template: '<div>home page two</div>'
},
meta: {
header: 2
}
},
{
path: '/home-three',
component: {
template: '<div>home page three</div>'
},
meta: {
header: 3
}
}
]
const router = new VueRouter({
routes
})
const app = new Vue({
router
}).$mount('#app')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<h1 v-if="$route.meta.header === 1">I'm visible on home page one</h1>
<h2 v-else-if="$route.meta.header === 2">I'm visible on home page two</h2>
<h3 v-else-if="$route.meta.header === 3">I'm visible on home page three</h3>
<p>
<router-link to="/">Home</router-link>
<router-link to="/home-one">Home One</router-link>
<router-link to="/home-two">Home Two</router-link>
<router-link to="/home-three">Home Three</router-link>
</p>
<router-view></router-view>
</div>