link1096 link1097 link1098 link1099 link1100 link1101 link1102 link1103 link1104 link1105 link1106 link1107 link1108 link1109 link1110 link1111 link1112 link1113 link1114 link1115 link1116 link1117 link1118 link1119 link1120 link1121 link1122 link1123 link1124 link1125 link1126 link1127 link1128 link1129 link1130 link1131 link1132 link1133 link1134 link1135 link1136 link1137 link1138 link1139 link1140 link1141 link1142 link1143 link1144 link1145 link1146 link1147 link1148 link1149 link1150 link1151 link1152 link1153 link1154 link1155 link1156 link1157 link1158 link1159 link1160 link1161 link1162 link1163 link1164 link1165 link1166 link1167 link1168 link1169 link1170 link1171 link1172 link1173 link1174 link1175 link1176 link1177 link1178 link1179 link1180 link1181 link1182 link1183 link1184 link1185 link1186 link1187 link1188 link1189 link1190 link1191 link1192 link1193 link1194 link1195 link1196 link1197 link1198 link1199 link1200 link1201 link1202 link1203 link1204 link1205 link1206 link1207 link1208 link1209 link1210 link1211 link1212 link1213 link1214 link1215 link1216 link1217 link1218 link1219 link1220 link1221 link1222 link1223 link1224 link1225 link1226 link1227 link1228 link1229 link1230 link1231 link1232

[Vue.js] Fetch cached data Vue CLI Vuex PWA

How do I get my cached data from service worker in to the vuex store in offline mode?

The app works in offline mode in the browser, but when I add the site to home screen with the manifest.json file included, it won’t show the cached data and only the general js, css and html.

I’m having a hard time figuring out, how I get my cached data from my PWA. I already have the data cached. The problem is retrieving it back to the vuex store state called “games”, to display when the app is offline.

The vue.config.js code for caching the api call for the service worker.

module.exports = {
pwa: {
workboxPluginMode: “GenerateSW”,
workboxOptions: {
navigateFallback: “/index.html”,
runtimeCaching: [{
urlPattern: new RegExp(‘API_URL’),
handler: ‘networkFirst’,
options: {
networkTimeoutSeconds: 20,
cacheName: ‘api-cache’,
cacheableResponse: {
statuses: [0, 200],
},
},
}]
}

}
};

As you can see in the image above the code, it has stored the cache “api-cache” with the objects from the API.

Now to use this data in the cache from api-cache on my site, when the site is offline.

So my question is:
How do I get my cached data from service worker in to the vuex store in offline mode, when a user has added the app to their home screen?

Solution :

You’re thinking about this in the wrong way. You don’t need the service worker to do anything for you. It’s already doing it by providing you with a cache implementation. Instead, you need to use the navigator.onLine hook to determine if they have internet access. If not, then hydrate the store from the cache and make sure to subscribe to any mutations and push the state back into the cache, like this:

if (!navigator.onLine) {
const state = hydrateFromCache()

store.subscribe((mutation, state) => cache.setItems(state)
}

Where the hydrateFromCache method simply pulls the store in from the cache and hydrates the state of all vuex modules.

[Vue.js] VueJS Router View reactive prop not defined

I’m making Router-View based application and Im trying to create table filled with data from reactive property. So far I’m receiving an error that its not defined:

“Property or method “messages” is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property”.

Here is the script:

<script>

import axios from ‘axios’

export default {
data () {
return {
messages : [],
}
},
mounted() {
this.getMessages()
},
methods: {
getMessages() {
let uri = ‘http://localhost:8000/api/messages'
axios.get(uri).then(response => {
this.messages = response.data.data
})
},
}
}

And here is the template:

<table class=”table”>
<thead>
<tr>
<th>Title</th>
<th>Content</th>
<th>Options</th>
</tr>
</thead>
<tbody>
<tr v-for=”message in messages”>
<td>{ message.title }</td>
</tr>
</tbody>
</table>

I’ve read the VueJS documentation, looked at some other projects and I’m sure it’s right. there is parent App.js where I define the Router-View page.

Solution :

At first glance, two things stand out:

this.axios looks wrong to me (w/o knowing how the complete component looks).. You can either import axios in each .vue.js file that needs to use it, or you can import it globally..
You appear to be missing the closing ) on the axios call..

Possible solutions:

Import Axios globally
the component should look something like this:

import axios from ‘axios’

export default {
data() {
return {
messages: []
}
},
mounted() {
this.getMessages()
},
methods: {
// could also give this a shot…although I doubt this is the issue
// var self = this;
getMessages() {
let uri = ‘http://localhost:8000/api/messages';
axios.get(uri).then(response => {
// is anything shown here?
console.log(response);
return response.data.data;
// or..
// return response.data;
}).catch(err => {
alert(err);
}).then(data => {
this.messages = data;
// or…
// self.messages = data;
});
}
}
}

You could also try adding a key to the items within the loop..

<tr v-for=”(message, index) in messages” :key=”index”>
<td>{ message.title }</td>
</tr>

Solution 2:

The problem was that I forgot to close the tag at the end of the document.

[Vue.js] Webpack resolve.alias breaks import of libraries prefixed with an @

when working on a vue.js project where I’m attempting to use VuexORM. Upon initial install, I was getting an odd error:
Module not found: Error: Can’t resolve ‘../uex-orm/core’.

It should instead be ../@vuex-orm/core (notice it’s missing the @ and ‘v’ character).

I double-checked that I hadn’t mistyped my imports. Then I realized that I’d implemented an alias so that I could import from the src/ directory with an @ symbol, which I believe explains the odd-looking import. I must have misconfigured my webpack or .babelrc (very possible because I suck at both).

How should I go about setting up my webpack.config.js and/or .babelrc so that I can both use an alias for imports as well as import libraries such as @vuex-orm?

webpack.config.js

const path = require(‘path’);
const HtmlWebpackPlugin = require(‘html-webpack-plugin’);
const Dotenv = require(‘dotenv-webpack’);

module.exports = {
mode: ‘development’,
resolve: {
extensions: [‘.js’, ‘.vue’],
},
module: {
rules: [
{
test: /\.vue?$/,
exclude: /(node_modules)/,
use: ‘vue-loader’,
},
{
test: /\.js?$/,
exclude: /(node_modules)/,
use: ‘babel-loader’,
},
{
test: /\.css$/,
use: [{ loader: ‘style-loader’ }, { loader: ‘css-loader’ }],
},
{
test: /\.sass$/,
use: [
‘vue-style-loader’,
‘css-loader’,
{
loader: ‘sass-loader’,
options: {
indentedSyntax: true,
},
},
],
},
{
test: /\.svg$/,
loader: ‘svg-inline-loader’,
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: ‘./src/index.html’,
}),
new Dotenv(),
],

devServer: {
historyApiFallback: true,
},
externals: {
// global app config object
config: JSON.stringify({
apiUrl: ‘http://localhost:3000',
}),
},
}

.babelrc

{
“presets”: [
“env”,
“stage-0”
],
“plugins”: [
[“babel-plugin-root-import”, {
“rootPathSuffix”: “src/“,
“rootPathPrefix”: “@”
}]
]
}

Solution :

I went through the docs again for babel-plugin-root-import and either missed it or it was recently edited, but they mention:

If you don’t like the ~ syntax you can use the own symbol (for
example an # symbol or \ or anything you want). Using @ is not
recommended, as recent versions of NPM allow @ in package names. ~ is
the default since it’s very unlikely to conflict with anything (and
wouldn’t be expanded to HOME anyway).

So going through and changing my imports from @/_components/User’ to ~/_components/User works!

Hope this helps someone else!

[Vue.js] Vue.js / How to sort by data using buefy

I use Vue.js and Buefy to construct the front end.

there is a color field with red, black, and orange.

to sort the b-table through the color field.

However, the sorting methods I found are ascending and descending. Can I sort by the color of the fields I want?

If possible, please help me.

component

<template>
<div>
<div class=”wrapper”>
<b-table
:data=”users”>

<template slot-scope=”props”>
<b-table-column label=”id” sortable>
{props.row.id}
</b-table-column>

<b-table-column field=”content” label=”content” sortable>
{props.content}
</b-table-column>
<b-table-column field=”color” label=”color” sortable>
{props.color}
</b-table-column>
</template>
</b-table>
</div>
</div>
</template>

Solution :

Well, you can create a method that sorts the users object based on one of its keys (color):

methods: {
sortUsers() {
this.users.sort(function(a, b) {
var colorA = a.color.toUpperCase();
var colorB = b.color.toUpperCase();
return (colorA < colorB) ? -1 : (colorA > colorB) ? 1 : 0;
});
},
},

Now you can call that method by clicking on a button.

Solution 2:

Here you go https://jsfiddle.net/mazinoukah/7wdje649/3/

All you need to do is add the ‘sortable’ prop to the b-table-column component.

Vue.use(Buefy.default)

var App = new Vue({
el: ‘#app’,
data: {
switchState: true,
checkboxState: true
}
})
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src=”https://unpkg.com/buefy"></script>
<html>

<head>

<link href=”https://unpkg.com/buefy/dist/buefy.min.css" rel=”stylesheet” />

</head>

<body>
<div id=”app”>
<div class=”columns”>
<div class=”column is-2”>
<section>

<b-table
:data=”[{ id: 44, color: ‘red’ }, { id: 343, color: ‘black’ }, { id: 56, color: ‘orange’ }]“
:default-sort-direction=”defaultSortDirection”
default-sort=”user.first_name”
aria-next-label=”Next page”
aria-previous-label=”Previous page”
aria-page-label=”Page”
aria-current-label=”Current page”>

<template slot-scope=”props”>
<b-table-column field=”id” label=”ID” width=”40” sortable numeric>
{ props.row.id }
</b-table-column>

<b-table-column field=”color” label=”color” sortable>
{ props.row.color }
</b-table-column>

</template>
</b-table>
</section>
</div>
</div>
<hr>
</div>

</body>

</html>

Hope it helps :)

[Vue.js] How to scroll to a specific anchor using a router-link?

I’m trying to develop a simple website using vue.js js and so far it goes well but I’m facing the following Issue:

I’m using a router to change pages, it works, but what I need to do is: Change Page & scroll to a specific anchor.

What I tried already:

Works well:
Route to contact page or home

<router-link to=”/contact”>Contact</router-link>
<router-link to=”/“>Home</router-link>

Doesn’t work:

<router-link :to=”{ name: ‘/‘, hash: ‘#technology’ }” >Technology</router-link>

The last one works only if I’m on the home page, but whenever I change to Contact Page and try to route to “/#technology” it won’t work. It does try routing to “http://example.com/contact/#technology" instead of “http://example.com/#technology".

If I do it like that, it will just scroll to top, but not to the anchor:

<router-link to=”/#technology” Technology</router-link>

My Router Code:

const routes = [
{ path: ‘/‘, component: Home },
{ path: ‘/contact’, component: Contact }
]

const router = new VueRouter({
mode: ‘history’,

routes,
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition;

}

if (to.hash) {
return { selector: to.hash };
}
return { x: 0, y: 0 }
},

});

new Vue({
router,
}).$mount(‘#app’);

And the templates look like this ( I did remove the unnecessary code):

<template id=”home”>
<div>
Home
<div id=”technology”> <!– IT SHOULD SCROLL TO HERE –>
</div>
</template>

<template id=”contact”>
<div>
Contact Page
</div>
</template>

Solution :

i think you are on the right path.

but maybe you have mistaken the usage of Route name and path.

instead of

<router-link :to=”{ name: ‘/‘, hash: ‘#technology’ }” >Technology</router-link>

try using path instead of name

<router-link :to=”{ path: ‘/‘, hash: ‘#technology’ }” >Technology</router-link>

[Vue.js] Vue Router not matching a url with multiple dynamic values

when trying to add a nested url to my routes. So far, every route works fine except for the last one (see code below).

I also tried nesting the urls (using the children property), but was unsuccessful with that, and I don’t think that’s the approach to take here anyway, since to use an entirely separate component, and not nest the <router-view>s.

Any suggestions for what I should do? I’m not even sure how to debug. The vue.js dev tools just show a <RouterView> component, with one prop: name: “default”.

Here is my routes.js file:

import VueRouter from ‘vue-router’;

import Search from ‘./views/Search’;
import FoodItem from ‘./views/FoodItem’;
import NutrientCategory from ‘./views/NutrientCategory’;
import NutrientDetail from ‘./views/NutrientDetail’;

let routes = [
{
path: ‘/‘,
component: Search
},
{
path: ‘/:id’,
component: FoodItem
},
{
path: ‘/nutrients/:slug’,
component: NutrientCategory
},
{
path: ‘/nutrients/:slug/:nutrient-slug’,
component: NutrientDetail
}
]

export default new VueRouter({
routes,
linkActiveClass: ‘active’,
scrollBehavior (to, from, savedPosition) {
return { x: 0, y: 0 }
}
});

Solution :

The problem is that you try to use the minus sign as the parameter name:

/nutrients/:slug/:nutrient-slug

But the regular expression from the path-to-regexp package for parsing the path-pattern uses the \w character classe as the name-pattern:

\w+ matches any word character (equal to [a-zA-Z0-9_])

So use underscore instead of minus:

/nutrients/:slug/:nutrient_slug

[ https://jsfiddle.net/fhrekL25/ ]

[Vue.js] How to render the value of v-for based on the condition(v-if) provided in vue.js

I’m trying to implement the condition provided in the code. My last attempt was like in the one in the code.

<ul class = “details” v-for = “(value, propertyName) in items[this.index]“ :key = “value.id”>
<li v-if=”{propertyName} == ‘IndustryIdentifiers’”>Data not available</li>
<li v-else>{value}</li>
</ul>

How can the following be implemented:
v-if=”{propertyName} == ‘IndustryIdentifiers’”

Solution :

The { } syntax is used to wrap a JavaScript expression that should be output as text. It isn’t necessary to use the braces to access data in other contexts. In the case of a v-if the attribute value is already an expression and there’s no need to include any special characters to pull in data values.

So it’d be just v-if=”propertyName === ‘IndustryIdentifiers’”:

<ul class=”details” v-for=”(value, propertyName) in items[this.index]“ :key = “value.id”>
<li v-if=”propertyName === ‘IndustryIdentifiers’”>Data not available</li>
<li v-else>{ value }</li>
</ul>

Here I’m assuming that item[this.index] is an object rather than an array, which is implied by the way you’ve written the loop.

You could also write it like this:

<ul class=”details” v-for=”(value, propertyName) in items[this.index]“ :key = “value.id”>
<li>{ propertyName === ‘IndustryIdentifiers’ ? ‘Data not available’ : value }</li>
</ul>

You should also be able to remove the this. from the index unless it’s also declared locally.

I also wonder whether you’re intentionally creating a separate list for each value, with each list only containing a single item. Difficult to know exactly what you’re trying to achieve but I would guess that you want the loop inside the <ul> rather than on the <ul>. If you only have a single <li> (as in my second example) then you could move the v-for onto the <li>. If you want to stick to having two <li> elements with v-if/v-else then you’ll need to wrap them in a <template> tag to hold the v-for.

[Vue.js] Preventing parent site styling affecting Vue JS component styling

I’m building a vue.js JS plguin with some scoped styling, it works perfectly fine within another website when including it as a component, e.g: <my-component></my-component>.

However, the styling that I’ve added to the component is scoped to the component which means it doesn’t affect the parent’s site styling, however the parent’s site styling DOES affect my component’s styling, is there a way to prevent this without being super specific with my component’s styling and using !important for everything?

Solution :

Scoped styles work by adding a special key to the selectors. So the component would not affect other components. Parent components still may affect the component styling. And global styles also can intervene.

Well, you have 2 options if you don’t want to use !important

First, and preferred - use specific BEM naming.
It is really easy to implement by using sass (scss).
e.g.

.mycompoment{
background:#fff;

&–body{
color:#eb0b0;

&–title{
font-size:5rem;
}
}
&–footer{
position:relative;
}
//etc
}

which would compile to the following css:

.mycompoment {
background: #fff;
}

.mycompoment–body {
color: #eb0b0;
}

.mycompoment–body–title {
font-size: 5rem;
}

.mycompoment–footer {
position: relative;
}

The other option is to increase the selector’s specificity.
Try to use more direct descendant selectors. >
But still, outer css may still affect the values you don’t even think of specifying.
For example position:absolute; top:-20px; or box-sizing/display/opacity and many different props the aren’t aware of.

[Vue.js] Why does this vuejs v-for loop throw undefined error?

when a vue.js newbie trying to learn through a basic example which prints out a list of numbers which are properties of vue.js data objects.
My attempt to do this using the v-for directive in a loop only results in the error:
TypeError: “fibnum is undefined”
Please help me spot the error in my code or thinking.

Here are the files.

index.html

<!doctype html>
<html>
<head>
<meta content=”text/html;charset=utf-8” http-equiv=”Content-Type”>
<meta content=”utf-8” http-equiv=”encoding”>
<script src=”/vue.js”></script>
</head>
<body>
<div id=”fib-triangle”>
<ol>
<li v-for:”fibnum in fib_row”>
{fibnum.num}
</li>
</ol>
</div>
</body>
<script src=”./trivue.js”></script>
</html>

trivue.js

(function(){

‘use strict’

//Create ‘triangle’ component to hold fib-numbers
var triangle= new Vue({
el:’#fib-triangle’,
data:{ fib_row:[{num: 1}, {num: 1}, {num: 2}, {num: 3}, {num: 5}, {num: 8}, {num: 10}] }
});

})()

Solution :

So, the right answer should be like:

<html>
<head>
<meta content=”text/html;charset=utf-8” http-equiv=”Content-Type”>
<meta content=”utf-8” http-equiv=”encoding”>
<script src=”/vue.js”></script>
</head>
<body>
<div id=”fib-triangle”>
<ol>
<li v-for=”fibnum in fib_row”>
{fibnum.num}
</li>
</ol>
</div>
</body>
<script src=”./trivue.js”></script>
</html>

[Vue.js] How can I efficiently write a fallback to grab an object from localstorage in the event of an axios promise failing?

when trying to create a progressive web app (I think).
there is bound a button in my markup to a method that gets an object from a last.fm api

to write a fallback in case there is no response from the API to grab the same object from a previously cached request.

However I noticed two things are wrong
1. The cacheTopArtists function isn’t saving my object into my localstorage correctly.

new Vue({
el: ‘#LastFM’,
data() {
return {
myArtists: null
}
},
mounted() {
loadCachedTopArtists: {
if (localStorage.cachedArtists) {
this.myArtists = localStorage.cachedArtists;
}
}
},
methods: {
getTopArtists: function(e) {
axios
.get(“https://ws.audioscrobbler.com/2.0/?api\_key=2c5c5c19e5d21ce9cf86b13712a1bbed&format=json&method=user.getTopArtists&user=El\_Mayo&period=overall&limit=200")
.then(response => (this.myArtists = response.data.topartists.artist))
.catch(error => console.log(error))
//if there is an error nothing should happen an this.myArtists is still equal to the localStorage.cachedArtists from line 31 (?);

},
cacheTopArtists: function(e) {
localStorage.setItem(‘cachedArtists’, JSON.stringify(this.myArtists));
}
},
computed: {
backgroundImage: function() {
return (artist) => artist.image.find(size => size.size === ‘large’)[‘#text’]
}
}
})

The cachedArtists key exists but is null. Even though i set myArtists : null i think the condition is still being met as the code I wrote inside is displaying

I think this is having a knockon effect on my mounted() function which should fill my empty object with the localstorage version on page load

there is tried moving the getTopArtists method to the mounted() object so it runs on page load

there is also tried setItem without stringifying the myArtists object.

Here is the pen with the js and html
https://codepen.io/anon/pen/GaEaKp

No error messages, except cachedArtists being null

Solution :

1st - why should cacheTopArtists save something if it is never called? It should be called after a successful request.

2nd - if you want “fallback” behavior on page load then you should put you cache-loading routines to axios .get(…) .catch(…) handler. And call getTopArtists inside the mounted hook.

But the most efficient way to do this is to implement an API module and use axios interceptors to achieve transparent caching in case of successful response and intercept fails and return caches.

https://github.com/axios/axios#interceptors