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
Related
I created a language selection dropdown in my Navbar component. So here is my navbar component:
<div>
<h6>{{ translate("welcomeMsg")}} </h6>
<select name="lang" v-model="lang">
<option value="en">English</option>
<option value="de">Deutsch</option>
</select>
</div>
<script>
export default {
mixins: [en, de],
data() {
return {
lang: "en",
};
},
methods: {
translate(prop) {
return this[this.lang][prop];
}
}
}
</script>
So the parent of this component is an Index.vue which is main component in my application.
<div id="app">
<Topnav/>
<Navbar/>
<router-view></router-view>
<Footer/>
</div>
Currently, I am able to change the language in my Navbar component. So according to the selected value in the dropdown in Navbar component, welcomeMsg is changing. What I am trying to do is I want to put this pieve of code to TopBar "{{ translate("welcomeMsg")}} ", and according to the value of the dropdown in Navbar component, I want to change this value.
Can you help me with this or can you give me an idea how to do it?
If I understand you correctly, you want to use translate method inside Topnav component.
This method is however defined in Navbar, so it's not accessible in Topnav.
To use it elsewhere you could create a mixin with this method to import it to any component. I don't recommend this solution though as mixins are making the code messy.
Another solution is to create a component with translate method defined inside. Let this component do just that: translate a message passed by prop and render it inside some div:
<div>
{{ translatedMessage }}
</div>
<script>
mixins: [en, de],
props: {
message: {
type: String,
default: ''
},
language: {
type: String,
default: 'en'
}
},
computed: {
translatedMessage() {
return this[this.language][this.message];
}
}
</script>
You can reuse this component anywhere in the application. You would still need to pass a language prop somehow, possibly the solution would be to use vuex store to do this, since language is probably global for entire application.
For easier and more robust solutions I would use vue-i18n, which #Abregre has already suggested in his comment: https://stackoverflow.com/a/70694821/9463070
If you want a quick solution for a full-scale application and you don't have a problem with dependencies, you could try to use vue-i18n.
It's a plugin for vue that does exactly this for multi-locale websites/apps in Vue.
https://www.npmjs.com/package/vue-i18n
EDIT
Then in order to use it globally in your app, you should use vuex.
Keep the language selection state there and then wherever you want to use it, you make a computed function with the state.language getter.
The translate function should be a global registered filter
https://v2.vuejs.org/v2/guide/filters.html
I am trying to build a dropdown using vue-multiselect, where I am facing an issue. Upon selecting the first option, it works fine. However, when I try to select another option, the earlier selected option also disappears. Given below is the code which I am using:
<template>
<div>
<app-header></app-header>
<multiselect v-model="value" tag-placeholder="Add this as new tag" placeholder="Search or add a tag" label="name" track-by="code" :options="options.campaign_name" :multiple="true" :taggable="true" #tag="addTag1" style="width:200px"></multiselect>
<app-footer></app-footer>
</div>
</template>
<script>
import Header from './components/header.vue'
import Multiselect from 'vue-multiselect'
import Footer from './components/footer.vue'
export default {
components: {
'app-header': Header,
'app-footer': Footer,
'multiselect': Multiselect
},
data() {
return {
value: [
{ name: 'chess', code: 'js' }
],
options:{
campaign_name:[{name:"Chess", code:"js"},{name: "Badminton",code:"js"}],
vmw_platform_test:[],
release_version:[]
},
}
},
methods: {
addTag1 (newTag) {
const tag = {
name: newTag,
code: newTag.substring(0, 2) + Math.floor((Math.random() * 10000000))
}
this.options.campaign_name.push(tag)
this.value.campaign_name.push(tag)
}
}
}
</script>
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
<style scoped>
</style>
I guess it must have something to do with the way I am passing the data, but this is actually how I need data to be passed, in order to learn the behavior of a bigger project. Any help is appreciated.
EDIT 1: Upon selecting one component, I am not getting the option to add more options. Instead I am getting the option of only removing it, on all the options.
In your example, you have two options with same code value, and you have set the code property to be tracked as the key that will be pushed into the value array of selected options. Try changing this:
campaign_name:[{name:"Chess", code:"chess"},{name: "Badminton",code:"badminton"}],
As per the docs (https://vue-multiselect.js.org/):
track-by is used to identify the option within the options list thus it’s value has to be unique. In this example the name property is unique across all options, so it can be used as track-by value.
I'm trying to dynamically show a footer/header based on a child view in ionic
I am using the Ionic 4 framework in combination with Vue.js. Tried slots and such having the feeling i'm on the right track but not fully there yet.
I've got a Base.vue (component) which holds
<template>
<ion-app>
<ion-page class="ion-page" main>
<page-header />
<router-view />
<page-footer />
</ion-page>
</ion-app>
</template>
<script>
import PageHeader from '#/components/PageHeader'
import PageFooter from '#/components/PageFooter'
import { mapState } from 'vuex'
export default {
name: 'master',
components: {
PageHeader,
PageFooter,
},
}
</script>
As a child view i've got the following; i know that it's not the right approach to include it inside the <ion-content> but don't know how to set this up in the correct way:
<template>
<ion-content fullscreen>
<page-header>
<ion-toolbar>
<ion-title>
Test
</ion-title>
</ion-toolbar>
</page-header>
<ion-content>
<p>Schedule page</p>
</ion-content>
</ion-content>
</template>
<script>
import PageHeader from '#/components/PageHeader'
export default {
name: 'schedule',
components: {
PageHeader,
},
}
</script>
The header component (which should be dynamic):
<template>
<ion-header>
<slot name="header" />
</ion-header>
</template>
<script>
export default {
name: 'page-header',
}
</script>
What i'm trying to do is making a Base.vue with a dynamic header (PageHeader.vue) so based on a given child view i could change or extend the header if needed.
So I think you're saying you want to change the content of the page header depending on the child.
Components cannot directly affect the templates of other components in the tree. Slots give you some control over this, but it is limited to allowing a component to inject templates into sections of a child component, not the other way around.
Your options are:
Add logic to your parent component which detects what child component is shown and then change the page header accordingly. The page header won't be controlled directly by the child component, though.
Use named views with vue-router.
Use something like portal-vue, but don't go crazy with this kind of power...
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>
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!