link959 link960 link961 link962 link963 link964 link965 link966 link967 link968 link969 link970 link971 link972 link973 link974 link975 link976 link977 link978 link979 link980 link981 link982 link983 link984 link985 link986 link987 link988 link989 link990 link991 link992 link993 link994 link995 link996 link997 link998 link999 link1000 link1001 link1002 link1003 link1004 link1005 link1006 link1007 link1008 link1009 link1010 link1011 link1012 link1013 link1014 link1015 link1016 link1017 link1018 link1019 link1020 link1021 link1022 link1023 link1024 link1025 link1026 link1027 link1028 link1029 link1030 link1031 link1032 link1033 link1034 link1035 link1036 link1037 link1038 link1039 link1040 link1041 link1042 link1043 link1044 link1045 link1046 link1047 link1048 link1049 link1050 link1051 link1052 link1053 link1054 link1055 link1056 link1057 link1058 link1059 link1060 link1061 link1062 link1063 link1064 link1065 link1066 link1067 link1068 link1069 link1070 link1071 link1072 link1073 link1074 link1075 link1076 link1077 link1078 link1079 link1080 link1081 link1082 link1083 link1084 link1085 link1086 link1087 link1088 link1089 link1090 link1091 link1092 link1093 link1094 link1095

[Vue.js] the search stopped working after adding it to a separate component

I had a page on which there was a header with an input that was a search engine, a list of posts, and pagination. I decided to move the header from this file to a separate component in a separate vue.js file. After I did this, the search for posts by title stopped working, and I cant add a post now either. I think that I need to import my posts into a new file for my newly created component but how to do it.

And here is the code how it looked before my changes

Header.vue:

<template>
<div class=”header”>
<input type=”text” v-model=”search” class=”header_input_search” placeholder=”Search” />
<img src=”src/assets/milk.png”>
<div class=”header_div_inputs”>
<input type=”text” v-model=”createTitle” class=”created”/>
<p><input type=”text” v-model=”createBody” class=”createBody”/></p>
</div>
<button @click=”addPost()” class=”addPost”>AddPost</button>
</div>
</template>

<script>
import axios from ‘axios’;
export default {
name: ‘Pagination’,
data () {
return {
search: ‘’,
current: null,
posts: [],
createTitle: ‘’,
createBody: ‘’,
}
},
created(){
this.getData()
},
methods: {
getData() {
axios.get(`https://jsonplaceholder.typicode.com/posts\`).then(response => {
this.posts = response.data
})
},
addPost() {
axios.post(‘http://jsonplaceholder.typicode.com/posts/', {
title: this.createTitle,
body: this.createBody
}).then((response) => {
this.posts.unshift(response.data)
})
},
}
}
</script>

App.vue:

<template>
<div id=”app”>
<header-self></header-self>
<router-view></router-view>
</div>
</template>

<script>

export default {
components: {
name: ‘app’,
}
}
</script>

The file in which my posts lie:

<template>
<div class=”app”>
<ul>
<li v-for=”(post, index) in paginatedData” class=”post” :key=”index”>
<router-link :to=”{ name: ‘detail’, params: {id: post.id, title: post.title, body: post.body} }”>
<img src=”src/assets/nature.jpg”>
<p class=”boldText”> { post.title }</p>
</router-link>
<p> { post.body }</p>

</li>

</ul>
<div class=”allpagination”>
<button type=”button” @click=”page -=1” v-if=”page > 0” class=”prev”><<</button>
<div class=”pagin”>
<button class=”item”
v-for=”n in evenPosts”
:key=”n.id”
v-bind:class=”{‘selected’: current === n.id}”
@click=”page=n-1”>{ n } </button>
</div>
<button type=”button” @click=”page +=1” class=”next” v-if=”page < evenPosts-1”>>></button>
</div>

</div>
</template>

<script>
import axios from ‘axios’;
export default {
name: ‘Pagination’,
data () {
return {
search: ‘’,
current: null,
page: 0,
posts: [],
createTitle: ‘’,
createBody: ‘’,
visiblePostID: ‘’,
}
},
watch: {
counter: function(newValue, oldValue) {
this.getData()
}
},
created(){
this.getData()
},
computed: {
evenPosts: function(posts){
return Math.ceil(this.posts.length/6);
},

paginatedData() {
const start = this.page * 6;
const end = start + 6;
return this.posts.filter((post) => {
return post.title.match(this.search);
}).slice(start, end);
},
},
methods: {
getData() {
axios.get(`https://jsonplaceholder.typicode.com/posts\`).then(response => {
this.posts = response.data
})
},

}
}
</script>

Solution :

You have a computed property paginatedData in the Pagination.vue.js component that relies on a search data value but this value is not updated in that component because you moved the search input that populates that value out of that component.

What you need to do now is make sure that the updated search value is passed to the Pagination.vue.js component so that the computed property detects the change and computes the new paginatedData value.

You’re now encountering the need to pass values between components that may not have a parent/child relationship.

In the scenario, I would look at handling this need with some Simple State Management as described in the vue.js docs.

Depending on the scale of you app it may be worth implementing Vuex for state management.

Good luck!

[Vue.js] Problem when creating a menu by iteration

I’m new to vue.js and vuetify. I need to create a submenu and for that when using v-menu. Its construction is by iteration, where I need each sub menu to assign it a method. But it turns out that the way I’m doing it generates an error
[vue.js warn]: Error in v-on handler: ‘TypeError: handler.apply is not a function’
. What am I doing wrong?
https://codepen.io/maschfederico/pen/vMWBPV?editors=1011

<div id=”app”>
<v-app id=”inspire”>
<div class=”text-xs-center”>
<v-menu>
<template #activator=”{ on: menu }”>
<v-tooltip bottom>
<template #activator=”{ on: tooltip }”>
<v-btn
color=”primary”
dark
v-on=”{ …tooltip, …menu }”
\>Dropdown w/ Tooltip</v-btn>
</template>
<span>Im A ToolTip</span>
</v-tooltip>
</template>
<v-list>
<v-list-tile
v-for=”(item, index) in items”
:key=”index”
@click=”item.f”
\>
<v-list-tile-title>{ item.title }</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</div>
</v-app>
</div>
new Vue({
el: ‘#app’,
data: () => ({
items: [
{ title: ‘Click Me1’,f:’login’},
{ title: ‘Click Me2’,f:’login’ },
{ title: ‘Click Me3’,f:’login’ },
{ title: ‘Click Me4’ ,f:’login’ }
]
}),
methods: {
login(){console.log(‘login’)}
}
})

Solution :

Try to pass the method name to another one and handle it inside the last one like :

<v-list-tile
v-for=”(item, index) in items”
:key=”index”
@click=”handle(item.f)”
\>

inside the methods :

methods: {
handle(f){
this[f]();
},
login(){console.log(‘login’)}
}

check this codepen

Solution 2:

You are passing the method’s name - a string - instead of a function. The click event listener generated by vue.js is trying to call a function using apply, this is why you are getting that error.

One solution would be to pass directly the function when the vue.js instance is created (before that, the method might not be available, so passing it directly to the data { title: ‘Click Me1’, f: this.login } would not work).

For example, you could keep having method names in the data, and replace them with the actual methods at create:

new Vue({
el: ‘#app’,
data: () => ({
items: [
{ title: ‘Click Me1’, f: ‘login’ }
]
}),
created () {
this.items.forEach(item => {
item.f = this[item.f]
})
},
methods: {
login (){
console.log(‘login’)
}
}
})

[Vue.js] Need for vuex for 2 components

there is just 2 Components at any given point in time
a global component to store all the common data
and a child component which changes based on vue-router.

Is there a real need to add vuex complexity in my case.

Solution :

I don’t think you’ll benefit from Vuex in this case.

You can just use props and custom events.

[Vue.js] Vuejs updating the child component when updating parent data

there is a component that displays a detailed description of a person, this component has a table displaying his technique, I need to update (redraw) this table when I press the button

<template>
<div class=”animated fadeIn”>
<b-row>
<b-col xs=”12” lg=”12”>
<b-card>
<div slot=”header”>
Person:
<strong>Name</strong>
<b-button @click=”Update”></b-button>
</div>
<b-row>
<TransactionsTable ref=”TransactionsTable”/>
</b-row>
</b-card>
</b-col>
</b-row>

</div>
</template>

<script>
import TransactionsTable from “./TransactionsTable.vue”;

export default {
components: {
TransactionsTable
},
methods: {
Update() {
this.$refs.TransactionsTable.$forceUpdate();
}
},
};
</script>

Solution :

Because the TransactionsTable seems to manage it’s own state, instead of calling .$forceUpdate(), add a method to TransactionsTable. Call that from the parent, and then mutate the state within the TransactionsTable method.

You should really never need to call $forceUpdate if you wire things up correctly.

[Vue.js] Vue Component Props are not being updated

In my data there is an object program. I load a list of objects asynchronously and add it to program.sections.

async loadSections() {
if (this.user == null && this.program.sections) { return }
await this.$store.dispatch(‘loadProgramSections’, {program: this.program, user: this.user});
console.log(‘loaded Sections’, this.program);

// this.$set(this.program, ‘sections’, this.progrmm.sections)
// this.$nextTick(() => { this.$forceUpdate(); })
},

My UI looks like this:

<Section :program=”program” ></Section>

So I pass my program object down to my Sections component

In my console log I can see that the field programm.sections is indeed my array of objects but my UI does not get changed. When I put my UI code from the Sections component directly in to my page, it gets updated and the data is dispalyed correctly but when I use the component the props are not being updated correctly.

I already tried the commented lines in my code but it doesn’t work.

Any Ideas?

Solution :

Assign a new object reference in this.program:

async loadSections() {
if (this.user == null && this.program.sections) { return }
await this.$store.dispatch(‘loadProgramSections’, {program: this.program, user: this.user});
console.log(‘loaded Sections’, this.program);

// assign a new object reference
this.program = Object.asssign({}, this.program);
},

Also make sure you initialize program in data() section.

Solution 2:

The main issue is that vue.js cannot detect the changes in some situations.

e.g. set a item to an array or set an additional property to an object

That’s the crux of the problem. You might need Caveats.

[Vue.js] VUEJS Call a function in function (axios)

When I call this.func1() in func2, func1 return undefined.
Someone for help me please ?
I think the func return nothing because axios is not finished, how can I fix this ?

func1:function(val){
if(val.x == 0)
{
axios.post(‘/…’, {

})
.then((response) => {
if(response.data == 0)
{
return true;
}
else
{
return false
}
})
.catch((error) => {
return false;
});
}
else
{
return false;
}
}

//////
//////
//////

func2:function(variable){
console.log(this.func1(variable)) // undefined..
if(this.func1(variable) == true)
{

}
}

Solution :

what about instead add function 2 inside function 1 to call syncs.

func2:function(variable){
console.log(this.func1(variable)) // undefined..

func1:function(val){
if(val.x == 0)
{
axios.post(‘/…’, {

})
.then((response) => {
if(response.data == 0)
{
return true;
}
else
{
return false
}
})
.catch((error) => {
return false;
});
}
else
{
return false;
}

}
}

[Vue.js] Adjust the select box when option value is bigger using element ui

Adjust the select box when option value is bigger using element ui

How this is possible please guide

It should not cut the string after selection

<template>
<el-select v-model=”value” placeholder=”Select”>
<el-option
v-for=”item in options”
:key=”item.value”
:label=”item.label”
:value=”item.value”>
</el-option>
</el-select>
</template>
</div>

var Main = {
data() {
return {
options: [{
value: ‘OptionFirstWithBigCharacter’,
label: ‘OptionFirstWithBigCharacter’
}, {
value: ‘Option2’,
label: ‘Option2’
}, {
value: ‘Option3’,
label: ‘Option3’
}, {
value: ‘Option4’,
label: ‘Option4’
}, {
value: ‘Option5’,
label: ‘Option5’
}],
value: ‘’
}
}
}
var Ctor = Vue.extend(Main)
new Ctor().$mount(‘#app’)
@import url(“//unpkg.com/element-ui@2.7.2/lib/theme-chalk/index.css”);
<script src=”//unpkg.com/vue/dist/vue.js”></script>
<script src=”//unpkg.com/element-ui@2.7.2/lib/index.js”></script>
<div id=”app”>
<template>
<el-select v-model=”value” placeholder=”Select”>
<el-option
v-for=”item in options”
:key=”item.value”
:label=”item.label”
:value=”item.value”>
</el-option>
</el-select>
</template>
</div>

“OptionFirstWithBigCharacter” should display properly

Solution :

Add some padding to the select input as follows :

.el-select>.el-input {
display: block;
padding-right: 2px;
}

var Main = {
data() {
return {
options: [{
value: ‘OptionFirstWithBigCharacter’,
label: ‘OptionFirstWithBigCharacter’
}, {
value: ‘Option2’,
label: ‘Option2’
}, {
value: ‘Option3’,
label: ‘Option3’
}, {
value: ‘Option4’,
label: ‘Option4’
}, {
value: ‘Option5’,
label: ‘Option5’
}],
value: ‘’
}
}
}
var Ctor = Vue.extend(Main)
new Ctor().$mount(‘#app’)
@import url(“//unpkg.com/element-ui@2.7.2/lib/theme-chalk/index.css”);
.el-select>.el-input {
display: block;
padding-right: 8px;
}
<script src=”//unpkg.com/vue/dist/vue.js”></script>
<script src=”//unpkg.com/element-ui@2.7.2/lib/index.js”></script>
<div id=”app”>
<template>
<el-select v-model=”value” placeholder=”Select”>
<el-option
v-for=”item in options”
:key=”item.value”
:label=”item.label”
:value=”item.value”>
</el-option>
</el-select>
</template>
</div>

Solution 2:

That’s an interesting question.

Obviously, the solution would be to calculate the text width of selected value and adjust select to this width, but that’s a tricky task.

Under the hood el-select uses <input> element to show selected item, and <input> can’t adjust its width based on its value, so we’d need to use another element that can do that. For example, <span> is good choice.

Here is what I’ve got:

Vue.config.productionTip = false;

var Main = {
data() {
return {
options: [{
value: ‘OptionFirstWithBigCharacter’,
label: ‘OptionFirstWithBigCharacter’
}, {
value: ‘Option2’,
label: ‘Option2’
}, {
value: ‘Option3’,
label: ‘Option3’
}, {
value: ‘Option4’,
label: ‘Option4’
}, {
value: ‘Option5’,
label: ‘Option5’
}],
value: ‘’
}
},
mounted() {
// pass true to make input use its initial width as min-width
this._addShadow();
},
methods: {
_getElements() {
// helper method to fetch input and its shadow span
const input = this.$refs.resizeable.$el.querySelector(‘.el-input__inner’);
const span = input.previousSibling;;
return { input, span };
},
_addShadow(useMinWidth = false) {
// this method adds shadow span to input
// we’ll use this span to calculate text width
const { input } = this._getElements();
const span = document.createElement(‘span’);
span.classList.add(‘resizeable-shadow’);
input.parentNode.insertBefore(span, input);

// copy font, padding and border styles from input
const css = input.computedStyleMap();
span.style.font = css.get(‘font’);
span.style.padding = css.get(‘padding’);
span.style.border = css.get(‘border’);
if (useMinWidth) {
span.style.minWidth = `${input.getBoundingClientRect().width}px`;
}
},
_adjustSize() {
this.$nextTick(() => {
const { input, span } = this._getElements();
span.textContent = input.value;
input.style.width = `${span.getBoundingClientRect().width}px`;
});
},
},
}
var Ctor = Vue.extend(Main)
new Ctor().$mount(‘#app’)
@import url(“//unpkg.com/element-ui@2.7.2/lib/theme-chalk/index.css”);

span.resizeable-shadow {
display: inline-block;
box-sizing: border-box;
position: absolute;
left: -99999px;
top: -99999px;
}
<script src=”//unpkg.com/vue/dist/vue.js”></script>
<script src=”//unpkg.com/element-ui@2.7.2/lib/index.js”></script>
<div id=”app”>
<template>
<el-select v-model=”value” placeholder=”Select”
ref=”resizeable” @change=”_adjustSize”>
<el-option
v-for=”item in options”
:key=”item.value”
:label=”item.label”
:value=”item.value”>
</el-option>
</el-select>
</template>
</div>

Code is pretty simple and I’ve added some comments, so it shouldn’t be hard to adjust it to the needs: move it to mixin, add support for multiple selects etc.

Popper works weird in SO snippet, so here is working jsfiddle.

[Vue.js] Vue.js img src concatenate variable and text

to concatenate Vue.js variable with image URL.

What I computed:

imgPreUrl : function() {
if (androidBuild) return “android_asset/www/“;
else return “”;
}

If I build for android:

<img src=”/android_asset/www/img/logo.png”>

Else

<img src=”img/logo.png”>

How can I concatenate the computed variable with the URL?

I tried it:

<img src=”{imgPreUrl}img/logo.png”>

Solution :

You can’t use curlies (moustache tags) in attributes. Use the following to concat data:

<img v-bind:src=”imgPreUrl + ‘img/logo.png’”>

Or the short version:

<img :src=”imgPreUrl + ‘img/logo.png’”>

Read more on dynamic attributes in the vue.js docs.

Solution 2:

In another case I’m able to use template literal ES6 with backticks,
so for yours could be set as:

<img v-bind:src=”`${imgPreUrl()}img/logo.png`“>

Solution 3:

just try

<img :src=”require(`${imgPreUrl}img/logo.png`)”>

[Vue.js] how to import wavesurfer in nuxt.js?

to use wawesurfer plugin for audio visualization in nuxt.js framework.

but i don’t know how to import and use it?
my application is in universal(ssr) mode.

if i import it like this:

import WaveSurfer from ‘wavesurfer.js’;

its give me error that windows is not defined

if i create a plugin in plugin directory and import it and add it to nuxt.config.js in plugins section, it doesn’t work and it’s give me this error message:
wawesurfer is not defined

what should i do?

Solution :

if (process.browser) {
var WaveSurfer = require(‘wavesurfer.js’);
}

[Vue.js] How to prevent user to leave page using middleware in Nuxt?

I got a Nuxt application, and in some special route, to prevent user from leaving the page by showing plain confirm javascript dialog.

I did some beforeRouteLeave <- this kinda thingy introduced in the vue.js official documentation, but none of them seemed work in Nuxt.

And Nuxt recommends users to use middleware for doing this ‘beforeRoute’ things. Here’s my code.

export default function (context) {
if (process.client &&
context.from.path.includes(“board/write”) &&
context.route.name !== “board-articleId”) {
if (!confirm(“Are you sure you want to leave the page?”)) {
context.next(false)
}
}
}

As you can see, I’m checking if my current route is certain page (context.from.path…), ask user if user wants to leave the page. And if they canceled, which makes confirm as false, do

next(false)

and it works fine as it makes the user stay on the page.

But the problem is, the loading bar of the browser still loads even if the page doesn’t change. And it looks like the route is still changing anyway despite the actual page doesn’t change.

How can I prevent this to happen?

Solution :

I could have used

redirect(from.path)

instead of

next(false)

For the sake of information,
the incoming argument ‘context’ has some properties like below:

from, route, next, redirect…