link2740 link2741 link2742 link2743 link2744 link2745 link2746 link2747 link2748 link2749 link2750 link2751 link2752 link2753 link2754 link2755 link2756 link2757 link2758 link2759 link2760 link2761 link2762 link2763 link2764 link2765 link2766 link2767 link2768 link2769 link2770 link2771 link2772 link2773 link2774 link2775 link2776 link2777 link2778 link2779 link2780 link2781 link2782 link2783 link2784 link2785 link2786 link2787 link2788 link2789 link2790 link2791 link2792 link2793 link2794 link2795 link2796 link2797 link2798 link2799 link2800 link2801 link2802 link2803 link2804 link2805 link2806 link2807 link2808 link2809 link2810 link2811 link2812 link2813 link2814 link2815 link2816 link2817 link2818 link2819 link2820 link2821 link2822 link2823 link2824 link2825 link2826 link2827 link2828 link2829 link2830 link2831 link2832 link2833 link2834 link2835 link2836 link2837 link2838 link2839 link2840 link2841 link2842 link2843 link2844 link2845 link2846 link2847 link2848 link2849 link2850 link2851 link2852 link2853 link2854 link2855 link2856 link2857 link2858 link2859 link2860 link2861 link2862 link2863 link2864 link2865 link2866 link2867 link2868 link2869 link2870 link2871 link2872 link2873 link2874 link2875 link2876

[Vue.js] Problems with Laravel 5.6 Vue.js e o app.js (404)

I use laravel 5.6, vue.js, apache.

Erro:
GET https://alphi.com.br/js/app.js net::ERR_ABORTED 404

Did you upload the file in the server? yes

Does the build provide a minified version with a hash added? no

The app.js is not recognized in my frontend application.

What I tried and did not work:

folder permission is correct
mix did not advance anything
I changed the folder, but error persist.

Configuration webpack.mix.js:

let mix = require(‘laravel-mix’);

mix.js(‘resources/assets/js/app.js’, ‘public/js’)
.sass(‘resources/assets/sass/app.scss’, ‘public/css’)
.version();

Can anybody help me. I searched all over the internet and found nothing to help me.

Thank you

Solution :

If you use .version() in Laravel-Mix, you should use in the blade

<script src=”{ mix(‘js/app.js’) }”></script>

..because it’s has a versioned name instead. Same for stylesheet path:

{ mix (‘css/app.css’) }

Docs: https://laravel.com/docs/5.8/mix#versioning-and-cache-busting

Solution 2:

when using a dedicated server with centos7, I contacted the support to check if it could get any configuration from the server. they messed around and ruffled. As I do not know what it is I opened a ticket to check what they messed up to know. so answer post here

[Vue.js] Vue Js show and hide a div with a Toggle

Hey all so when brand new into the world of Vue.

when building an app With a Rails API back end and vue.js front end.

when trying use a Toggle Switch (found in this repo Git Hub ) to send true attribute back to my model and open a hidden div on the page.

Right now when getting these errors and there is no idea how to proceed. I dont think when understanding their docs as I’ve read them but not really understanding what i need to do..:

vue.esm.js?efeb:1897 RangeError: Maximum call stack size exceeded
at VueComponent.Vue._render (vue.esm.js?efeb:3553)
at VueComponent.updateComponent (vue.esm.js?efeb:4069)
at Watcher.get (vue.esm.js?efeb:4482)
at new Watcher (vue.esm.js?efeb:4471)
at mountComponent (vue.esm.js?efeb:4076)
at VueComponent.Vue.$mount (vue.esm.js?efeb:9057)
at VueComponent.Vue.$mount (vue.esm.js?efeb:11953)
at init (vue.esm.js?efeb:3127)
at createComponent (vue.esm.js?efeb:5983)
at createElm (vue.esm.js?efeb:5930)

vue.esm.js?efeb:1897 RangeError: Maximum call stack size exceeded
at VueComponent.Vue._render (vue.esm.js?efeb:3553)
at VueComponent.updateComponent (vue.esm.js?efeb:4069)
at Watcher.get (vue.esm.js?efeb:4482)
at new Watcher (vue.esm.js?efeb:4471)
at mountComponent (vue.esm.js?efeb:4076)
at VueComponent.Vue.$mount (vue.esm.js?efeb:9057)
at VueComponent.Vue.$mount (vue.esm.js?efeb:11953)
at init (vue.esm.js?efeb:3127)
at createComponent (vue.esm.js?efeb:5983)
at createElm (vue.esm.js?efeb:5930)

Here is my AppToggle.vue

<template>
<div>
<AppToggle v-model=”isToggleOn” onText=”Hide Map” offText=”Show Map”/>
</div>
</template>

<script>
export default {
name: “AppToggle”,
data() {
return {
isToggleOn: true
};
}
};
</script>

and here is my Signup.vue.js component where the toggle is called:

<template>
… Some form stuff up here…
<app-toggle @click.prevent=”toggleSmsDiv()”/>
<div id=”smsDiv” v-if=”isToggleOn”>TEST DIV ITEMS</div>
… More form stuff down here…
</template>
<script>
import AppToggle from “@/components/AppToggle”;
export default {
name: “Signup”,
components: {
AppToggle
},
data() {
return {
isToggleOn: false,
first_name: “”,
last_name: “”,
email: “”,
password: “”,
password_confirmation: “”,
error: “”
};
},
created() {
this.checkSignedIn();
},
updated() {
this.checkSignedIn();
},
methods: {
toggleSmsDiv() {
this.isToggleOn = !this.isToggleOn;
},
signup() {
this.$http.plain
.post(“/signup”, {
email: this.email,
password: this.password,
password_confirmation: this.password_confirmation
})
.then(response => this.signupSuccessful(response))
.catch(error => this.signupFailed(error));
},
signupSuccessful(response) {
if (!response.data.csrf) {
this.signupFailed(response);
return;
}
localStorage.csrf = response.data.csrf;
localStorage.signedIn = true;
this.error = “”;
this.$router.replace(“/products”); // Change this to User Dashboard
},
signupFailed(error) {
this.error =
(error.response && error.response.data && error.response.data.error) ||
“Something went wrong. Please try again.”;
delete localStorage.scrf;
delete localStorage.signedIn;
},
checkSignedIn() {
if (localStorage.signedIn) {
this.$router.replace(“/products”); //Change this to User Dashboard
}
}
}
};
</script>

<style>
</style>

Solution :

You got Maximum call stack size exceeded because of you are using the AppToggle component inside AppToggle component which that cause the recursively call itself.

I’m not sure how do you import this package since I can’t find it on npm. It seems the author of this package want us to copy TailwindToggle.vue.js manually.

So the AppToggle.vue.js would be:

// Same as TailwindToggle.vue

<template>

</template>

<script>

</script>

<style lang=”postcss”> // Make sure you vue.js config support postcss` language

</style>

And the Signup.vue.js would be:

<template>

<AppToggle v-model=”isToggleOn” onText=”Hide Map” offText=”Show Map”/>
<div id=”smsDiv” v-if=”isToggleOn”>TEST DIV ITEMS</div>

</template>

I’m not sure this will works since the style of TailwindToggle seems have to import some pieces from somewhere else (not sure). If it not working may be you can looking at its dist file and copy involved style and paste it into yours AppToggle.vue. But if it possible I would recommend you to another package instead.

Hope this helps.

[Vue.js] How to allow HTML templates define React components the same as Vue?

In vue.js you can have something like.

<!– index.php –>

<div id=”app”>
<section>
<main>
<h1>Main</h1>
<some-component></some-component>
</main>
<aside>
<h2>Side</h2>
<another-component></another-component>
</aside>
</section>
</div>

<script>
Vue.component(‘some-component’, { template: ‘<div>hello - { this.$parent.test }</div>’ });
Vue.component(‘another-component’, { template: ‘<div>world - { this.$parent.test }</div>’ });

new Vue({el: ‘#app’, data: () => ({test: 123})});
</script>

which will render all the registered components and you’ll end up with something like

<div id=”app”>
<section>
<main>
<h1>Main</h1>
<div>hello - 123</div>
</main>
<aside>
<h2>Side</h2>
<div>world - 123</div>
</aside>
</section>
</div>

How can the same thing be done using React?

I’ve tried silly things like

class App extends Component {
render() {
return <div>{this.props.kids}</div>
}
}

if (document.getElementById(‘app’)) {
ReactDOM.render(<App kids={document.getElementById(‘app’).innerHTML)} />, document.getElementById(‘app’));
}

The overall goal is to be able to have normal html templates, then scatter various react components throughout where needed.

Ideally it should be contained with a single renderless-like component which can provide down global data using the context api.

Solution :

I dont see the point in using React if you want vue/angular-like templates, use vue.js instead. React uses javascript xml or jsx if you will, whichs do look like templates but are actually giving you the benefit of everything javascript can do.

Although, if you want everything in a single component, there’s nothing stopping you from doing so.

now if you meant that you want a single component that renders all children, you aren’t far off tbh. Here’s a simple example from codeburst

const Picture = (props) => {
return (
<div>
<img src={props.src}/>
{props.children}
</div>
)
}

render () {
return (
<div className=’container’>
<Picture src={picture.src}>
//what is placed here is passed as props.children
</Picture>
</div>
)
}

Solution 2:

React is not template-based but uses JS or JSX to define components, so options are limited.

It’s preferable to

It’s possible to render HTML snippets with dangerouslySetInnerHTML:

<div dangerouslySetInnerHTML={this.props.kids}/>

This doesn’t allow to use custom components inside snippets because React components don’t use selectors. It may be possible to parse a template with HTML parser to a hierarchy of React elements and then replace custom elements like <some-component> with corresponding React components, like shown in this question.

It’s possible to define and transpile components on the fly but this isn’t recommended in production:

<script src=”https://unpkg.com/babel-standalone/babel.js"></script>
<script src=”https://unpkg.com/react/umd/react.development.js"></script>
<script src=”https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script type=”text/babel”>
var Foo = () => ‘Foo’;
</script>

<script type=”text/babel”>
ReactDOM.render(<Foo/>, document.getElementById(‘foo’));
</script>

In order to use context API for multiple components, they should be rendered not as root components with render but within a common parent, for instance, as portals with createPortal:


<script>
var portals = {};
</script>

<script type=”text/babel”>
portals[‘#foo’] = <Foo/>;
</script>

<script type=”text/babel”>
// runs on page load
var CommonContext = …;
var Root = () => (
<CommonContext.Provider value={…}>
{Object.entries(portals).map(({ selector, child }) => (
ReactDOM.createPortal(child, document.querySelector(selector))
)}
</CommonContext.Provider>
);

ReactDOM.render(<Root/>, document.getElementById(‘root’));
</script>

[Vue.js] From an array of objects, extract value of a property as array

there is JavaScript object array with the following structure:

objArray = [ { foo: 1, bar: 2}, { foo: 3, bar: 4}, { foo: 5, bar: 6} ];

to extract a field from each object, and get an array containing the values, for example field foo would give array [ 1, 3, 5 ].

I can do this with this trivial approach:

function getFields(input, field) {
var output = [];
for (var i=0; i < input.length ; ++i)
output.push(input[i][field]);
return output;
}

var result = getFields(objArray, “foo”); // returns [ 1, 3, 5 ]

Is there a more elegant or idiomatic way to do this, so that a custom utility function would be unnecessary?

Note about suggested duplicate, it covers how to convert a single object to an array.

Solution :

Here is a shorter way of achieving it:

let result = objArray.map(a => a.foo);

or

let result = objArray.map(({ foo }) => foo)

You can also check Array.prototype.map() documentation on MDN

Solution 2:

Yes, but it relies on an ES5 feature of JavaScript. This means it will not work in IE8 or older.

var result = objArray.map(function(a) {return a.foo;});

On ES6 compatible JS interpreters you can use an arrow function for brevity:

var result = objArray.map(a => a.foo);

Documentation

Solution 3:

Check out Lodash’s _.pluck() function or Underscore’s _.pluck() function. Both do exactly what you want in a single function call!

var result = _.pluck(objArray, ‘foo’);

Update: _.pluck() has been removed as of Lodash v4.0.0, in favour of _.map() in combination with something similar to Niet’s answer. _.pluck() is still available in Underscore.

Update 2: As Mark points out in the comments, somewhere between Lodash v4 and 4.3, a new function has been added that provides this functionality again. _.property() is a shorthand function that returns a function for getting the value of a property in an object.

Additionally, _.map() now allows a string to be passed in as the second parameter, which is passed into _.property(). As a result, the following two lines are equivalent to the code sample above from pre-Lodash 4.

var result = _.map(objArray, ‘foo’);
var result = _.map(objArray, _.property(‘foo’));

_.property(), and hence _.map(), also allow you to provide a dot-separated string or array in order to access sub-properties:

var objArray = [
{
someProperty: { aNumber: 5 }
},
{
someProperty: { aNumber: 2 }
},
{
someProperty: { aNumber: 9 }
}
];
var result = _.map(objArray, _.property(‘someProperty.aNumber’));
var result = _.map(objArray, _.property([‘someProperty’, ‘aNumber’]));

Both _.map() calls in the above example will return [5, 2, 9].

If you’re a little more into functional programming, take a look at Ramda’s R.pluck() function, which would look something like this:

var result = R.pluck(‘foo’)(objArray); // or just R.pluck(‘foo’, objArray)

Solution 4:

Speaking for the JS only solutions, I’ve found that, inelegant as it may be, a simple indexed for loop is more performant than its alternatives.

https://jsperf.com/extract-prop-from-object-array/

Extracting single property from a 100000 element array

Traditional for loop 368 Ops/sec

var vals=[];
for(var i=0;i<testArray.length;i++){
vals.push(testArray[i].val);
}

ES6 for..of loop 303 Ops/sec

var vals=[];
for(var item of testArray){
vals.push(item.val);
}

Array.prototype.map 19 Ops/sec

var vals = testArray.map(function(a) {return a.val;});

Edit: Ops/s updated 10/2017. TL;DR - .map() is slow. But sometimes readability is worth more than performance.

Solution 5:

Using Array.prototype.map:

function getFields(input, field) {
return input.map(function(o) {
return o[field];
});
}

See the above link for a shim for pre-ES5 browsers.

Solution 6:

It is better to use some sort of libraries like lodash or underscore for cross browser assurance.

In lodash you can get values of a property in array by following method

_.map(objArray,”foo”)

and in underscore

_.pluck(objArray,”foo”)

both will return [ 1, 3, 5 ]

Solution 7:

While map is a proper solution to select ‘columns’ from a list of objects, it has a downside. If not explicitly checked whether or not the columns exists, it’ll throw an error and (at best) provide you with undefined.
I’d opt for a reduce solution, which can simply ignore the property or even set you up with a default value.

function getFields(list, field) {
// reduce the provided list to an array only containing the requested field
return list.reduce(function(carry, item) {
// check if the item is actually an object and does contain the field
if (typeof item === ‘object’ && field in item) {
carry.push(item[field]);
}

// return the ‘carry’ (which is the list of matched field values)
return carry;
}, []);
}

jsbin example

This would work even if one of the items in the provided list is not an object or does not contain the field.

It can even be made more flexible by negotiating a default value should an item not be an object or not contain the field.

function getFields(list, field, otherwise) {
// reduce the provided list to an array containing either the requested field or the alternative value
return list.reduce(function(carry, item) {
// If item is an object and contains the field, add its value and the value of otherwise if not
carry.push(typeof item === ‘object’ && field in item ? item[field] : otherwise);

// return the ‘carry’ (which is the list of matched field values)
return carry;
}, []);
}

jsbin example

This would be the same with map, as the length of the returned array would be the same as the provided array. (In which case a map is slightly cheaper than a reduce):

function getFields(list, field, otherwise) {
// map the provided list to an array containing either the requested field or the alternative value
return list.map(function(item) {
// If item is an object and contains the field, add its value and the value of otherwise if not
return typeof item === ‘object’ && field in item ? item[field] : otherwise;
}, []);
}

jsbin example

And then there is the most flexible solution, one which lets you switch between both behaviours simply by providing an alternative value.

function getFields(list, field, otherwise) {
// determine once whether or not to use the ‘otherwise’
var alt = typeof otherwise !== ‘undefined’;

// reduce the provided list to an array only containing the requested field
return list.reduce(function(carry, item) {
// If item is an object and contains the field, add its value and the value of ‘otherwise’ if it was provided
if (typeof item === ‘object’ && field in item) {
carry.push(item[field]);
}
else if (alt) {
carry.push(otherwise);
}

// return the ‘carry’ (which is the list of matched field values)
return carry;
}, []);
}

jsbin example

As the examples above (hopefully) shed some light on the way this works, lets shorten the function a bit by utilising the Array.concat function.

function getFields(list, field, otherwise) {
var alt = typeof otherwise !== ‘undefined’;

return list.reduce(function(carry, item) {
return carry.concat(typeof item === ‘object’ && field in item ? item[field] : (alt ? otherwise : []));
}, []);
}

jsbin example

Solution 8:

In ES6, you can do:

const objArray = [{foo: 1, bar: 2}, {foo: 3, bar: 4}, {foo: 5, bar: 6}]
objArray.map(({ foo }) => foo)

Solution 9:

It depends of the definition of “better”.

The other answers point out the use of map, which is natural (especially for guys used to functional style) and concise. I strongly recommend using it (if you don’t bother with the few IE8- IT guys). So if “better” means “more concise”, “maintainable”, “understandable” then yes, it’s way better.

In the other hand, this beauty don’t come without additional costs. I’m not a big fan of microbench, but I’ve put up a small test here. The result are predictable, the old ugly way seems to be faster than the map function. So if “better” means “faster”, then no, stay with the old school fashion.

Again this is just a microbench and in no way advocating against the use of map, it’s just my two cents :).

Solution 10:

Function map is a good choice when dealing with object arrays. Although there have been a number of good answers posted already, the example of using map with combination with filter might be helpful.

In case you want to exclude the properties which values are undefined or exclude just a specific property, you could do the following:

var obj = {value1: “val1”, value2: “val2”, Ndb_No: “testing”, myVal: undefined};
var keysFiltered = Object.keys(obj).filter(function(item){return !(item == “Ndb_No” || obj[item] == undefined)});
var valuesFiltered = keysFiltered.map(function(item) {return obj[item]});

https://jsfiddle.net/ohea7mgk/

Solution 11:

If you want to also support array-like objects, use Array.from (ES2015):

Array.from(arrayLike, x => x.foo);

The advantage it has over Array.prototype.map() method is the input can also be a Set:

let arrayLike = new Set([{foo: 1}, {foo: 2}, {foo: 3}]);

Solution 12:

In general if you want to extrapolate object values which are inside an array (like described in the question) then you could use reduce, map and array destructuring.

ES6

let a = [{ z: ‘word’, c: ‘again’, d: ‘some’ }, { u: ‘1’, r: ‘2’, i: ‘3’ }];
let b = a.reduce((acc, x) => […acc, Object.values(x).map((y, i) => y)], []);
console.log(b)

The equivalent using for in loop would be the following:

for (let i in a) {
let temp = [];
for (let j in a[i]) {
temp.push(a[i][j]);
}
array.push(temp);
}

Produced output: [“word”, “again”, “some”, “1”, “2”, “3”]

Solution 13:

Above provided answer is good for extracting single property, what if you want to extract more than one property from array of objects.
Here is the solution!!
In case of that we can simply use _.pick(object, [paths])

_.pick(object, [paths])

Lets assume objArray has objects with three properties like below

objArray = [ { foo: 1, bar: 2, car:10}, { foo: 3, bar: 4, car:10}, { foo: 5, bar: 6, car:10} ];

Now we want to extract foo and bar property from every object and store them in a separate array.
First we will iterate array elements using map and then we apply Lodash Library Standard _.pick() method on it.

Now we are able to extract ‘foo’ and ‘bar’ property.

var newArray = objArray.map((element)=>{ return _.pick(element, [‘foo’,’bar’])})
console.log(newArray);

and result would be
[{foo: 1, bar: 2},{foo: 3, bar: 4},{foo: 5, bar: 6}]

enjoy!!!

Solution 14:

If you want multiple values in ES6+ the following will work

objArray = [ { foo: 1, bar: 2, baz: 9}, { foo: 3, bar: 4, baz: 10}, { foo: 5, bar: 6, baz: 20} ];

let result = objArray.map(({ foo, baz }) => ({ foo, baz }))

This works as {foo, baz} on the left is using object destructoring and on the right side of the arrow is equivalent to {foo: foo, baz: baz} due to ES6’s enhanced object literals.

[Vue.js] Vue/Vuex - Module two depends on module one, and module one gets data from server

Check this out:

import accountModule from ‘@/store/modules/account/account’;
import otherModule from ‘@/store/modules/other/other’;

export default new Vuex.Store({
modules: {
account: accountModule,
other: otherModule,
}
});

The data initialization in other depends on the account module because the account module has user specific settings. However, the data for the account module to come from the server. Which is async. When other is executing, account hasn’t finished getting its stuff from the server, and other doesn’t have access to the user settings it needs.

I tried exporting a promise in accountModule that resolves with the module itself. But that approach doesn’t seem to work.

import accountModulePromise from ‘@/store/modules/account/account’;

accountModulePromise.then(function (accountMoudle) {
import otherModule from ‘@/store/modules/other/other’;


});

This gives me an error saying that import statements need to be top level.

The following doesn’t work either:

let accountModule = await import ‘@/store/modules/account/account’;
import otherModule from ‘@/store/modules/other/other’;

It gives me an error saying that await is a reserved word. I’m confused though, because https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import says that I should be able to do it.

Solution :

the last code block didn’t work because of await have to be inside async function.

Remember, the await keyword is only valid inside async functions. If
you use it outside of an async function’s body, you will get a
SyntaxError.

From MDN.

You can use Dynamic Module Registration:

accountModulePromise.then(async () => {
let otherModule = await from ‘@/store/modules/other/other’;
store.registerModule(‘other’, otherModule.default);
});

But when you want to get state or dispatch actions you have to check whether module is registered which is pretty bad.

In my opinion it would be better if you redesign the module structure to decoupling each other. Try to move the initialize code to main.js or App.vue.js then dispatch actions to update module states from that.

[Vue.js] Cant get Vue to focus on input

I’m trying to use this.$refs.cInput.focus() (cInput is a ref) and it’s not working. I’d be able to hit g and the input should pop up and the cursor should focus in it, ready to input some data. It’s showing but the focus part is not working. I get no errors in the console.

Vue.component(‘coordform’, {
template: `<form id=”popup-box” @submit.prevent=”process” v-show=”visible”><input type=”text” ref=”cInput” v-model=”coords” placeholder =””></input></form>`,
data() {
{
return { coords: ‘’, visible: false }
}
},
created() {
window.addEventListener(‘keydown’, this.toggle)
},
mounted() {
},
updated() {
},
destroyed() {
window.removeEventListener(‘keydown’, this.toggle)
},
methods: {
toggle(e) {
if (e.key == ‘g’) {
this.visible = !this.visible;
this.$refs.cInput.focus() //<——–not working
}
},
process() {

}
}
});

Solution :

You can use the nextTick() callback:

When you set vm.someData = ‘new value’, the component will not
re-render immediately. It will update in the next tick, when the
queue is flushed. […]

In order to wait until Vue.js has finished updating the DOM after a data
change, you can use Vue.nextTick(callback) immediately after the data
is changed. The callback will be called after the DOM has been
updated.

(source)

Use it in the toggle function like:

methods: {
toggle(e) {
if (e.key == ‘g’) {
this.visible = !this.visible;
this.$nextTick(() => this.$refs.cInput.focus())
}
}
}

[Vue.js] Vue Lazy load refactor

when trying to lazy load a lot of components in my app, to show a loading spinner while any of them is loading, and the same for error; so there is a lot of duplication.

export default c => ({
component: import(`${c}`),
loading: loadingComponent,

timeout: 3000
})

when trying to refactor this into a single function and using it like that

import lazyload from ‘./lazyload’;
Collection: lazyload(“./Collection.vue”)

But webpack is not extracting the component as it normally does, I know that when missing something.

Solution :

You need to be creating an async component factory (meaning function). Also the import module cannot be fully dynamic, there needs to be some prefix to the module path otherwise it could match literally any module and webpack needs to know which subset of modules it could possibly match at runtime to include them in the build.

Fully dynamic statements, such as import(foo), will fail because webpack requires at least some file location information. This is because foo could potentially be any path to any file in the system or project. The import() must contain at least some information about where the module is located, so bundling can be limited to a specific directory or set of files.

I’ve made some adjustments to the code (untested):

lazyload.js

export default c => () => ({
component: import(`./components/${c}`),
loading: loadingComponent,
timeout: 3000
})

Example usage

import lazyload from ‘./lazyload’

export default {
components: {
Collection: lazyload(‘collection.vue’)
}
}

A better implementation, in my opinion, would be to avoid creating the dynamic import. I prefer webpack to know for certain which modules are definitely needed at build time instead of bundling together a subset of modules inside a directory.

lazyload.js

export default componentFn => () => ({
component: componentFn(),
loading: loadingComponent,
timeout: 3000
})

Example usage

import lazyload from ‘./lazyload’

export default {
components: {
Collection: lazyload(() => import(‘./collection.vue’))
}
}

Now lazyload has no dependency on any specific component directory and can be used with any component.

[Vue.js] Trouble structuring v-if as a filter inside a v-for using Vue.js

I’m having a bit of trouble setting up a v-if with a v-for, since when very new to Vue. I currently have:

<div class=”row form-group” v-for=”(article, key, index) in articles” :key=”key” v-if=”article.pubdate(first four characters)”>={ filterYear} >

I’m not sure how to get the first four characters of the pubdate, so it would be treated as a number, and also how to pass in the filterYear.
articles is a JSON object that is returned using Axios. However, pubdate is formatted as: year, space, then month. For example:

2007 Aug or 2009 Aug 1

What I need to do is to identify a year, and pass it into the v-if, so only articles written during or after the year will show up. there is similar code on the JavaScript side that identifies values and puts them into a string ( uid_string). See Codepen.

Solution :

Instead of a v-if loop filter, I recommend a computed property to simplify the loop’s template a bit. Another advantage to this solution over the other is it removes the need for additional ordinal number calculation of each item, since the ordinal naturally matches the item’s array index incremented by 1.

For example, you could move the filter suggested by @Stephen into a computed property:

<script>
export default {
computed: {
filteredArticles() {
const { articles, filterYear } = this
return Object.values(articles)
.filter(article => parseInt(article.pubdate.substring(0,4)) >= filterYear)
}
}
}
</script>

Then, use the computed property in the template like this:

<template>
<div v-for=”(article, index) in filteredArticles” :key=”article.uid”>

</div>
</template>

demo

Solution 2:

To get an integer year from first four characters:

parseInt(article.pubdate.substring(0, 4))

<div
v-for=”(article, key, index) in articles”
:key=”key”
v-if=”parseInt(article.pubdate.substring(0, 4))>=filterYear”>

the code here…
To print the article JSON put it in braces: {article}.
Or the date {article.date}, etc.
Don’t put the braces in the template attribute value though.

</div>

The beauty of vue.js is that all template properties are relative to the component, so you do not need to use this. to reference them.

You can also clean up the template by moving the parseInt(…) and comparison to a component method.

Here is the codepen with these changes:
https://codepen.io/anon/pen/NVrvre?editors=1111

[Vue.js] Vuejs Gitlab page is blank, console says MIME type mismatch, css and js not found

I made a website in Vuejs, it works on my local browser. I build the page locally and push to gitlab here (https://gitlab.com/ayaderaghul/coi6), and run CI (with folder: public). The page is blank (https://ayaderaghul.gitlab.io/coi6/), the console says:

The resource from https://ayaderaghul.gitlab.io/coi6/public/static/js/vendor.d5bde172b988351183eb.js was blocked due to MIME type (text/html) mismatch (X-Content-Type-Options: nosniff).[Learn More] coi6

Loading failed for the <script> with source https://ayaderaghul.gitlab.io/coi6/public/static/js/vendor.d5bde172b988351183eb.js.

And I right click the page to View Page Source, the link to css, js files are not found (view-source:https://ayaderaghul.gitlab.io/coi6/)

there is tried the following:

I write commands to build the page in .gitlab-ci.yml

image: alpine:latest

before_script:
- apk add –update nodejs
- apk add –update npm
- npm install chalk
- npm install each-async
- npm install indent-string
- npm install

pages:
stage: deploy
script:
- npm run build
artifacts:
paths:
- public
only:
- master

(https://gitlab.com/ayaderaghul/coi6/blob/master/.gitlab-ci.yml)

I change the css and js paths in file index.html in some ways: /coi6/public/static/css/… or static/css/… …

None of them works. The behavior is the same. Please give me more options to try? Or more cues to look at? Or explain me something I haven’t understood. Thank you,

Solution :

the path is wrong in index.html.

the files are available for example here :

https://ayaderaghul.gitlab.io/coi6/static/js/vendor.d5bde172b988351183eb.js

Whereas you are referencing them here :

https://ayaderaghul.gitlab.io/coi6/public/static/js/vendor.d5bde172b988351183eb.js

[Vue.js] Route protect vue-router

there is admin dashboard on vue.js and I need to know is it enouth to protect this route by checking for example “isLoggedIn” flag from vuex getters? This flag changing after success login to “true” right after client gets admin JWT from backend. If someone trying to get “/dashboard” route without that flag, vue-router forward him to “/login” route. But I still not sure about that solution: is it possible to change this flag direct from client or from vue.js tools?

Solution :

Yes, it possible. A client with vue.js devtool can change the variable isLoggedIn.
I would prefer to use some kind of a list in the backend which contains the logged in admins at the moment. When someone try reaching the admin page send request to the backend to check if this user logged in as admin.