GSAP implementing to Vue.js app with webpack - vue.js

i have a problem with implementing GSAP to my vue.js app which i created with vue-cli and webpack
What i wanna do?
1- I tried to create tween beforeComponent mounting, in some function.
What i tried?
1- I create my vue app,
2- I already installed this package, with:
npm install greensock --save
everything is was okey with installation, then;
3- I imported TweenMax to main.js with this way:
import { TweenMax } from 'greensock';
4- I created some div into my component for animating with TweenMax.
5- I create some functions into methods of my component which wrapping the Tween,
methods: {
animate: function() {
TweenMax.to(".rect", 1, {x:100, alpha:0, ease:Sine.easeIn});
console.log('test');
}
},
and then i call this function on before mounting component;
beforeMount(){
this.animate()
}
so my tween not working, i'm not getting some error in my console.
I print the console.log("test"); for testing the function is work or not?.
result is function work. I'm getting the test message on console. But tween is no there :) .
Where i make mistake ?
Fully code of my component:
<template>
<div class="container">
<div class="home">
<h1>
HELLO
</h1>
<h4>
How are u doing?
</h4>
</div>
<div class="rect">
</div>
</div>
</template>
<script>
export default {
name: 'Home',
methods: {
animate: function() {
TweenMax.to(".rect", 1, {x:100, alpha:0, ease:Sine.easeIn});
console.log('test');
}
},
beforeMount(){
this.animate()
}
}
</script>
<style lang="scss">
.rect {
background-color:blue;
width: 10vw;
height: 100px;
position: absolute;
z-index: -1;
}
</style>
FIX . ///////////
While i wait to answer :) found the solution myself,
everything is fine with code, just need to call function not on beforeMount(), need to call it on mounted();

Related

Simple Nuxt 3 Page Transition not working

I'm discovering Nuxt 3 and and simply want to make an animation between pages. The idea is to use javascript hooks to make page transitions using js library such as gsap or animeJs.
So in my app.vue file, I simply put <NuxtPage/> into <Transition> element like this :
<NuxtLayout>
<Transition>
<NuxtPage/>
</Transition>
</NuxtLayout>
My vue pages ('./pages/index.vue' and './pages/project/myproject.vue') look like this :
<template>
<div>
<h1>My Project</h1>
</div>
</template>
<script setup>
function onEnter(el, done) {
done()
}
function onLeave(el, done) {
done()
}
</script>
I have followed both Nuxt 3 and Vue 3 documentations :
https://v3.nuxtjs.org/guide/directory-structure/pages#layouttransition-and-pagetransition
https://vuejs.org/guide/built-ins/transition.html#javascript-hooks
I also read this thread on github, but I can't find answer :
https://github.com/nuxt/framework/discussions/851
When i was using Nuxt 2 I only need to put transition object into my page like this and it's working fine :
<script>
export default {
// ... (datas, methods)
transition: {
mode: "in-out",
css: false,
enter(el, done) {
console.log("enter");
done()
},
leave(el, done) {
console.log("leave");
done()
}
}
}
</script>
<template>
<div>
<h1 class="text-center text-5xl">Hello World</h1>
</div>
</template>
Do you have any idea how to achieve it ?
Nuxt 3 doesn't need a <Transition> wrapper around pages/layouts, by default it does that for you.
Take a look at this starter template: in assets/sass/app.scss, the last part of the style is page and layout transition.
You can tweak the default named animations (page- and layout-).
More infos here
Just follow the official documentation for Nuxt 3. You need to add the following code to your nuxt.config.ts file:
export default defineNuxtConfig({
app: {
pageTransition: { name: 'page', mode: 'out-in' }
},
})
And then apply the classes inside your app.vue file, like this:
<template>
<NuxtPage />
</template>
<style>
.page-enter-active,
.page-leave-active {
transition: all 0.4s;
}
.page-enter-from,
.page-leave-to {
opacity: 0;
filter: blur(1rem);
}
</style>
Nuxt 3 uses the Vue's <Transition> component under the hood, so you don't need to add it in the template.
Be careful with the css prefix.

d3 graph rendering with vue

Because of non compatible dependencies, I have to downgrade from vue3 to vue2.
I have created a force directed graph with D3 library. Everything worked find with vue3 using composition api. I am not familiar with vue 2 and adapting my graph to vue2 has not been working out for me.
In vue3 it was very straitforward and ref() made it pretty easy to accomplish.
As for vue2, I have tried making good use of lifecycle hooks such as computed and watch
Any help is more than welcome
Here is a minimalistic representation of my working component in vue3. This component creates the graph in a svg and then renders it in the template.
<template>
<div class="col" style="position: absolute; width:100%; height:100%" >
<div class="main-map-container" style="overflow: hidden; width: 100%;">
<div ref="graph" class="canvas">
</div>
</div>
</div>
</template>
<script >
import {onMounted, onBeforeMount, ref} from 'vue'
export default {
setup(){
const graph = ref()
const links = [{src:"Amazon",target:"Aurora"},{src:"Amazon",target:"Aurora"},{src:"Amazon",target:"Zoox"},{src:"Amazon",target:"Rivian"}]
const nodes = [{id:"Amazon"},{id:"Aurora"},{id:"Zoox"},{id:"Rivian"}]
onBeforeMount( async ()=>{
const svgobj = ForceGraph(nodes, links)
graph.value.appendChild(svgobj);
})
function ForceGraph(
nodes,
links
){
// The code for the graph has been removed since it is much too long
return Object.assign( svg.node() );
}
return { graph }
}
}
</script>
<style></style>
This is the vue2 component that i have emptied for this post
<template>
<div class="col" style="position: absolute; width:100%; height:100%" >
<div class="main-map-container" style="overflow: hidden; width: 100%;">
<div ref="graph" class="canvas">
</div>
</div>
</div>
</template>
<script>
export default {
setup(){
},
methods: {
},
watch: {
},
props: {
},
computed: {
},
created() {
},
mounted() {
},
updated(){
},
data() {
return {
}}
}
</script>
<style>
</style>
You can use Vue3 composition API in vue 2. Install the composition api and then just keep your code the same, with the setup method exactly as it was.
The setup method, lifecycle hooks, and all the reactivity (refs and reactive objects) are made available to you, with very few incompatibilities.
We use d3 with Vue2 in this fashion all the time. 100% compatible.
https://github.com/vuejs/composition-api

VueJS import and parse CSV (frontend only)

can you please share a working example of parsing CSV file from client?
I can't seem to find any working example at all ...
I have been playing around with vue-papa-parser and vue-csv-import but can make it work :(
Here is my component file (using the latter package):
<template lang="html">
<div class="container">
<h1 class="h2">CSV Upload</h1>
<div class="dragndrop text-muted d-flex flex-column justify-content-center align-items-center border border-secondary">
<vue-csv-import
v-model="csv"
:fields="{name: {required: false, label: 'Name'}, age: {required: true, label: 'Age'}}"
>
<vue-csv-toggle-headers></vue-csv-toggle-headers>
<vue-csv-errors></vue-csv-errors>
<vue-csv-input></vue-csv-input>
<vue-csv-map :auto-match="false"></vue-csv-map>
</vue-csv-import>
</div>
</div>
</template>
<script>
import { VueCsvImport } from 'vue-csv-import';
export default {
name: "CSVUpload",
components: {
VueCsvImport
},
data() {
return {
csv: null
}
},
methods: {
}
}
</script>
<style lang="css" scoped>
.dragndrop {
background-color: #f5f5f5;
height: 50vh;
width: 80%;
margin: 2.5em auto;
}
</style>
but on the console I am getting this:
[Vue warn]: Error in render: "TypeError: Cannot read property 'VueCsvImportData' of undefined"
found in
---> <VueCsvImport>
<CallRecordUpload> at src/components/admin/Upload/Upload.vue
<Home> at src/components/Home.vue
<App> at src/App.vue
<Root>
and thus I cannot even see any INPUT TYPE="FILE" to try to upload ... there is something wrong with the vue-csv-import :(
any thoughts?
EDIT: SOLVED
I had to install lower version (v4 is for vue3 only!)
npm install vue-csv-import#2.3.4 --save
works for me great!
thx #marsnebulasoup for the tip !!
bad version .. it automatically uses the latest version 4 (which is for vue3 only .. for vue2 I had to use 2.3.4 and it worked great :) )
see the changelog

How to include external html in Nuxt app from object in js file with http url provided by bot constructor?

I try to include a bot developed with landbot.io in my nuxt web app (NUXT.js framework).
Below, there is the code that the landbot's guide provides me.
Code to include:
<script src="https://static.landbot.io/landbot-widget/landbot-widget-1.0.0.js"></script>
<div id="myLandbot" style="width: 100%; height: 500px"></div>
<script>
var myLandbot = new LandbotFrameWidget({
container: '#myLandbot',
index: 'https://landbot.io/u/..../index.html',
});
</script>
But i don't know what i should do with the second script tag because i always get this error:
"LandbotFrameWidget do not definied"
I include the first script tag in nuxt.config.js like that:
head: {
script: [
{ src: 'https://static.landbot.io/umicore/UmiAccessPoint.js' },
{ src: 'https://static.landbot.io/landbot-widget/landbot-widget-1.0.0.js' }
]
}
Your nuxt.config.js config is correct, but the first script src is not needed.
I've created a working example in this codesandbox, take a look at the code used in the index.vue file:
<template>
<section>
<div>
<div id="myLandbot" style="width: 100vw; height: 100vh"></div>
</div>
</section>
</template>
<script>
export default {
mounted() {
var myLandbot = new LandbotFrameWidget({
container: "#myLandbot",
index: "https://landbot.io/u/H-117144-ZGUSSI5IM2OI5NYH/index.html"
});
}
};
</script>
Hope it helps!

How to compute styles on <body> or <html> using vue.js?

I am using vuejs style bindings to render changes dynamically as the styles are computed.
This works great for everything within the scope of my Vue instance but how can I compute styles for body or html tags?
This used to be possible when you could bind the vue instance to but vue no longer lets you do it.
I want to dynamically update the background color of using my computed variables in vue.
edit: added code snippet to demonstrate
var app = new Vue({
el: '#app',
data: {
color: '#666666'
},
computed: {
backgroundColor: function() {
return {
'background-color': this.color
}
}
},
methods: {
toggleBackground: function() {
if(this.color=='#666666'){
this.color = '#BDBDBD'
} else {
this.color = '#666666'
}
}
}
})
<script src="https://vuejs.org/js/vue.min.js"></script>
<html>
<body>
<div id="app" :style="backgroundColor">
<div>
lots of content...
</div>
<button #click="toggleBackground"> Click to toggle </button>
</div>
</body>
</html>
If you really need to style body itself, you'll need to do it with plain JavaScript in a watcher. A simple example is below.
You should (not something I've tried, but I'm hypothesizing) be able to defeat overscrolling effects by making body and your outer container non-scrolling. Put a scrollable container inside that. When it overscrolls, it will show your outer container, right?
The reasons for not binding to body are here (for React, but applies to Vue).
What’s the problem with ? Everybody updates it! Some people have
non-[Vue] code that attaches modals to it. Google Font Loader will
happily put elements into body for a fraction of second, and
your app will break horribly and inexplicably if it tries to update
something on the top level during that time. Do you really know what
all your third party scripts are doing? What about ads or that social
network SDK?
new Vue({
el: '#app',
data: {
isRed: false
},
watch: {
isRed() {
document.querySelector('body').style.backgroundColor = this.isRed ? 'red' : null;
}
}
});
#app {
background-color: white;
margin: 3rem;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
<input type="checkbox" v-model="isRed">
</div>
I think I found better solution than using jQuery/querySelector
You can add tag style right in your Vue template.
And add v-if on this, smth like that:
<style v-if="true">
body {
background: green;
}
</style>
Thus you can use computed/methods in this v-if and DOM always will update when you need.
Hope this will help someone ;)
UPD:
Using tag "style" in templates is not best idea, but you can create v-style component, then everything will be fine:
Use style tags inside vuejs template and update from data model
My snippet:
Vue.component('v-style', {
render: function (createElement) {
return createElement('style', this.$slots.default)
}
});
new Vue({
el: '#app',
data: {
isRed: false,
color: 'yellow',
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input type="checkbox" v-model="isRed">
<v-style v-if="isRed">
body {
background: red; /*one more benefit - you can write "background: {{color}};" (computed)*/
}
</v-style>
</div>