vuetify doesnt load image in <v-img> although prop shows it has the url - vuejs2

<v-img :src="getPhoto()" height="200px" width="200px"></v-img>
this is for photo to load from getphot function. the src has the url for facebook but vuetify doesnt load anything
computed: {
user () {
return this.$store.getters.user
}
},
methods: {
getPhoto () {
return this.$store.getters.user.photoUrl
}
}
i do not get any error. and when i use the link i can access the image. because i have logged in from my device.
note: i am using firebase for all of these

Try
<v-img :src="require('getPhoto()')" height="200px" width="200px"></v-img>
instead of
<v-img :src="getPhoto()" height="200px" width="200px"></v-img>
Vue loader converts relative paths into require functions automatically for you. Unfortunately, this is not the case when it comes to custom components. You can circumvent this issue by using require. If you're using Vuetify as a Vue-CLI 3 plugin, you can edit your project's vue.config.js file by modifying the options for vue-loader.
// Incorrect
<v-img src="../path/to/img" />
// Correct
<v-img :src="require('../path/to/img')" />
Source: Vuetify
Update: When not using a relative path, I tried creating an example when using a function to get the URL for the image source. I think there are two problems with your code:
Remove the () from getPhoto() in <v-img>
Add the getPhoto() to the computed property.
Here is a Codepen
I hope it helps.

Related

attribute binding in vue 3

I'm new to Vue and currently trying to dynamically change the video or image source link by passing the data in through a prop. I created a component with specific template structure that I would like to pass in the source from the main app.js page. I've tried binding it in both areas but unsure if I'm doing it correctly. I tried using regular divs and stuff to embed the video in app.js and it shows the content perfectly.
parent element contains 'Video' component-
<Video theme="IL" :vidSrc="srcIL.vid"></Video>
import Video from "./components/Video.vue";
export default {
name: "App",
components: {
Video
},
data() {
return {
srcIL: {
vid: "./assets/invi-lines/invisible-lines-film.mp4"
}
};
}
child 'Video component'
<template>
<div class="introVid top">
<video controls :src="vidSrc"></video>
</div>
</template>
<script>
export default {
props: ["theme", "vidSrc"]
};
</script>
This seems like you have it set up properly, and it is hard to know exactly what is causing the issues from the info provided, but I'm going to make a guess that it might be that the asset is not getting bundled.
I tried using regular divs and stuff to embed the video in app.js and it shows the content perfectly
I suspect you had something like:
<video controls src="./assets/invi-lines/invisible-lines-film.mp4"></video>
which would have taken the resource from the assets and packaged it for use.
see relative-path-imports for details.
You can try forcing these to load using require somewhere in the project, which will force the compiler to copy the asset, but really, if you have dynamic assets (assuming there's more than a handful and they can change) you should have them in the public folder already, not in the source folder. So my recommendation is that you move the dynamic assets to the public folder (assuming that was your issue to begin with)

Vue.js - Embed Swagger UI inside a Vue component?

I have a form in my Vue component which uploads the api file. Now I want to render the contents of the file like this:
I have imported swagger client library: https://github.com/swagger-api/swagger-ui.
Now, here
is an example of how you do it in a static page. But I need to do it inside a Vue component (or Quasar, specifically), so I do it like that:
Register swagger-ui inside my register components file:
<link rel="stylesheet" type="text/css" href="swagger-ui.css">
Now it is available as:
this.swaggerUI({})
anywhere in my components. Inside my component I have a div in a template to render the api file:
<template>
<q-form>here lies q-file element, submit button and other stuff</q-form>
<div id="swagger-ui"></div>
</template>
In the mentioned question he had something like:
<script>
window.onload = function() {
const ui = SwaggerUIBundle({
url: "https://yourserver.com/path/to/swagger.json",
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
]
})
window.ui = ui
}
</script>
Here's the difference: first of all, no window.onload, I must render it on submit button. Then, I deal with an uploaded file stored in my model, so no URL here. Now, I don't get how to make it work with locally stored file, when I try with the remote url, it gives me:
vue.esm.js?a026:628 [Vue warn]: Error in v-on handler: "Invariant Violation: _registerComponent(...): Target container is not a DOM element."
I was getting a similar error (Target container is not a DOM element) trying to use a static swagger spec. Instead of using window.onload, I found that Vue has the mounted() function, so this Vue 3 file worked for me:
<template>
<div class="swagger" id="swagger"></div>
</template>
<script>
import SwaggerUI from 'swagger-ui';
import 'swagger-ui/dist/swagger-ui.css';
export default {
name: "Swagger",
mounted() {
const spec = require('../path/to/my/spec.json');
SwaggerUI({
spec: spec,
dom_id: '#swagger'
})
}
}
</script>
This one appeared to be a simple yet very unobvious typo: in windows.onload function:
dom_id: '#swagger-ui',
must instead be
dom_id: 'swagger-ui',
without hash sign, that's it!

How to insert content inside tinymce editor using vue js?

I want to insert content like <span class="some-class">text</span> inside tinymce editor using a button in vue js template. How could I accomplish that using the tinymce-vue wrapper?
Here's the code:
<template>
<tinymce-editor
api-key="my-api-key-here"
/>
<button #click="addContent">button</button>
</template>
import Editor from '#tinymce/tinymce-vue'
export default {
components: {
tinymceEditor: Editor
},
methods: {
addContent () {
tinymce.activeEditor.setContent('<span class="some-class">text</span>');
}
}
}
Edit:
I also installed tinymce using npm i tinymce --save and added the import import tinymce from 'tinymce/tinymce to the code above. Now I don't get the error 'tinymce' is not defined anymore, but the editor doesn't appear either.
If you want to use tinymce in vue with typscritt to set up your content and avoid the undefined error you need to import tinyMCE as
import { getTinymce } from '#tinymce/tinymce-vue/lib/cjs/main/ts/TinyMCE';
Then you can set your content
getTinymce().activeEditor.setContent('coucou');
In your event handler for the button click, you can call TinyMCE's .setContent() method to set editor content.
Here is a demo:
https://codesandbox.io/s/set-content-in-tinymce-in-vue-jzciu
Don't forget, tinymce-vue doesn't include the code for TinyMCE itself. You'll either have to use an API key (which you can get for free at tiny.cloud) or use a self-hosted installation of TinyMCE. (For more info, see Step 6, here: https://www.tiny.cloud/docs/integrations/vue/#procedure)
I finally gave up trying to get access to tinymce in Vue 3 component. It either undefined or if it is not undefined - setContent command just do nothing - no errors but still no content inserted.
I just used recommended for "#tinymce/tinymce-vue" way of data binding using v-model
It looks like this:
<Editor
v-model="someLocalVar"
api-key="no-api-key"
:init="{
plugins: 'lists link image table code help wordcount',
}"
/>
then
watch(someLocalVar, () => {
//do whatever you like with your someLocalVar
});
If you want to insert content into TinyMCE you should use its APIs to do so:
https://www.tiny.cloud/docs/api/tinymce/tinymce.editor/#setcontent
https://www.tiny.cloud/docs/api/tinymce/tinymce.editor/#insertcontent
For example:
tinymce.activeEditor.setContent('<span class="some-class">text</span>');
tinymce.activeEditor.insertContent('<span class="some-class">text</span>');

Using <object> to embed svg but doesn't show anything

I was trying to use to embed the svg picture but it does not show anything. I looked at some other threads and it was suggested to add type="image/svg+xml", however, it did not solve the issue. When I am trying to look at the DOM for some reason it seems to create an endless loop. I attached the picture
This is the compononent
<template>
<div class="logo">
<object type="image/svg+xml" data="logo.svg">
</object>
</div>
</template>
This is the app.vue
template>
<div id="app">
<Demo></Demo>
</div>
</template>
<script>
import Demo from './components/Demo.vue'
export default {
name: 'app',
components: {
Demo
}
}
</script>
```[![Snapshot][1]][1]
[1]: https://i.stack.imgur.com/Q6ipO.png
This happen because vue-loader doesn’t recognize paths in just any attribute. By default just recognize these ones: https://vue-loader.vuejs.org/options.html#transformasseturls
So, there are 3 possible solutions
Note: If you are not using eslint as linter you could remove eslint comments
1: Bind the route to your image
First add the next variable to your data in the component
data() {
return {
// eslint-disable-next-line global-require
mySvg: require('../assets/logo.svg'),
};
},
Next modify your template
<object type="image/svg+xml" :data="mySvg">
2: Add vue-loader rule
If you don't want to have to bind every svg image, you could add a rule to vue-loader in order to say how to handle data attribute in a object
Go to your webpack config file, if you created the project using vue-cli 3.x you have to create a vue.config.js file in the root (same level that package.json)
// vue.config.js
module.exports = {
chainWebpack: (config) => {
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap((options) => {
// eslint-disable-next-line no-param-reassign
options.transformAssetUrls = {
object: 'data',
};
return options;
});
},
};
if you want to check that the config was added, execute vue inspect > webpack.config and expect see something like this (inside webpack.config):
{
loader: 'vue-loader',
options: {
...
transformAssetUrls: {
object: 'data'
}
}
}
More info: https://cli.vuejs.org/guide/webpack.html#working-with-webpack
3: Replace default loader and use svg as vue components
Other option is use vue-svg-loader. This loader inlines the SVGs which enables you to modify them using css. Also optimize your files with SVGO
See more: https://vue-svg-loader.js.org/#vue-cli
It is worth checking that you don't have a CSS rule hiding object tags. Otherwise it seems correct. You probably need to check the path and make sure you can reach your image. I assume your filename is a dummy, but try to use an absolute path. And make sure you can hit the path and see the image in your browser.

Vue.js - Element UI - Use upload component without POST request triggering

I'm using the upload component of Element UI. It unfortunately triggers a POST request as soon as a file is uploaded. What I'm aiming for is to push the files to an empty array which would be posted after with button.
HTML
// Element UI documentation says http-request overrides xhr behavior
// so I can use my own file request. In this case, I wanted to use a method
// though I'm not quite sure about this part?
<el-upload
action="",
:http-request="addAttachment",
:on-remove="deleteAttachment",
:file-list="attachments">
<el-button size="mini" type="primary">Add file</el-button>
</el-upload>
// button that uploads the files here
JS
data() {
attachments: []
},
methods: {
addAttachment ( file, fileList ) {
this.attachments.push( file );
},
deleteAttachment () {
// removes from array
}
}
Apparently, you also need to set the auto-upload prop to be false. Otherwise, it defaults to true and will automatically try to upload the file even if you've specified a function for the http-request prop.
In your case:
<el-upload
action="",
:http-request="addAttachment",
:auto-upload="false"
:on-remove="deleteAttachment",
:file-list="attachments"
>
<el-button size="mini" type="primary">Add file</el-button>
</el-upload>
Here's the documentation for the component.