String operations on Vue variable - vue.js

How can I make the template dynamic? I want field.title.arrayName to be text1.arrayName, text2.arrayName and so on...
Vue.component('box', {
props: ['field'],
template: `
<div>
<p>Total:{{ field.title + '.arrayName.length' }}</p>
</div>
<div>
<card-stack v-for="x in field.title + '.arrayName'" v-bind:course="x"></card-stack>
</div>
`
})
new Vue({
el: 'main',
data: {
fields: [
{ title: 'text1' },
{ title: 'text2' },
],
}
})
And that's my HTML:
<main>
<box v-for="x in fields" v-bind:field="x"></box>
</main>
Also, text1 and text2 are component names:
var text1 = new Vue({
el: '#text1',
data: {
arrayName: [
{ title: 'example' },
],
}
})
note
Please edit my question title as I really don't know how to describe it

using eval() works:
<p>Total:{{ eval(field.title + '.arrayName.length') }}</p>
<card-stack v-for="x in eval(field.title + '.arrayName')" :course="x"></card-stack>

Related

Why v-text is not working to show a String

I tried to show particular string using v-text. But it shows nothing.
Tried code
ccc.handlebars
<div id="app">
<div class="input-group mb-3">
<input type="text" class="form-control" v-text="getValues[0].value">
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
'bulk': {{{bulks}}}
},
computed: {
getValues: function() {
return this.bulk;
}
},
methods: {},
});
</script>
getValues retuens JSON
[
{ name: "Dauth", age: "18", value: "TGFR123" }
]
I want to show TGFR123 in the text box
Above getValues returns the correct JSON. But v-text="getValues[0].value" not shows the string. Help me to solve this.
v-text does not work on input.
If you want to set the value of an input use :value or v-model
var app = new Vue({
el: '#app',
data: {
bulk: [{
name: "Dauth",
age: "18",
value: "TGFR123"
}]
},
computed: {
getValues: function() {
return this.bulk;
}
},
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.0"></script>
<div id="app">
Bind : <input type="text" :value="getValues[0].value">
v-model : <input type="text" v-model="getValues[0].value">
<div>Result : {{getValues[0].value}}</div>
</div>
With v-model the data will be changed with the user input
v-text
value binding
You can use v-model or v-bind:value to insert this value in your input
var app = new Vue({
el: '#app',
data: {
bulk: [{id: 123, name: "Test", value: "NerF21_346"}]
},
computed: {
getValues() {
return this.bulk[0].value
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input type="text" v-model="getValues">
</div>
v-model documentation

Vue-Router doesn't work in a Select Option

I I try to create a simple navigation from a select option but without results.
<router-link> does not work inside <select><option>
Here's what I tried :
vue
<div>
<select v-model="selected">
<option v-for="orga in organisations" :key="orga.name">
<router-link :to="{name: 'Box', params: {orga: orga.route}}">
{{ orga.name }}
</router-link>
</option>
</select>
</div>
javascript
data() {
return {
selected: this.$route.params.orga,
organisations: [
{ name: "Abc", route: "abc" },
{ name: "Lmn", route: "lmn" },
{ name: "Xyz", route: "xyz" }
]
};
}
If you want to change your view based on the select option, you can't use a router-link inside an option tag.
However, you can achieve this by a workaround shown below. Here we will be switching the views based on the select option and changing the route.
Vue.component('compA', {
template: '<div>{{name}}</div>',
data() {
return {
name: 'Component A'
}
}
})
Vue.component('compB', {
template: '<div>{{name}}</div>',
data() {
return {
name: 'Component B'
}
}
})
const routes = [{
path: '/a',
component: {
template: '<compA/>'
}
},
{
path: '/b',
component: {
template: '<compB/>'
}
}
];
const router = new VueRouter({
routes
})
new Vue({
el: "#app",
data() {
return {
selected: ''
}
},
router,
methods: {
routeChange: function(e) {
this.$router.push(e.target.value)
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<div>
<select #change="routeChange">
<option></option>
<option v-for="(c, i) in ['a', 'b']" :key="i">
{{ c }}
</option>
</select>
</div>
<router-view/>
</div>
But this scenario can be alternatively achieved by dynamic components. The docs explains more about this which can be used to switch between components or dynamic render.
Vue.component('CompA', {
template: '<div>new component A</div>'
})
Vue.component('CompB', {
template: '<div>new component B</div>'
})
new Vue({
el: "#app",
data() {
return {
value: ""
}
},
template: `
<div>
<select v-model="value">
<option v-for="c in ['compA', 'compB']">{{c}}</option>
</select>
<component :is="value" />
</div>
`
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<div id="app"></div>

Vue.js and Multiselect - The name 'input' does not exist in the current context

I'm trying to start a method after the value of the component Vue Multiselect has been changed using #input, but I'm getting the following compilation error:
CS0103: The name 'input' does not exist in the current context
Here's my multiselect:
<multiselect v-model="Instalacao.value" label="Serie" track-by="Serie" placeholder="Nº de série" :options="Instalacoes"
:multiple="false" :searchable="true" :allow-empty="false" :disabled="Editando" #input="getTecnicosByRepresentante">
<span slot="noResult">Nenhum técnico encontrado</span>
</multiselect>
This example works as expected: both the watch and the #input handler execute when you select a value. Your problem is probably not in the code that you included here.
new Vue({
el: '#app',
components: {
Multiselect: window.VueMultiselect.default
},
data: {
Instalacao: {
value: null
},
Instalacoes: [{
Serie: 'one',
value: 'Vue.js'
},
{
Serie: 'two',
value: 'Vue-Multiselect'
},
{
Serie: 'three',
value: 'Vuelidate'
}
]
},
watch: {
'Instalacao.value': function(newValue) {
console.log('Updated', newValue);
}
},
methods: {
getTecnicosByRepresentante() {
console.log("Input detected, too");
}
}
})
<script src="https://unpkg.com/vue#latest/dist/vue.js"></script>
<link href="https://unpkg.com/vue-multiselect#latest/dist/vue-multiselect.min.css" rel="stylesheet" />
<script src="https://unpkg.com/vue-multiselect#latest/dist/vue-multiselect.min.js"></script>
<div id="app">
<multiselect v-model="Instalacao.value" label="Serie" track-by="Serie" placeholder="Nº de série" :options="Instalacoes" :multiple="false" :searchable="true" :allow-empty="false" #input="getTecnicosByRepresentante">
<span slot="noResult">Nenhum técnico encontrado</span>
</multiselect>
<pre>{{ Instalacao.value }}</pre>
</div>

VueJs render template issue

I've an issue to fill data from model into code when I'v more then one template with separate data. What I need is first template renders as many times as many objects in firstFormDetails array and same the second one. There example of my code below:
<div id="app">
<first v-for="item in secondFormDetails" track-by="id"></first>
<second v-for="item in firstFormDetails" track-by="id"></second>
</div>
<template id="template-first">
<div> {{ item.docNumber }}</div>
</template>
<template id="template-second">
<div> {{ item.docNumber }}</div>
</template>
And VueJs module as follows:
Vue.component('first', {
template: '#template-first',
data: function() {
return {
firstFormDetails: [
{docNumber: 7},
{docNumber: 7777},
{docNumber: 10000}
]
}
}
});
Vue.component('second', {
template: '#template-second',
data: function() {
return {
secondFormDetails: [
{docNumber: 1908},
{docNumber: 7777},
{docNumber: 10000}
]
}
}
});
new Vue({
el: '#app'
});
#vbranden is correct, move the v-for into the component
<template id="template-first">
<div v-for="item in firstFormDetails"> {{ item.docNumber }}</div>
</template>
<template id="template-second">
<div v-for="item in secondFormDetails"> {{ item.docNumber }}</div>
</template>
You must define what components you use. Let try to use this:
var first = Vue.component('first', {
template: '#template-first',
data: function() {
return {
firstFormDetails: [
{docNumber: 7},
{docNumber: 7777},
{docNumber: 10000}
]
}
}
});
var second = Vue.component('second', {
template: '#template-second',
data: function() {
return {
secondFormDetails: [
{docNumber: 1908},
{docNumber: 7777},
{docNumber: 10000}
]
}
}
});
new Vue({
el: '#app',
components: {
'first': first,
'second': second
}
});
in addition on #johnnynotsolucky 's answer, you will need a wrapper element out of v-for, since only allow only one element inside it.
<template id="template-first">
<div class="form-details">
<div v-for="item in firstFormDetails"> {{ item.docNumber }}</div>
</div>
</template>
var first = Vue.component('first', {
template: '#template-first',
props: ['item']
});
var second = Vue.component('second', {
template: '#template-second',
props: ['item']
});
new Vue({
el: '#app',
components: {
'first': first,
'second': second
},
data: function () {
return {
firstFormDetails: [
{docNumber: 7},
{docNumber: 7777},
{docNumber: 10000}
],
secondFormDetails: [
{docNumber: 1908},
{docNumber: 7777},
{docNumber: 10000}
]
}
}
});
<div id="app">
<first v-for="item in secondFormDetails" :item="item"></first>
<second v-for="item in firstFormDetails" :item="item"></second>
</div>
<template id="template-first">
<div> {{ item.docNumber }}</div>
</template>
<template id="template-second">
<div> {{ item.docNumber }}</div>
</template>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.min.js"></script>
When Vue app is loaded, it looks for component field, if component field is not defined then not component is loaded, if component field is defined, Vue looks for the definition of the component and parse it for syntax checking, once the syntax is correct the component is binded. This happens recursively for nested components.
Registering a component is mandatory

Binding div value to event handler

Is it possible to bind the div value 1 or 2 to implicitly pass it to getValue instead of the manual assignments below?
<div id="app">
{{value}}
<div #click="getValue(1)">1</div>
<div #click="getValue(2)">2</div>
</div>
new Vue({
el: 'app',
data: {
value: ''
},
methods: {
getValue: (v) => this.value = v
}
})
<div id="app">
{{value}}
<div #click="getValue">1</div>
<div #click="getValue">2</div>
</div>
new Vue({
el: 'app',
data: {
value: ''
},
methods: {
getValue: (event) => this.value = event.target.textContent
}
})
If the actual content of the div is hardcoded, I guess that the call will be hardcoded too...
You could try:
<div id="app">
{{value}}
<div v-for="val in values" #click="getValue(val)">{{ val }}</div>
</div>
And then:
new Vue({
el: 'app',
data: {
value: '',
values: [1, 2]
},
methods: {
getValue: (v) => this.value = v
}
})