link2877 link2878 link2879 link2880 link2881 link2882 link2883 link2884 link2885 link2886 link2887 link2888 link2889 link2890 link2891 link2892 link2893 link2894 link2895 link2896 link2897 link2898 link2899 link2900 link2901 link2902 link2903 link2904 link2905 link2906 link2907 link2908 link2909 link2910 link2911 link2912 link2913 link2914 link2915 link2916 link2917 link2918 link2919 link2920 link2921 link2922 link2923 link2924 link2925 link2926 link2927 link2928 link2929 link2930 link2931 link2932 link2933 link2934 link2935 link2936 link2937 link2938 link2939 link2940 link2941 link2942 link2943 link2944 link2945 link2946 link2947 link2948 link2949 link2950 link2951 link2952 link2953 link2954 link2955 link2956 link2957 link2958 link2959 link2960 link2961 link2962 link2963 link2964 link2965 link2966 link2967 link2968 link2969 link2970 link2971 link2972 link2973 link2974 link2975 link2976 link2977 link2978 link2979 link2980 link2981 link2982 link2983 link2984 link2985 link2986 link2987 link2988 link2989 link2990 link2991 link2992 link2993 link2994 link2995 link2996 link2997 link2998 link2999 link3000 link3001 link3002 link3003 link3004 link3005 link3006 link3007 link3008 link3009 link3010 link3011 link3012 link3013

[Vue.js] Vue, child component says that props are undefined on view change

I’m doing a sample vue.js app. I implemented a form that will be used for both create and update operations.

<template>
<div>
<div class=”row”>
<div class=”col-md-6”>
<div class=”form-group”>
<label>Post Title:</label>
<input type=”text” class=”form-control” v-model=”post.title”>
<div v-if=”errors[‘post.title’]“ class=”invalid-feedback”>
{errors[‘post.title’].join(‘ ‘)}
</div>
</div>
</div>
</div>
<div class=”row”>
<div class=”col-md-6”>
<div class=”form-group”>
<label>Post Body:</label>
<textarea class=”form-control” v-model=”post.body” rows=”5”></textarea>
<div v-if=”errors[‘post.body’]“ class=”invalid-feedback”>
{errors[‘post.body’].join(‘ ‘)}
</div>
</div>
</div>
</div>
<br />
<div class=”form-group”>
<button class=”btn btn-primary”>Create</button>
</div>
</div>
</template>

<script>
export default {
props: [‘post’, ‘errors’]
}
</script>

When the parent component, does a router.push(‘/another-route’); the child component throws an error that the post model is undefined.

The parent component is the following:

<template>
<div class=”row justify-content-center”>
<div class=”col-md-8”>
<div class=”card card-default”>
<div class=”card-header”>
Create Post
</div>
<div class=”card-body”>
<form @submit.prevent=”handlePostCreate”>
<PostForm v-bind:post=”post” v-bind:errors=”errors”/>
</form>
</div>
</div>
</div>
</div>
</template>

<script>
import Post from ‘./../../models/Post’;
import PostForm from ‘./../../components/forms/PostForm’;
import PostService from ‘./../../services/PostService’;
export default {
data() {
return {
post: new Post(),
postService: new PostService(),
errors: {}
}
},
methods: {
handlePostCreate() {
this.postService.store(this.post)
.then(res => {
router.push(‘/posts’);
})
.catch(err => {
this.errors = err.errors;
});
}
},
components: {
PostForm
}
}
</script>

I tried to add some default props but It does not work.

props: {
post: {
title: ‘’,
‘body’: ‘’
},
errors: {

}
}

Does anyone have some idea of how I can fix this?

Solution :

Set default values by following:

// PostForm
props: {
post: {
type: Object,
default: () => ({}),
}
errors: {
type: Object,
default: () => ({}),
}
}

See Reference

[Vue.js] Vue, what does $ means?

I’m learning Vue.js and I don’t understand what does the $ symbols does. Im using Laravel, I mean I’m not using the Vue-CLI.
When I go to the vue.js documentation, a lot of the documents does not have the $.

For example the Programmatic Navigation section says: router.push({ path: ‘/posts’ }), but when I did it on my code I had to do this.$router.push({ path: ‘/posts’ });

Thanks in advance.

Solution :

In Vue, $ means that you’re using a vue.js instance property or an vue.js instance method.

You can learn more about it on the documentation.

[Vue.js] Vue autocomplete in laravel

I’m working on an issue with a vue.js autocomplete function in a laravel site.

I’ve set my route, controller and blade. Currently, if I inspect the vue.js component and type in the input, it shows the keywords I’m typing in the console, so I know it’s catching what I’m typing.

As for the $groupResult in my controller, if I just dump that on my page then it dumps about 100 results as expected. All to do is have an autocomplete on the input that searches within those 100 results.

What exactly am I missing here?

Route

Route::get(‘campaigns/categories’,‘CampaignsController@searchcategories’)->name(‘campaigns.categories’);

Controller:

public function searchcategories(Request $request)
{
$userNum = $this->user;
$category = new categoryService();
$safecategories = $category->info($userNum);

$groupResult = array();

foreach($safecategories->categories as $categories){
$groupItem = array();
$groupItem[“group_code”] = $categories->group_code;
$groupItem[“group_name”] = $categories->group_name;

array_push($groupResult, $groupItem);
}

return $groupResult;
}

Blade

<div id=”categoryNames”>
<input type=”text” v-model=”keywords”>
<ul v-if=”results.length > 0”>
<li v-for=”result in results” :key=”result.id” v-text=”result.name”></li>
</ul>
</div>

var categoryNames = new Vue({
data() {
return {
keywords: null,
results: []
};
},

watch: {
keywords(after, before) {
this.fetch();
}
},

methods: {
fetch() {
axios.get(‘campaigns/categories’, { params: { keywords: this.keywords } })
.then(response => this.results = response.data)
.catch(error => {});
}
}
}).$mount(‘#categoryNames’);

Solution :

If you’re simply attempting to filter the existing results there is no need to call the server to do this.

<div id=”categoryNames”>
<input type=”text” v-model=”keywords”>
<ul v-if=”filteredResults.length > 0”>
<li v-for=”result in filteredResults” :key=”result.id” v-text=”result.name”></li>
</ul>
</div>

var categoryNames = new Vue({
data() {
return {
keywords: null,
results: []
};
},

computed: {
filteredResults () {
return this.keywords ? this.results.filter(row => row.name.search(new RegExp(`${this.keywords}`, ‘i’)) !== -1) : this.results
}
}
}).$mount(‘#categoryNames’);

The computed property returns an array of objects (I assumed you are filtering on the object key name). If a keyword is present it uses regex to perform a case insensitive search. If keyword is not present it returns the full results object.

Note, I did not test this code directly so there may be a typo etc. But have implemented many versions of this in a large scale application.

[Vue.js] Microsoft graph is remembering the user after authentication

I’m using Microsoft graph in my Android project to authenticate users.
I’m doing so via this method:
https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-v1-android

after a successful login Microsoft remembers the user email, so next time when user is trying to login it will suggest to use a previously logged in account. If user chooses a previously used email, a password is not required.

Problem raises when we have a single device where multiple users need to login via Microsoft. In this case new user will see the email of previously logged users and can select their email and log into account without entering any password.
My question is how can I avoid this behavior and close the session after each login?

Thank you!

Solution :

You can tell ADAL to request credentials again by switching PromptBehavior from Auto to Always:

// Perform authentication requests
mAuthContext.acquireToken(
getActivity(),
RESOURCE_ID,
CLIENT_ID,
REDIRECT_URI,
PromptBehavior.Always,
getAuthInteractiveCallback());

[Vue.js] Should a component have its parent's file name as part of its own file name?

to ask the correct way to name a component file.

I read the style guide.

https://vuejs.org/v2/style-guide/

when wondering, if you make a directory contain some child components of specific component, should those child component names start with the parent component’s name?

// OPTION 1:

file) ParentA.vue

directory) ParentA

|_ file) ParentAChildA.vue

// OPTION 2

file) ParentA.vue

directory) ParentA

|_ file) ChildA.vue

Which is proper?

Solution :

I think this is kind of opinion based.
Most developers use both approaches. Why?

Example for option 1:
Imagine a todo list from a classic todo app. First we have TodoList as wrapper for the items, maybe with some sorting options and so on. One item (= child component) would then be called TodoListItem.

Example for option 2:
Imagine some dashboard-style app. We have multiple shown components that aren’t directly mutual (can but don’t have to be). So we would have a Dashboard component. Of course, DashboardItem with dynamic values would also work but is overkill for most applications. So one would just use Dashboard and then Investments as child.

Most important: Be concise and consistent in naming the components (and of course also variables, services, etc.).

[Vue.js] The same dynamic page on different routes?

when using Nuxt.js. there is this page structure for orders:

/orders (pages/orders.vue)
/orders/123456 (pages/orders/_id.vue)

The _id.vue.js view is loaded as <nuxt-child> located in the orders.vue.js page. Can there is page setup (router setup) so that this page pages/orders/_id.vue.js is loaded in a different route, for example here:

/production (pages/production.vue)
/production/123456 (here I would like to load existing view pages/orders/_id.vue)

Is this possible somehow?

Solution :

You can use router-extras module

<router>
path: /posts
alias:
- /articles
- /blog
</router>

[Vue.js] Automatically updating v-data-table on store data change

I’m working on a Nuxt.js application using Vuetify and Nuxt.
One of my pages displays a table showing a list of games you can possibly join.
My goal is to keep updating this table automatically whenever games are added to or deleted from the list.

So in my store I set up the following state and mutations:

export const state = () => ({
games: {}
})

export const mutations = {
addGame(state, game) {
state.games[game.id] = game
},
removeGame(state, id) {
delete state.games[id]
}
}

as well as this getter that transforms the games object into a list, in order to make it usable by my component:

export const getters = {
games(state) {
const games = []
for (const key in state.games) {
games.push(state.games[key])
}
return games
}
}

Now here we have the relevant parts of my component:

<template>
<v-data-table
:headers=”headers”
:items=”getGames()”
class=”elevation-1”
\>
<template v-slot:items=”props”>
<td>{ props.item.name }</td>
<td class=”text-xs-center”>
{ props.item.players.length }/{ props.item.numberOfPlayers }
</td>
<v-btn :disabled=”props.item.nonJoinable” class=”v-btn–left” @click=”joinGame(props.item.id)”>
{ props.item.nonJoinable ? ‘Already joined’: ‘Join’ }
</v-btn>
</template>
</v-data-table>
</template>

<script>
export default {
data() {
return {
games: [],
headers: [
{
text: ‘Game name’,
align: ‘left’,
sortable: true,
value: ‘name’
},
{
text: ‘Players’,
align: ‘center’,
sortable: true,
value: ‘players’
}
]
}
},
async fetch({ store, params }) {
await store.dispatch(‘fetchGamesList’)
},
methods: {
joinGame(id) {
this.$store.dispatch(‘joinGame’, id)
},
getGames() {
console.log(this.$store.getters.games)
this.games = this.$store.getters.games
}
}
}
</script>

I’ve tried this configuration as well as declaring “games” as a computed property or declaring a “watch” method.
In none of this cases I could see the table automatically update whenever any of the mutations above is triggered (the data on the store are updated correctly).

What would it be the correct way to get the desired behavior out of my component?

Solution :

As I said in my comment, you should use a computed property for getGames but you could use mapGetters in there. So if the store is being updated then this should work:

//the component
<template>
<v-data-table
:headers=”headers”
:items=”games”
class=”elevation-1”
\>
… //rest of the template code
</v-data-table>
</template>
<script>
import {mapGetters} from ‘vuex’
export default {
data() {
return {
headers: [
// the headers objects
]
}
},
computed: {
…mapGetters({
games
}),
},
… //rest of scripts but without getGames method
</script>

So delete the getGames method and keep the rest, should work fine.

[Vue.js] Vue Apollo - How to properly fetch data?

I’m having lot of problems with receiving movie data from this endpoint using vue-apollo.

Endpoint: http://movie-database-graphql.herokuapp.com/graphiql

And this is how I configure it (Vuetify for styling b.t.w):

main.js

import vue.js from ‘vue’
import App from ‘./App.vue’

// Plugins
import ‘./plugins/vuetify’
import VueApollo from ‘vue-apollo’
import ApolloClient from ‘apollo-boost’

const apolloClient = new ApolloClient({
uri: ‘http://movie-database-graphql.herokuapp.com/graphql'
});

const apolloProvider = new VueApollo({
defaultClient: apolloClient,
})

Vue.use(VueApollo);

Vue.config.productionTip = false

new Vue({
apolloProvider,
render: h => h(App)
}).$mount(‘#app’)

I believe the problem comes on how I call database through Apollo but not sure yet. I’ve tried many ways, following documentation and always fail.

MovieList.vue.js (Component with the query)

<template>
<v-container fluid grid-list-md>
<v-layout row wrap>
<h4 v-if=”$apollo.loading”>Loading…</h4>
<v-flex v-for=”movie in movies” :key=”movie.id” xs12 sm6>
<v-card height=”150px”>
<v-layout row>
<v-avatar size=”125” tile>
<v-img :src=”movie.poster_path” contain></v-img>
</v-avatar>
<v-flex xs12 sm6>
<v-card-title primary-title>
<h3>{ movie.title }</h3>
</v-card-title>
</v-flex>
</v-layout>
</v-card>
</v-flex>
</v-layout>
</v-container>
</template>

<script>
import gql from “graphql-tag”

export default {
name: “MovieList”,
data: () => { return { movies: [] } },
apollo: {
movies: gql`
query AllMoviesQuery {
movies(query: “Start Wars”) {
id
title
poster_path
}
}`
}
};
</script>

Do you understand what I’m missing? I don’t receive any movie data (no errors shown…). movies array is alway empty

Solution :

Just a typo — the query argument in the request is:

Start Wars

instead of

Star Wars

If you use that same value inside GraphiQL, you’ll also get empty results.

[Vue.js] Change width proportions of two blocks with a slider

I’m trying to design a component in which you could change the width proportions of two blocks by moving a slider left and right:

codpen and demo:

.outer {
display: flex;
flex-direction: row;
}

.block {
height: 200px;
width: -webkit-calc(50% - 5px);
width: -moz-calc(50% - 5px);
width: calc(50% - 5px);
}

.block-1 {
background-color: red;
}

.block-2 {
background-color: green;
}

.slider {
line-height: 100%;
width: 10px;
background-color: #dee2e6;
border: none;
cursor: e-resize;
}
<div id=”app”>
<div class=”outer”>
<div class=”block block-1”>
Block 1
</div>
<div class=”slider”>
S<br>l<br>i<br>d<br>e<br>r
</div>
<div class=”block block-2”>
Block 2
</div>
</div>
</div>

there is tried using draggable-vue-directive and change the width of blocks based on slider position.

However, it didn’t work really well, since draggable-vue-directive set the slider to position:fixed which in turn messed up the block alignment.

How can I make the .slider block horizontally draggable without setting position:fixed?

How to correctly resize Block1 and Block2 when slider moves?

Note: I’m not using jQuery

Solution :

You can adjust the flexbox along with resize - the downside is that the slider its not very customizeable:

add resize: horizontal to one of the flex items
add flex: 1 to the other flex item (so that this flex item will adjust automatically in response to the changing width of the other flex item as it is resized)

See demo below:

.outer {
display: flex;
flex-direction: row;
}

.block {
height: 100px;
width: 50%; /* 50% would suffice*/
}

.block-1 {
background-color: red;
resize: horizontal; /* resize horizontal */
overflow: hidden; /* resize works for overflow other than visible */
}

.block-2 {
background-color: green;
flex: 1; /* adjust automatically */
}
<div id=”app”>
<div class=”outer”>
<div class=”block block-1”>
Block 1
</div>
<div class=”block block-2”>
Block 2
</div>
</div>
</div>

So we’ll use vanilla JS instead of the resize solution above:

use a mousedown listener that registers a mousemove listener that updates the block-1 width (and reset the mouseup event)
also consider min-width: 0 to override min-width: auto of the block-2 element

See demo below:

let block = document.querySelector(“.block-1”),
slider = document.querySelector(“.slider”);

slider.onmousedown = function dragMouseDown(e) {
let dragX = e.clientX;
document.onmousemove = function onMouseMove(e) {
block.style.width = block.offsetWidth + e.clientX - dragX + “px”;
dragX = e.clientX;
}
// remove mouse-move listener on mouse-up
document.onmouseup = () => document.onmousemove = document.onmouseup = null;
}
.outer {
display: flex;
flex-direction: row;
}

.block {
height: 100px;
width: 50%; /* 50% would suffice*/
}

.block-1 {
background-color: red;
}

.block-2 {
background-color: green;
flex: 1; /* adjust automatically */
min-width: 0; /* allow flexing beyond auto width */
overflow: hidden; /* hide overflow on small width */
}

.slider {
line-height: 100%;
width: 10px;
background-color: #dee2e6;
border: none;
cursor: col-resize;
user-select: none; /* disable selection */
text-align: center;
}
<div id=”app”>
<div class=”outer”>
<div class=”block block-1”>
Block 1
</div>
<div class=”slider”>
S<br>l<br>i<br>d<br>e<br>r
</div>
<div class=”block block-2”>
Block 2
</div>
</div>
</div>

Solution

You can adapt the above into vue.js easily without using any custom vue.js plugins for this - the changes are:

@mousedown listener on slider that triggers the slider
use of refs to update the width of block-1

See demo below:

new Vue({
el: ‘#app’,
data: {
block1W: ‘50%’
},
methods: {
drag: function(e) {
let dragX = e.clientX;
let block = this.$refs.block1;
document.onmousemove = function onMouseMove(e) {
block.style.width = block.offsetWidth + e.clientX - dragX + “px”;
dragX = e.clientX;
}
// remove mouse-move listener on mouse-up
document.onmouseup = () => document.onmousemove = document.onmouseup = null;
}
}
});
.outer {
display: flex;
flex-direction: row;
}

.block {
height: 100px;
width: 50%; /* 50% would suffice*/
}

.block-1 {
background-color: red;
}

.block-2 {
background-color: green;
flex: 1; /* adjust automatically */
min-width: 0; /* allow flexing beyond auto width */
overflow: hidden; /* hide overflow on small width */
}

.slider {
line-height: 100%;
width: 10px;
background-color: #dee2e6;
border: none;
cursor: col-resize;
user-select: none; /* disable selection */
text-align: center;
}
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id=”app”>
<div class=”outer”>
<div class=”block block-1” ref=”block1” :style=”{‘width’: block1W}”>
Block 1
</div>
<div class=”slider” @mousedown=”drag”>
S<br>l<br>i<br>d<br>e<br>r
</div>
<div class=”block block-2”>
Block 2
</div>
</div>
</div>

[Vue.js] force component to rebuild on route change or vuex state change

to get into VueJs / Vuex and created a small todo app. There are three links for “all todos”, “pending ones” and “completed ones”. It’s the same route but with a different filter query.

When changing the route the component will not update, because it seems that updated query is not forcing an component update. But the computed event gets triggered.

I created a small example showing my current problem

https://codesandbox.io/s/6zx2p0m20r

If you click around on the todo links there will be no component update. If you head over to “another route” and head back, the component was updated (because of a completely different route).

How can I force to update the component on a query update within the same base route?

Solution :

You can add the beforeRouteUpdate navigation guard to reinitialize the data:

beforeRouteUpdate is called when the route that renders this component has changed,
but this component is reused in the new route.

For example, for a route with dynamic params /foo/:id, when we
navigate between /foo/1 and /foo/2, the same Foo component instance
will be reused, and this hook will be called when that happens.

(source)

beforeRouteUpdate(to, from, next) {
this.currentTodoFilter = to.query.filter
next()
}

You can also remove the updateTodoFilter method this way.