I have an vue application which I have divided in components kinda manner seen below.
What I want is to bind src property in <template> like below so that I could have a dynamic path every time a user asks for different template to get loaded.
The .ts file will have same code in use for every different template. which prompt me to ask this question.
Please suggest a solution to it. Or am I going into right direction or not to achieve this ?
One way to achieve dynamic templates being rendered is using dynamic component rendering:
App.vue:
<template>
<div>
<button #click="selectedComponent = 'app-quote'">Quote</button>
<button #click="selectedComponent = 'app-author'">Author</button>
<button #click="selectedComponent = 'app-new'">New</button>
<hr>
<component :is="selectedComponent"></component>
</div>
</template>
<srcript>
import Quote from './components/Quote.vue'
import Author from './components/Author.vue'
import New from './components/New.vue'
data: function() {
return {
selectedComponent: 'app-quote'
}
},
components: {
'app-quote': Quote,
'app-author': Author,
'app-new': New
}
</script>
Related
I am trying to create a basic site, where I need to select options from a dropdown menu. I am using the Select.vue from the vue-strap library to implement the same. However, the v-select component in not loading onto the html. Given below is the App.vue which inherits Select.vue from vue-strap:
<template>
<div>
<app-header></app-header>
<v-select v-model="selected" :options="['Vue.js','React']"></v-select>
<app-footer></app-footer>
</div>
</template>
<script>
import Header from './components/header.vue'
import select from '../node_modules/vue-strap/src/Select.vue'
import Footer from './components/footer.vue'
export default {
components: {
'app-header': Header,
'app-footer': Footer,
'v-select': select,
},
data() {
return {
}
},
}
</script>
<style scoped>
</style>
Given below are the errors that I am getting onto the web console:
I am unable to resolve these errors. Any help is appreciated.
:options="['Vue.js','React']"
Above line can be a big problem, since you are passing the static data and not assigning any variable you don't have to use :
: this actually a binding operator you should only use this when you are binding option to some variable
For eg:
data(){
return{
options:[['Vue.js','React']]
}
}
now inside your vue file, you can add
<v-select v-model="selected" :options=options></v-select>
If you dont want to declare variable then you can remove :
<v-select v-model="selected" options="['Vue.js','React']"></v-select>
Always make sure whatever you are passing to the component is declared inside the data
If you want to use computed make sure you declare it upfront before using it
I have a Vue component that lists a bunch of clickable tags. When you click on a tag, it takes you to another page with a list of objects containing that tag.
The relevant parts of the component code are:
<template>
<div>
<h2>All Tags</h2>
<TagList v-bind:tags="tags"/>
</div>
</template>
...
<script>
import TagList from './TagList'
export default {
name: 'AllTags',
components: {
TagList
},
data () {
return {
tags: []
}
},
mounted () {
tags = // array loaded from a database
}
}
</script>
This all works fine when I initially view the page. However if I browse away from this list, e.g. by clicking on a single tag, and then browse back, I only see the <h2>All Tags</h2> header. Using the Vue debugger in the browser, I can see that the data are still there.
I'm using <router-view :key="$route.fullPath"> to control the overall app and suspect the problem lies with the keys somehow.
Can someone point me in the right direction here? How can I get the TagList component to render every time I visit that page of the app?
EDIT: Here's the code of the TagList component:
<template>
<div class="tags">
<Tag v-for="tag in tags" v-bind:tag="tag" v-bind:key="tag" />
</div>
</template>
<script>
import Tag from './Tag'
export default {
name: 'TagList',
props: ['tags'],
components: {
Tag
}
}
</script>
You can try removing v-bind all thought its not required to use, I've checked your code it seems to work fine after visiting a tag and going back, all tags are still rendered. You can take a look at this working sample .
https://codesandbox.io/s/vue-template-3tcs4?fontsize=14
We are looking to get the contents from the html (for example using a slot ) but we later (after mounting) want to bind this to a variable as one would do with a v-html.
In other words we want on initialization to have the contents being loaded as they appear in the slot and later this entire piece of content to be controlled by a binding variable like v-html (because it will be html content).
How to achieve this? without following any ugly solutions such as needing to pass the entire initial html content inside v-html attribute!
You can try like this
<template>
<custom-component>
<div v-if="html_variable" v-html="html_variable"></div>
<template v-else>
<!-- default content here -->
</template>
</custom-component>
</template>
<script>
export default
{
data()
{
return {html_variable: null};
}
}
</script>
How using v-html is ugly? Anyway just use a non-visible element to define your initial html. a <script ref="initHTML" type="text/html"> ... </script> might be a good option.
Define a data entry that should hold your HTML init:
data () {
return {
dHTML: '',
}
},
On created() update your initial html state using the ref
created() {
this.dHTML = this.$refs.initHTML.innerHTML;
},
Now you can have a pretty v-html="dHTML"
I am trying electron for the first time and I am blown away by it. I have hit a wall, though, when trying to use single file vue.js components using electron-forge. My problem is the following:
I create a project using the vue.js template and run it. Works and looks great. I have a single file page with an index file that looks like this:
<div id="test"></div>
</body>
<script>
import Vue from 'vue';
import Test from './test';
const app = new Vue(Test).$mount('#test');
app.text = "Electron Forge with Vue.js!";
</script>
So far, so good. It imports Test, which is a single file component and renders it.
Now, I would like to have other single file components nested in this main component. For example, I would like to have the following, in my app file called test.vue
<template>
<h2>Hello from {{text}}</h2>
</template>
<script>
import About from './About.vue'
export default {
components: {
appAbout: About,
},
data () {
return {
text: 'Electron'
}
}
}
</script>
Again, so far so good. I can run the app with no errors so the component is being imported.
Here comes my problem: if I now try to render the component using <appAbout></appAbout>, as I have done before in web apps with vue.js, I get the following error.
It basically says that I am not using a single root element in my component, which is really strange because my component looks like this:
<template lang="html">
<div>Hello from component</div>
</template>
<script>
export default {
}
</script>
<style lang="css">
</style>
I am stuck. Can someone please help?
So I have tried a few different things with no success, like using or even as the component names.
I also have tried these two ways of starting the vue:
The way you get with electron-forge
const app = new Vue(App).$mount('#app')
and the way I learned
new Vue({el: '#app', render: h => h(App)})
Nothing seems to work...
Define your component like this :
export default {
components: {
'app-about': About
}
}
Then use it in template like this (with kebab-case) :
<app-about></app-about>
About your compiling template error you need to wrap everything in test.vue in a root element :
<template>
<div>
<h2>Hello from {{text}}</h2>
<app-about></app-about>
</div>
</template>
I'm using Vue and Brunch in a small project, today I decide to add Vueify to make my components more concise.
But they are always seen has fragment instance so they are not rendered.
<template lang="pug">
div.sticker-container.sticker-xs-container.nav-top-sticker-animate#btn-about(v-bind:href="link")
span.sticker.sticker-xs.sticker-dark
span.sticker-txt.sticker-xs-txt(v-html="locales.btns.open")
span.sticker.sticker-xs.sticker-over.sticker-over-xs.sticker-light(v-show="opened")
span.sticker-txt.sticker-xs-txt.sticker-light-txt(v-html="locales.btns.close")
</template>
<script>
export default {
data(){
return {
disabled: false,
link: '#'
}
}
}
</script>
To use Vueify I simply add Vue-brunch to my project and I call this vue component like this:
import bar from './foo/bar'
Vue.component('sticker-bar', bar)
So, what i'm doing wrong ?
Try adding a surrounding div within your template. Like so:
<template>
<div>
<content></content>
</div>
</template>
Most times this will solve the fragment instance error.
For more detailed info: https://vuejs.org/guide/components.html#Fragment-Instance
I hope it helps!