How to upload image file only in vuejs? - vue.js

I am having this little problem and i dont know what it is?
<div class="add-picture">
<vs-upload limit="1" action="https://jsonplaceholder.typicode.com/posts/" #on-success="successUpload" />
</div>
I dont know what javascript does to do this.

Vue itself doesn't have the ability upload the file to your server. You can pass parameters from Vue into a POST request to a back end using method event handlers and a client like Axios, but Vue itself merely forwards the data while something like Axios would be responsible for the transfer.
There are other clients out there who can handle HTTP requests and a plethora of components out there for handling file uploads, but Axios is the one I chose as an example.
This article here might be of more assistance.

<template>
<vs-upload limit=1 action="https://jsonplaceholder.typicode.com/posts/" #on-success="successUpload" />
</template>
<script>
export default {
methods:{
successUpload(){
console.log('success')
}
}
}
</script>
limit takes a Number not a String. Vue is terribly confusing on this subject, I know.
And Vuesax library is full of bugs, fyi.
https://lusaxweb.github.io/vuesax/components/upload.html#automatic

Related

Nuxt3 useFetch only retrieving data occasionally

I'm a little bit confused with Nuxt 3 and the lifecycle of when it gets data. I understand that it's a universal rendering process, but I'm using Strapi 4 to manage content in my Nuxt 3 project and only occasionally do I retrieve the data via useFetch. The API route from Strapi never goes down so I'm probably just doing something wrong.
Here is my Vue file in Nuxt:
<script setup lang="ts">
const {data: works, pending, error} = await useFetch("http://localhost:1337/api/works", {
params: {
populate: "*"
}
});
</script>
<template>
<div>
<div v-for="work in works">
... do something
</div>
</div>
</template>
I'm not sure how to get the content when the page loads. When I log the error returned, it's just true. But it's only sometimes. The content will load once, and then as soon as I refresh the page, it goes back to having an error. So I'm thinking something is getting cached maybe client-side? I'm really not sure what to do next.
Try passing this option to useFetch: initialCache: false. See more

Use Vimeo Player SDK with Nuxt.js

I want to use the library like Vimeo Player SDK with Nuxt.js.
<template>
<iframe
id="video01"
ref="video01"
src="https://player.vimeo.com/video/{videoID}">
</iframe>
</template>
<script>
import Player from '#vimeo/player'
export default {
created () {
const iframe = this.$refs.video01
const player = new Player(iframe)
}
}
</script>
But I cannot get DOM.
In case of SPA, I couldn't get DOM.
So error log is here.
TypeError: You must pass either a valid element or a valid id.
In case of SSR, window cannot use.
So error log is here.
window is not defined
Can't I use Vimeo Player SDK with Nuxt.js?
Did you try the vue-vimeo-player package? It could be helpful to have something managed the Vue way.
For the SPA, you will need to wait for the element to be on the page; hence try your code in a mounted hook (created step is before anything get mounted to the DOM).
If you want SSR too, you could try to wrap the whole thing into a
<client-only>
<! --- note I used vue-vimeo-player and not the vimeo-player --->
<vue-vimeo-player ref="player" :video-id="yourVideoID"/>
</client-only>
Here is a repo that I've created to show you how simple it is to make it work: https://github.com/kissu/so-nuxt-vimeo/blob/master/pages/index.vue
It made me find that you should use the <vue-vimeo-player /> component and not <vimeo-player />.
However, I imported the Vue wrapper for Vimeo Embed Player in the demo locally in a Vue component.

undefined data error on page reload Nuxt.js

I'm currently developing a universal app using Nuxt.js, the data on most of the pages is retrieved from an API using a fetch hook as well as vuex store. I started noticing errors on page reload/refresh and sometimes when I visit a page from the navbar. The page error is:
TypeError: Cannot read property 'data' of undefined
where data is an object retrieved from an API. I have searched around the internet for this and found it has something to do with data not being loaded or page rendering whilst the data is not fully retrieved. i have found a work around by using a v-if on my template to check if the data is set then display the contents. my question is if there is a way to achieve this, i have tried using the async/await keywords but it doesn't help and i feel like the v-if method is not the best way to handle it.
edit: solved by using $fetchState.pending when using fetch()
If in your template you display right away the data you retrieve from the API, then indeed using the v-if is the right way to do.
If you are using the new fetch() hook, then in your template you can use $fetchState.pending to check if the loading has finished, for example:
<div v-if="$fetchState.pending">
<p> Content is loading... </p>
</div>
<div v-else>
<p> Content has loaded! {{data}}</p>
</div>
<script>
export default{
data(){
return{
data: null
}
}
async fetch(){
this.data = await getSomeAPI
}
}
</script>

Vue Template - Making any URLs found in returned text string to a link

I am working on a project that is Vue modular based (code used is: https://github.com/mishushakov/dialogflow-web-v2/blob/bc3ce7d7cf8e09a34b5fda431590bd48cc31f66b/src/App.vue)
Linking to the file I think need to make the change to, have been trying but I don't really know Vue at all and had not luck.
The returned message is plain text for example: this is a test message, please visit https://wwww.google.com
What I am trying to do, is from that text string, if a URL found is to create a link from that found URL
<RichComponent><RichBubble v-if="message.queryResult.fulfillmentText" :text="message.queryResult.fulfillmentText" /></RichComponent>
Is what the current code is that returns the data.
Is there a best way to achieve this? Is there a core function maybe?
I have tried to npm install linkify but cannot seem to get it working so maybe a direct approach would be better?
You can use linkifyjs to convert links in a string into anchor tags. The linkifyjs/lib/linkify-string.js file augments the String prototype with a linkify() method.
<template>
<p v-html="msg.linkify()"></p>
</template>
<script>
import 'linkifyjs/lib/linkify-string' // side effect: creates String.prototype.linkify
export default {
props: ['msg'],
}
</script>
It also exports that method if you prefer an explicit call:
<template>
<p v-html="linkify(msg)"></p>
</template>
<script>
import linkify from 'linkifyjs/lib/linkify-string'
export default {
props: ['msg'],
methods: {
linkify,
}
}
</script>

Vue prerender flickering

I have the following solution now:
<template>
<section id="prod-main">
<prod-preview v-for="prod in products" :id="prod.id" :key="prod.id"/>
</section>
</template>
export default {
...
computed: {
products: function () {
return this.$store.getters['products/getPreview']
}
}
...
}
Vuex store will receive info after some delay from my backend. So at first call it will be empty. Now I want to use vue spa prerender and here I see a flickering.
As I understood it works like:
1. Browser loads HTML with products
2. Execute js that replace products with nothing because the store is empty.
3. After some delay shows it again with backend info.
How can I fix it? I should left prerender for indexing and I can't hardcode the backend reply.
You can use the setting captureAfterTime to wait for your async call to complete, before saving the html of the page.
Other settings are available :
// NOTE: Unless you are relying on asynchronously rendered content,
// such as after an Ajax request, none of these options should be
// necessary. All synchronous scripts are already executed before
// capturing the page content.
// Wait until a specific event is fired on the document.
captureAfterDocumentEvent: 'custom-post-render-event',
// This is how you would trigger this example event:
// document.dispatchEvent(new Event('custom-post-render-event'))
// Wait until a specific element is detected with
// document.querySelector.
captureAfterElementExists: '#content',
// Wait until a number of milliseconds has passed after scripts
// have been executed. It's important to note that this may
// produce unreliable results when relying on network
// communication or other operations with highly variable timing.
captureAfterTime: 5000,
Another issue can be related to how the prerendered HTMl gets hydrated, i've openned an issue on github, but they still haven't addressed it (and are not willing to ?)
https://github.com/chrisvfritz/prerender-spa-plugin/issues/131
The solution is to add data-server-rendered="true" to your vuejs parent node in the prerendered html, like this:
<div id="root" data-server-rendered="true">...
You can use the option postProcessHtml to do so.
I don't know if I understand your problem here but have you tried to add a v-if to avoid flickering:
<template>
<section id="prod-main">
<prod-preview
v-if="products.length > 0"
v-for="prod in products"
:id="prod.id"
:key="prod.id"/>
</section>
</template>