I have been struggling this error for a while now. I've tried multiple ways and none of them work. All I am trying to do is to get this simple component working. Someone help please. :)
<script>
const app = new Vue({
el: "#main",
data: function(){
return {
search: '',
customers: [
{ id: '1', name: 'Something', },
{ id: '2', name: 'Something else', },
{ id: '3', name: 'Something random', },
{ id: '4', name: 'Something crazy', }
]};
},
computed:
{
filteredCustomers:function()
{
var self=this;
return this.customers.filter(function(cust){return cust.name.toLowerCase().indexOf(self.search.toLowerCase())>=0;});
//return this.customers;
}
}
});
</script>
<template>
<div id="main">
Search: <input type="text" v-model="search"/>
<div v-bind:v-for="customer in filteredCustomers">
<span>{{customer.name}}</span>
</div>
</div>
</template>
You should include the Vue library.
One way of doing so is including using <script> as described in Vue's documentation.
Related
I'm using Vue.js 2 and I'm trying to update the description of a file using an input in a child component. I've been reading a few related questions and read some of the official docs along with .sync but I'm struggling to get the result I want since files is a list of objects.
Here's what I've been trying.
Vue.component('myComponent', {
props: ["file"],
data() {
return {
myDescription: '',
}
},
mounted() {
this.myDescription = this.file.description;
},
template: `
<div>
<label>{{ file.name }}</label>
<br>
<input type="text" #input="update" :value="myDescription"></input>
<br><br>
</div>
`,
methods: {
update() {
this.$emit("update-description", this.myDescription, this.file);
},
}
})
var app = new Vue({
el: '#app',
methods: {
updateDescription(description, file) {
console.log(description);
}
},
data: {
files: [{
id: 1,
name: "Hello",
description: "",
},
{
id: 2,
name: "World",
description: "Foo",
},
{
id: 3,
name: "John",
description: "Bar",
}
]
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div> {{ files }} </div>
<br>
<my-component v-for="file in files" :key="file.id" :file="file" #update-description="updateDescription" />
</div>
You're almost there, you can see in the code you've provided that the child component event is being emitted but the value is empty. The problem is you're not updating myDescription, if you change your :value to v-model then it will update, as v-model uses two way binding.
Also, if you want to update the file description, you can just do:
file.description = description;
Vue.component('myComponent', {
props: ["file"],
data() {
return {
myDescription: '',
}
},
mounted() {
this.myDescription = this.file.description;
},
template: `
<div>
<label>{{ file.name }}</label>
<br>
<input type="text" #input="update" v-model="myDescription"></input>
<br><br>
</div>
`,
methods: {
update() {
this.$emit("update-description", this.myDescription, this.file);
},
}
})
var app = new Vue({
el: '#app',
methods: {
updateDescription(description, file) {
console.log(description);
file.description = description;
}
},
data: {
files: [{
id: 1,
name: "Hello",
description: "",
},
{
id: 2,
name: "World",
description: "Foo",
},
{
id: 3,
name: "John",
description: "Bar",
}
]
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div> {{ files }} </div>
<br>
<my-component v-for="file in files" :key="file.id" :file="file" #update-description="updateDescription" />
</div>
I am using vue js multiselect library for multiselect library. I am using the sub group functionality.
. I want the functionality to allow only one option selection from one group. For example if I select vue js from javascript group, I shouldn't be allowed to select adonis for the given JS fiddle or else if I selelct vue js and then select adonis, then vue js should be deselected. Any help will be much appreciated. Thanks in advance
Example JS fiddle https://jsfiddle.net/bgarrison25/tndsmkq1/4/
new Vue({
components: {
Multiselect: window.VueMultiselect.default
},
data () {
return {
options: [
{
language: 'Javascript',
libs: [
{ name: 'Vue.js', category: 'Front-end' },
{ name: 'Adonis', category: 'Backend' }
]
},
{
language: 'Ruby',
libs: [
{ name: 'Rails', category: 'Backend' },
{ name: 'Sinatra', category: 'Backend' }
]
},
{
language: 'Other',
libs: [
{ name: 'Laravel', category: 'Backend' },
{ name: 'Phoenix', category: 'Backend' }
]
}
],
value: [
{ name: 'Laravel', category: 'Backend' },
{ name: 'Phoenix', category: 'Backend' }
]
}
}
}).$mount('#app')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link href="https://unpkg.com/vue-multiselect#2.1.4/dist/vue-multiselect.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/vue-multiselect#2.1.4/dist/vue-multiselect.min.js"></script>
<div id="app">
<label class="typo__label">Groups</label>
<multiselect
v-model="value"
:options="options"
:multiple="true"
group-values="libs"
group-label="language"
:group-select="true"
placeholder="Type to search"
track-by="name"
label="name">
<span slot="noResult">Oops! No elements found. Consider changing the search query.</span>
</multiselect>
<pre class="language-json"><code>{{ value }}</code></pre>
</div>
You could try something like this below, it's a bit overly complicated for what it does, but could work well in its own component.
Basically on the input event you can search to see if there are any others in that group and then select accordingly.
new Vue({
components: {
Multiselect: window.VueMultiselect.default
},
methods: {
selectUnique(ev) {
if (!ev || ev.length < this.value.length) {
this.value = ev;
return;
}
let newValue = ev.filter(x => this.value.indexOf(x) === -1)[0];
let group = this.getGroupByLib(newValue);
if (this.value.some(x => this.getGroupByLib(x) === group)) {
this.value = this.value.filter(x => this.getGroupByLib(x) !== group);
this.value.push(newValue);
} else
this.value = ev;
},
getGroupByLib(lib) {
return this.options.filter(x => x.libs.some(y => y.name === lib.name))[0].language;
}
},
data() {
return {
options: [{
language: 'Javascript',
libs: [{
name: 'Vue.js',
category: 'Front-end'
},
{
name: 'Adonis',
category: 'Backend'
}
]
},
{
language: 'Ruby',
libs: [{
name: 'Rails',
category: 'Backend'
},
{
name: 'Sinatra',
category: 'Backend'
}
]
},
{
language: 'Other',
libs: [{
name: 'Laravel',
category: 'Backend'
},
{
name: 'Phoenix',
category: 'Backend'
}
]
}
],
value: []
}
}
}).$mount('#app')
* {
font-family: 'Lato', 'Avenir', sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vue-multiselect#2.1.0"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-multiselect#2.1.0/dist/vue-multiselect.min.css">
<div id="app">
<label class="typo__label">Groups</label>
<multiselect :value="value" :options="options" :multiple="true" group-values="libs" group-label="language" placeholder="Type to search" track-by="name" label="name" #input="selectUnique">
<span slot="noResult">Oops! No elements found. Consider changing the search query.</span>
</multiselect>
<pre class="language-json"><code>{{ value }}</code></pre>
</div>
Make these two things into false
:multiple="false" :group-select="false"
Check Here Code
I am new in Vue and still learning using it. I've been following example from this page: https://vue.ant.design/components/table/
I'm trying to fetch data using json to be displayed using Antd Tables.
But I include the js and css manually using and .
The data calling is fine as i can see from the console logged. But the table is not displaying any records.
I've been trying to code in here:
https://jsfiddle.net/dedychaidir/yvr5o8Lk/4/
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ant-design-vue#1.3.13/dist/antd.css" />
<script src="https://unpkg.com/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/ant-design-vue#1.3.13/dist/antd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-resource#1.5.1"></script>
<div id="app">
<template>
<a-table :columns="columns" :rowKey="record => record.login.uuid" :dataSource="data" :pagination="pagination" :loading="loading" #change="handleTableChange">
<template slot="name" slot-scope="name">
{{name.first}} {{name.last}}
</template>
</a-table>
</template>
</div>
And this is the script section:
const columns = [{
title: 'Name',
dataIndex: 'name',
sorter: true,
width: '20%',
scopedSlots: {
customRender: 'name'
},
}, {
title: 'Gender',
dataIndex: 'gender',
filters: [{
text: 'Male',
value: 'male'
},
{
text: 'Female',
value: 'female'
},
],
width: '20%',
}, {
title: 'Email',
dataIndex: 'email',
}];
var app = new Vue({
el: "#app",
mounted: function() {
this.fetch();
},
data: function() {
return {
data: [],
pagination: {},
loading: false,
columns,
}
},
methods: {
handleTableChange(pagination, filters, sorter) {
console.log(pagination);
const pager = {
...this.pagination
};
pager.current = pagination.current;
this.pagination = pager;
this.fetch({
results: pagination.pageSize,
page: pagination.current,
sortField: sorter.field,
sortOrder: sorter.order,
...filters,
});
},
fetch(params = {}) {
this.loading = true;
this.$http.get('https://randomuser.me/api',{params:{results:"10"}}).then(response => {
json = JSON.parse(response.bodyText);
const pagination = {
...this.pagination
};
pagination.total = 200;
this.loading = false;
this.data = json.results;
this.pagination = pagination;
console.log(this.data);
}, response => {
console.log(response.body);
});
},
},
});
Please show me if there are some error or mistakes.
Thank you.
I made codesandbox for you with provided code and everything works.
https://codesandbox.io/embed/vue-template-pluqh
Not sure, but maybe you just need to remove first <template> tag inside div#app because its not neccessary
I have this fiddle:
https://jsfiddle.net/pnqzspoe/12014/
I want to modify it a bit and want to display each node as a text area containing the corresponding text. Further, I want to give an option to 'reply' to it. This would mean insertion of a new text area into which we can enter text.
Here is the code:
<script type="text/x-template" id="item-template">
<li>
<div
:class="{bold: isFolder}"
#click="toggle"
#dblclick="changeType">
{{ model.name }}
<span v-if="isFolder">[{{ open ? '-' : '+' }}]</span>
</div>
<ul v-show="open" v-if="isFolder">
<item
class="item"
v-for="(model, index) in model.children"
:key="index"
:model="model">
</item>
<li class="add" #click="addChild">+</li>
</ul>
</li>
</script>
<p>(You can double click on an item to turn it into a folder.)</p>
var data = {
name: 'My Tree',
children: [
{ name: 'hello' },
{ name: 'wat' },
{
name: 'child folder',
children: [
{
name: 'child folder',
children: [
{ name: 'hello' },
{ name: 'wat' }
]
},
{ name: 'hello' },
{ name: 'wat' },
{
name: 'child folder',
children: [
{ name: 'hello' },
{ name: 'wat' }
]
}
]
}
]
}
// define the item component
Vue.component('item', {
template: '#item-template',
props: {
model: Object
},
data: function () {
return {
open: false
}
},
computed: {
isFolder: function () {
return this.model.children &&
this.model.children.length
}
},
methods: {
toggle: function () {
if (this.isFolder) {
this.open = !this.open
}
},
changeType: function () {
if (!this.isFolder) {
Vue.set(this.model, 'children', [])
this.addChild()
this.open = true
}
},
addChild: function () {
this.model.children.push({
name: 'new stuff'
})
}
}
})
// boot up the demo
var demo = new Vue({
el: '#demo',
data: {
treeData: data
}
})
What would be the template for this use-case?
If I don't understand your question wrongly...
Replace
{{model.name}}
with
<textarea v-model="model.name"></textarea>
should work?
I have created for loop which works but for some reason the show/hide part does not work and no matter what I just can't figure out why.
<div id="app">
<ul>
<li v-for="club in clubs" v-on:click="toggleDetails(clubs)">
<h1>{{club.name}}</h1>
<div v-show="clubs.showDetail">
<p>{{club.location}}</p>
<p>{{club.members}}</p>
</div>
</li>
</ul>
</div>
and for the JS part I have the following;
const clubs = [
{
name: 'Tigers',
location: 'Manchester',
members: '22'
},
{
name: 'Dolphins',
location: 'Miami',
members: '19'
},
{
name: 'Bleu Sox',
location: 'Paris',
members: '13'
}
];
const app = new Vue({
el: '#app',
data: {
title: 'Here is a list',
club: clubs
},
methods: {
toggleDetails: function(clubs) {
clubs.showDetail = !clubs.showDetail;
}
}
});
If you need to show detail on each club separately, you need to set a property on each club separately instead of on clubs; Also use Vue.set to reactively add a new property to an object as follows:
const clubs = [
{
name: 'Tigers',
location: 'Manchester',
members: '22'
},
{
name: 'Dolphins',
location: 'Miami',
members: '19'
},
{
name: 'Bleu Sox',
location: 'Paris',
members: '13'
}
];
const app = new Vue({
el: '#app',
data: {
title: 'Here is a list',
clubs
},
methods: {
toggleDetails: function(club) {
this.$set(club, 'showDetails', !club.showDetails)
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.21/dist/vue.js"></script>
<div id="app">
<ul>
<li v-for="club in clubs" v-on:click="toggleDetails(club)">
<h1>{{club.name}}</h1>
<div v-show="club.showDetails">
<p>{{club.location}}</p>
<p>{{club.members}}</p>
</div>
</li>
</ul>
</div>