I'm trying to develop a straightforward program that will allow me to get movies from my AWS-S3 bucket and convert them to picture thumbnails.
Here is my code.
<template>
<img :src="imgURL" class="card-top" alt="thumb_nail">
</template>
<script>
import { defineComponent, ref } from "vue";
export default defineComponent({
props: {
url: {
type: String,
required: true,
},
},
setup(props) {
const imgURL = ref("")
const video = document.createElement("video");
video.src = props.url;
video.addEventListener("loadeddata", () => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
imgURL.value = ctx.canvas.toDataURL("image/jpeg");
})
return { url: props.url, imgURL };
},
});
</script>
Home.vue
<template>
<Thumbnail src="aws-s3_bucket_url" />
</template>
<script>
import { defineComponent, ref } from "vue";
import Thumbnail from "../components/Thumbnail.vue"
export default defineComponent({
components: {
Thumbnail
}
});
</script>
There are no errors in the code, the picture does not appear. It has its height and width, but the picture does not appear.
Make sure that the url is valid and that loadeddata event fires.
You can test with a test video url to ensure that it loads.
<template>
<!-- parent.vue -->
<VideoComponent url="https://www.w3schools.com/html/mov_bbb.mp4" />
</template>
If this example show you something that means that the provided prop is not a valid url when you load your data.
If it doesn't you are not rendering this component properly.
Related
What I am trying to achieve:
Display an image from dynamic link in Post.vue, which follows the layout of PostLayout.vue
In PostLayout.vue, I have a <slot> named postFeaturedImage, and inside the slot, there is a <div>, I want to use the image as the background of it.
What I am using:
Laravel, InertiaJS, Vue 3
My codes are:
Post.vue:
<template>
<PostLayout>
<template #postfeaturedImage>
<!-- Here I want to display the image -->
</template>
</PostLayout>
</template>
<script>
import PostLayout from '#/Layouts/PostLayout'
export default {
data() {
return {
featured_image: ''
}
},
components: {
PostLayout,
},
props: {
post: Object /* Passed the prop from Controller */
},
mounted () {
this.featured_image = this.post.featured_image
}
}
</script>
PostLayout.vue:
<template>
<slot name="postfeaturedImage" :bgImage="bgImage">
<div :style="`background-image:url(${bgImage}); height: 75vh;`"></div>
</slot>
</template>
<script>
export default {
}
</script>
I've removed all irrelevant codes. I am a beginner in Vue 3 and Inertia and in need of help!
An alternative approach will be creating a FeaturedImage component. Also, you can reference the post image directly from the props you receiving. There's no need for the data method and the mounted in this case.
<template>
<PostLayout>
<template #postfeaturedImage>
<FeaturedImage :src="post.featured_image" />
</template>
</PostLayout>
</template>
<script>
import PostLayout from '#/Layouts/PostLayout'
import FeaturedImage from '#/Layouts/FeaturedImage'
export default {
components: {
PostLayout,
FeaturedImage
},
props: {
post: Object
}
}
</script>
Add a props to your PostLayout.vue
<script>
export default {
props: {
bgImage: { type: String },
},
};
</script>
And give a value to that props in your Post.vue
<template>
<PostLayout :bgImage="featured_image"> </PostLayout>
</template>
And if you ever want to have a post without an image and a different layout you should do :
<template>
<PostLayout>
<template #postfeaturedImage> post without background image</template>
</PostLayout>
</template>
I tried to use prueba.js in one of the components of my app (InputSwap.vue), in which there is a button ('console.log'). I want to use this file using that button, but the app showed me this error:
enter image description here
prueba.js let me see the data in the console by clicking the button.
The data was saved with window.localStorage:
window.localStorage.setItem('data_input', JSON.stringify(data));
where am I wrong?
prueba.js :
export default {
infoPrueba() {
var data = (JSON.parse(window.localStorage.getItem('data_input')))
console.log(data)
}
}
InputSwap.vue:
<template>
<div class="card-action">
<Button v-on:click="prueba()"
v-bind:style="{'margin-left' : '5px', background : '#52368c'}"
btext="Console.log" icon="code"
/>
</div>
</template>
<script>
import Button from './Button'
import * as prueba from './prueba.js' // I have prueba.js in components folder
export default {
name: 'InputSwap',
components: {Button},
methods: {
prueba: async function () {
prueba.infoPrueba()
},
},
}
</script>
Thanks to x-rw, I solved this problem:
I changed import * as prueba from './prueba.js' to import {infoPueba} from './prueba.js'
and I wrote this code in prueba.js:
export const infoPrueba = () => {
var data = (JSON.parse(window.localStorage.getItem('data_input')))
console.log(data)
}
I have made a vue dropzone component using dropzonejs. The component works however I'm not able to configure the dropzone to upload files larger than 256mb which I believe is the default. For testing purposes I have put 1mb(reducing max file size).
I have also tried putting my config code inside mounted beforeMount, create etc.
My Code
<template>
<div class="dropzone-container">
<form
:action="uploadurl"
class="dropzone drop-area"
enctype="multipart/form-data"
id="myDropzone"
ref="myDropzone"
:key="`dz-${dzkey}`"
>
<input type="hidden" name="path" :value="currentPath" />
</form>
<button class="finish-button" #click="finishUpload">Finish Upload</button>
</div>
</template>
<script>
// import * as Dropzone from "dropzone/dist/min/dropzone.min.js";
import FileHandling from "../fileHandling";
const Dropzone = require("dropzone/dist/dropzone.js");
Dropzone.autoDiscover = true;
export default {
name: "DropZone",
props: ["currentPath"],
data() {
return {
uploadurl: FileHandling.SendForUpload(),
dzkey: 0,
};
},
methods: {
finishUpload() {
this.$refs.myDropzone.dropzone.removeAllFiles();
this.$emit("finishedUpload");
},
dropconfig() {
console.log(Dropzone);
Dropzone.options[this.$refs.myDropzone] = {
maxFilesize: 1,
};
},
},
ready: function() {
this.dropconfig();
},
};
</script>
There are two issues in your code:
There is no ready hook. Perhaps you meant mounted:
export default {
// ❌ ready hook does not exist
//ready() {
// this.dropconfig();
//},
// ✅
mounted() {
this.dropconfig();
}
}
Dropzone.options is a map of element IDs (strings), not element instances (HTMLElement):
// ❌
//Dropzone.options[this.$refs.myDropzone] = {/*...*/};
// ✅ `myDropzone` is a string that matches element ID in template
Dropzone.options.myDropzone = {/*...*/};
Fixing those issues should allow your maxFilesize config to take effect.
I want a review button on image, but I don't find attribute.
I set the imagePreviewMarkupShow = true but it didn't work.
Package here
My Template
<template>
<div id="app">
<file-pond
name="test"
ref="pond"
max-files="4"
label-idle="Drop files here..."
:allow-multiple="true"
accepted-file-types="image/jpeg, image/png"
:files="myFiles"
v-on:init="handleFilePondInit"
allowImagePreview ="false"
/>
</div>
</template>
My Script
import vueFilePond from 'vue-filepond';
import 'filepond/dist/filepond.min.css';
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css';
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
import FilePondPluginImageOverlay from 'filepond-plugin-image-overlay';
// Create component
const FilePond = vueFilePond(FilePondPluginFileValidateType, FilePondPluginImagePreview,FilePondPluginImageOverlay);
export default {
name: 'app',
data: function() {
return { myFiles: [] };
},
methods: {
handleFilePondInit: function() {
console.log('FilePond has initialized');
// this.$refs.pond.getFiles();
// FilePond instance methods are available on `this.$refs.pond`
}
},
components: {
FilePond
}
};
How do I add that button?
I was also struggling with this problem.
The solution is to import CSS.
import 'filepond-plugin-image-overlay/dist/filepond-plugin-image-overlay.min.css'
This is not mentioned in Github.
I have two files: total.vue and completeness.vue. I would visualize the chart from total.vue into completeness.vue which will be my admin dashboard where I'll put 2 or 3 others charts.
From total.vue I'm going to export my stuff
<script>
import Chart from 'chart.js';
import JQuery from 'jquery'
let $ = JQuery
export default {
name: 'total_chart',
mounted() {
var chart_total = this.$refs.chart_total;
const ctx = chart_total.getContext("2d");
const myChart = new Chart(ctx, {
type: 'bar',
...
...
...
</script>
In completeness.vue I'm going then to import like this:
<template>
<div id="total_chart">
<div id="content">
<canvas ref="chart_total"></canvas>
</div>
</div>
</template>
<script>
import chart_total from '#/components/total'
export default {
components: {
chart_total
}
}
</script>
NO result pointing to the route which I have assigned to completeness.vue.
Suggestions?
Thanks for your time
Your code is not actually rendering the component. This is how you should do it:
<template>
<total-chart>
</total-chart>
</template>
<script>
import TotalChart from '#/components/total'
export default {
components: {
TotalChart
}
}
</script>
And then your total-chart component:
<template>
<div id="content">
<canvas ref="chart_total"></canvas>
</div>
</template>
<script>
import Chart from 'chart.js';
import JQuery from 'jquery'
let $ = JQuery
export default {
name: 'total-chart',
mounted() {
var chart_total = this.$refs.chart_total;
const ctx = chart_total.getContext("2d");
const myChart = new Chart(ctx, {
type: 'bar',
...
...
...
</script>
And just an fyi - you might want to read up on naming components: https://v2.vuejs.org/v2/guide/components-registration.html