link1233 link1234 link1235 link1236 link1237 link1238 link1239 link1240 link1241 link1242 link1243 link1244 link1245 link1246 link1247 link1248 link1249 link1250 link1251 link1252 link1253 link1254 link1255 link1256 link1257 link1258 link1259 link1260 link1261 link1262 link1263 link1264 link1265 link1266 link1267 link1268 link1269 link1270 link1271 link1272 link1273 link1274 link1275 link1276 link1277 link1278 link1279 link1280 link1281 link1282 link1283 link1284 link1285 link1286 link1287 link1288 link1289 link1290 link1291 link1292 link1293 link1294 link1295 link1296 link1297 link1298 link1299 link1300 link1301 link1302 link1303 link1304 link1305 link1306 link1307 link1308 link1309 link1310 link1311 link1312 link1313 link1314 link1315 link1316 link1317 link1318 link1319 link1320 link1321 link1322 link1323 link1324 link1325 link1326 link1327 link1328 link1329 link1330 link1331 link1332 link1333 link1334 link1335 link1336 link1337 link1338 link1339 link1340 link1341 link1342 link1343 link1344 link1345 link1346 link1347 link1348 link1349 link1350 link1351 link1352 link1353 link1354 link1355 link1356 link1357 link1358 link1359 link1360 link1361 link1362 link1363 link1364 link1365 link1366 link1367 link1368 link1369

[Vue.js] Adding active class click Subscribe to RSS

when having trouble adding an active class when clicking a link.

there is the dynamic class setup with a click listener that passes an argument to the function but the class does not update. when not sure why. The ‘Dashboard’ link is red when page is refreshed so I know it is working to an extent.

<template>
<b-list-group>
<b-list-group-item
v-for=”(link, index) in menu”
:key=”index”
:href=”link.sectionId”
:class=”{active: link.title === selectedLink}”
:click=”isActive(link.title)”
\>
{link.title}
</b-list-group-item>
</b-list-group>
</template>

<script>

export default {
data() {
return {
selectedLink: ‘Dashboard’,
menu: [
{
title: ‘Dashboard’,
icon: labStuffs,
sectionId: ‘#’
},
{
title: ‘Lactose intolerance’,
icon: labStuffs,
sectionId: ‘#’
}
]
}
},
methods: {
isActive(title) {
this.selectedLink === title
}
}
}
</script>

<style scoped lang=”scss”>
.active {
background-color: red;
}
</style>

Expecting the background colour of clicked link to change. Only the dashboard link is red and whenever I click anything else, nothing happens.

Solution :

Here is a working example of the code.

I changed the :click to @click and the following.

methods: {
isActive(title) {
this.selectedLink = title // Had === before
}
}

https://codesandbox.io/s/vue-template-y3k12?fontsize=14

[Vue.js] Wait for some time before showing loading screen VueJS Subscribe to RSS

In VueJS, when showing the loader on each route as:

router.beforeEach((to, from, next) => {
store.commit(‘loading’, true);
next();
})

But if server loads the page in less than one second then it looks weird to show loader for this request, for just one sec.

What to wait for some time let just say 2sec or maybe 3sec and after all, if the page is not loaded yet then show loader otherwise not. So for this, I put setTimeout as:

router.beforeEach((to, from, next) => {
setTimeout(() => {
store.commit(‘loading’, true);
}, 500);
next();
})

Now the loader is always shown never goes then I also tried to move next() statement into setTimeout but then the page first waits for 500 mili-sec then the loader shows up and then hides suddenly and page loads.

to make it in a better way, any suggestions?

Solution :

I think you are not understanding the vue.js Router Navigation Guards. According to vue.js Router Docs:

Global before guards are called in creation order, whenever a navigation is triggered. Guards may be resolved asynchronously, and the navigation is considered pending before all hooks have been resolved.

In simple words, just show the loader in beforeEach as you are doing:

store.commit(‘loading’, true);

And just hide it in afterEach as:

store.commit(‘loading’, false);

That’s it.

Don’t add setTimeout in afterEach.

Hope it will help.

Solution 2:

so about the question. As of now you’re only delaying commiting ‘loading’ mutation by 500ms. To answer the question you should do something like that:

router.beforeEach((to, from, next) => {
store.commit(‘loading’, true);
setTimeout(() => {
store.commit(‘loading’, false);
}, 500);
next();
})

That will delay commiting store.commit(‘loading’, false); by 500ms. The question is do you really want to falsely delay loading of a component. Why not use transitions in that case ?

Here is example how loading next route is delayed
https://codesandbox.io/s/vue-highcharts-demo-nn3uv

[Vue.js] why am i getting 'i is not defined' error from a simple for loop in vue.js component script? Subscribe to RSS

I’m trying to taking an array, order that array by version, and then moving all versions that begin with ‘ipad’ to the end of the list.

snippet from single file vue.js component:

computed: {
orderedUsers: function () {
let newArray = sortBy(this.jobs, ‘version’).reverse()
for (i in newArray) {
if (i.version.startsWith(‘iPad’)) {
newlist.push(newlist.splice(i, 1)[0]);
}
}
return newArray
},

error:

vue.runtime.esm.js?e832:619 [vue.js warn]: Error in render: “ReferenceError: i is not defined”

Not sure if this is a js question or a vue.js question

Solution :

Try to add let i before using it in the for loop.
See example below.

for (let i in newArray) {
if (i.version.startsWith(‘iPad’)) {
newlist.push(newlist.splice(i, 1)[0]);
}
}

Solution 2:

Several problems with the original code.

The missing const/let on i
in loop should be of. Or maybe not. The following lines seem to assume that i is both the index and the entry.
newlist isn’t defined.
It seems to be trying to mutate an array whilst iterating over it.

I think you’re looking for something more like this.

const newArray = sortBy(getData(), ‘version’).reverse()
const nonIPads = []
const iPads = []

for (const entry of newArray) {
if (entry.version.startsWith(‘iPad’)) {
iPads.push(entry)
} else {
nonIPads.push(entry)
}
}

const all = […nonIPads, …iPads]

console.log(all)

function sortBy(array, property) {
return […array].sort((a, b) => {
const valueA = a[property]
const valueB = b[property]

if (valueA === valueB) {
return 0
}

return valueA < valueB ? -1 : 1
})
}

function getData() {
return [
{version: ‘f’},
{version: ‘a’},
{version: ‘d’},
{version: ‘iPad 3’},
{version: ‘iPad 1’},
{version: ‘iPad 4’},
{version: ‘e’},
{version: ‘c’},
{version: ‘g’},
{version: ‘b’},
{version: ‘iPad 2’}
]
}

[Vue.js] Webpack4 with typescript cannot resolve module Subscribe to RSS

I’v just taken over a project, which has really bad setup of vue.js with typescript. Trying to create some speed improvement but the existing webpack build (v3) didn’t allow me to do anything significant.

so i’ve updated the packages and modules to support webpack 4. Rewritten the webpack build file but come across this issue.

ERROR in ./servers/web/vue-app/router.ts
Module not found: Error: Can’t resolve ‘@web/features/home’ in ‘/Users/username/Documents/repo/prism/src/servers/web/vue-app’
@ ./servers/web/vue-app/router.ts 23:13-42
@ ./servers/web/vue-app/application.ts
@ ./servers/web/vue-app/index.ts

there is created d.ts file, which resolve some issues, tried awsome-typescript-loader, added typescript extensions in the resolve section etc but nothing solves the issue.

// Webpack Config
const path = require(‘path’);
const UglifyJsPlugin = require(‘uglifyjs-webpack-plugin’);
const MiniCssExtractPlugin = require(‘mini-css-extract-plugin’);
const VueSSRClientPlugin = require(‘vue-server-renderer/client-plugin’)
const CopyWebpackPlugin = require(‘copy-webpack-plugin’)
const { isProduction, workingDirectory, isDevelopment } = require(‘../build/environment’)
const VueLoaderPlugin = require(‘vue-loader/lib/plugin’)
const OptimizeCssAssetsPlugin = require(‘optimize-css-assets-webpack-plugin’);

module.exports = {
mode: ‘production’,
context: path.resolve(__dirname, ‘./../src’),
entry:{
vendor: [
‘babel-polyfill’,
‘braintree-web’,
‘change-case’,
‘jquery’,
‘materialize-css’,
‘moment’,
‘numeral’,
‘vee-validate’,
‘vue’,
‘vue-resource’,
‘vue-router’,
‘vue-scrollto’,
‘vue-cookie’,
‘vuex’,
‘vuex-router-sync’
],
main: “../src/servers/web/vue-app/index.ts”,
},
output: {
path: path.resolve(__dirname, ‘../dist/client’),
filename:’[chunkhash].client.js’,
publicPath: process.env.HOST_STATIC,
},
module: {
rules:[
{
test: /\.js$/,
exclude:/node_modules/,
loader: “babel-loader”,
options: {
presets: [“@babel/preset-env”]
},
},
{
test: /\.vue$/,
loader: ‘vue-loader’,
},
{
test: /\.html$/,
use: [
// apply multiple loaders and options
“htmllint-loader”,
{
loader: “html-loader”,
}
]
},
{
test: /\.ts$/,
exclude: /node_modules/,
use: [{
loader: “babel-loader”,
options: {
presets: [“@babel/preset-env”]
},
},
{
loader: ‘ts-loader’,
options: {
appendTsSuffixTo: [/\.vue/]
}
}],
}, {
test: /\.scss$/,
use: [
“style-loader”, // creates style nodes from JS strings
“css-loader”, // translates CSS into CommonJS
“sass-loader” // compiles Sass to CSS, using Node Sass by default],
]
}, {
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it uses publicPath in webpackOptions.output
publicPath: ‘../‘,
hmr: process.env.NODE_ENV === ‘development’,
},
},
‘css-loader’,
],
}
],
},
resolve: {
// options for resolving module requests
// (does not apply to resolving to loaders)
modules: [‘node_modules’],
// directories where to look for modules
extensions: [ “.js”,”.ts”, “.vue”],
alias: {
vue$: ‘vue/dist/vue.esm.js’
},
},
optimization: {
mergeDuplicateChunks: false,
splitChunks: {
// include all types of chunks
chunks: ‘all’
},
minimizer: [new UglifyJsPlugin()]

},
performance: {
hints: “warning”, // enum
maxAssetSize: 100000, // int (in bytes),
maxEntrypointSize: 400000, // int (in bytes)
assetFilter: function(assetFilename) {
// Function predicate that provides asset filenames
return assetFilename.endsWith(‘.css’) || assetFilename.endsWith(‘.js’);
}
},
devtool: “source-map”,
target: “web”, // enum
externals: [“jQuery”, “Vue”, “Typescript”],
// Don’t follow/bundle these modules, but request them at runtime from the environment
// lets you provide options for webpack-serve
stats: “errors-only”,
// lets you precisely control what bundle information gets displayed
devServer: {
contentBase: path.join(__dirname, ‘public’), // boolean | string | array, static file location
compress: true, // enable gzip compression
historyApiFallback: true, // true for index.html upon 404, object for multiple paths
hot: true, // hot module replacement. Depends on HotModuleReplacementPlugin
https: true, // true for self-signed, object for cert authority
noInfo: true, // only errors & warns on hot reload
},
plugins: [
new VueLoaderPlugin(),
new VueSSRClientPlugin({
filename: ‘../asset-manifest.json’
}),
new MiniCssExtractPlugin({
filename: isDevelopment ? ‘[name]-style.css’ : ‘[hash]/[name]-style.css’,
chunkFilename: ‘[id].css’,
}),
new OptimizeCssAssetsPlugin({
cssProcessorOptions: { discardComments: { removeAll: true } },
canPrint: true
}),
new CopyWebpackPlugin([
{
from: path.resolve(workingDirectory, ‘src’, ‘servers’, ‘web’, (isProduction ? ‘production-robots.txt’ : ‘pre-production-robots.txt’)),
to: path.resolve(workingDirectory, ‘dist’, ‘server’, ‘client’, ‘robots.txt’)
}
]),
]
}

// TS config
{
“compileOnSave”: false,
“compilerOptions”: {
“allowSyntheticDefaultImports”: true,
“lib”: [
“es6”,
“es2017”,
“dom”,
“es2015.core”
],
“jsx”: “preserve”,
“module”: “commonjs”,
“moduleResolution”: “node”,
“noEmitOnError”: false,
“noImplicitAny”: false,
“noImplicitThis”: false,
“strict”: false,
“preserveConstEnums”: true,
“removeComments”: false,
“suppressImplicitAnyIndexErrors”: true,
“target”: “es2015”,
“baseUrl”: “./src”,
“typeRoots”: [“./src”],
“types”: [],
“outDir”: “./dist/server”,
“paths”: {
“@utils/*“: [
“utils/*“
],
“@src/*“: [
“./*“
],
“@web/*“: [
“./servers/web/vue-app/*“
],
“@shared/*“: [
“./servers/shared/*“
]
}

}
}

I’ expecting the build to complete and render out the files but these issues are preventing it

Solution :

Moved the webpack config to root folder and changed confirm to look like the below with Max pointing out Paths resolve. Which seems to work.

const path = require(‘path’);
const UglifyJsPlugin = require(‘uglifyjs-webpack-plugin’);
const MiniCssExtractPlugin = require(‘mini-css-extract-plugin’);
const VueSSRClientPlugin = require(‘vue-server-renderer/client-plugin’)
const CopyWebpackPlugin = require(‘copy-webpack-plugin’)
const { isProduction, workingDirectory, isDevelopment } = require(‘./build/environment’)
const VueLoaderPlugin = require(‘vue-loader/lib/plugin’)
const OptimizeCssAssetsPlugin = require(‘optimize-css-assets-webpack-plugin’);

module.exports = {
mode: ‘production’,
context: path.resolve(__dirname, ‘src’),
entry:{
vendor: [
‘babel-polyfill’,
‘braintree-web’,
‘change-case’,
‘jquery’,
‘materialize-css’,
‘moment’,
‘numeral’,
‘vee-validate’,
‘vue’,
‘vue-resource’,
‘vue-router’,
‘vue-scrollto’,
‘vue-cookie’,
‘vuex’,
‘vuex-router-sync’
],
main: “./servers/web/vue-app/index.ts”,
},
output: {
path: path.resolve(__dirname, ‘dist/client’),
filename:’[chunkhash].client.js’,
publicPath: process.env.HOST_STATIC,
},
module: {
rules:[
{
test: /\.js$/,
exclude:/node_modules/,
loader: “babel-loader”,
options: {
presets: [“@babel/preset-env”]
},
},
{
test: /\.vue$/,
loader: ‘vue-loader’,
},
{
test: /\.html$/,
use: [
// apply multiple loaders and options
“htmllint-loader”,
{
loader: “html-loader”,
}
]
},
{
test: /\.ts$/,
exclude: /node_modules/,
use: [{
loader: “babel-loader”,
options: {
presets: [“@babel/preset-env”]
},
},
{
loader: ‘ts-loader’,
options: {
appendTsSuffixTo: [/\.vue/]
}
}],
}, {
test: /\.scss$/,
use: [
“style-loader”, // creates style nodes from JS strings
“css-loader”, // translates CSS into CommonJS
“sass-loader” // compiles Sass to CSS, using Node Sass by default],
]
}, {
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it uses publicPath in webpackOptions.output
publicPath: ‘../‘,
hmr: process.env.NODE_ENV === ‘development’,
},
},
‘css-loader’,
],
}
],
},
resolve: {
// options for resolving module requests
// (does not apply to resolving to loaders)
modules: [‘node_modules’],
// directories where to look for modules
extensions: [ “.js”,”.ts”, “.vue”],
alias: {
vue$: ‘vue/dist/vue.esm.js’,
‘@utils’: path.resolve(__dirname,’src/utils/‘),
‘@src’: path.resolve(__dirname,’src/‘),
‘@web’: path.resolve(__dirname, ‘src/servers/web/vue-app/‘),
‘@shared’: path.resolve(__dirname, ‘src/servers/shared/‘),
},
},
optimization: {
mergeDuplicateChunks: false,
splitChunks: {
// include all types of chunks
chunks: ‘all’
},
minimizer: [new UglifyJsPlugin()]

},
performance: {
hints: “warning”, // enum
maxAssetSize: 100000, // int (in bytes),
maxEntrypointSize: 400000, // int (in bytes)
assetFilter: function(assetFilename) {
// Function predicate that provides asset filenames
return assetFilename.endsWith(‘.css’) || assetFilename.endsWith(‘.js’);
}
},
devtool: “source-map”,
target: “web”, // enum
externals: [“jQuery”, “Vue”, “Typescript”],
// Don’t follow/bundle these modules, but request them at runtime from the environment
// lets you provide options for webpack-serve
stats: “errors-only”,
// lets you precisely control what bundle information gets displayed
devServer: {
contentBase: path.join(__dirname, ‘public’), // boolean | string | array, static file location
compress: true, // enable gzip compression
historyApiFallback: true, // true for index.html upon 404, object for multiple paths
hot: true, // hot module replacement. Depends on HotModuleReplacementPlugin
https: true, // true for self-signed, object for cert authority
noInfo: true, // only errors & warns on hot reload
},
plugins: [
new VueLoaderPlugin(),
new VueSSRClientPlugin({
filename: ‘../asset-manifest.json’
}),
new MiniCssExtractPlugin({
filename: isDevelopment ? ‘[name]-style.css’ : ‘[hash]/[name]-style.css’,
chunkFilename: ‘[id].css’,
}),
new OptimizeCssAssetsPlugin({
cssProcessorOptions: { discardComments: { removeAll: true } },
canPrint: true
}),
new CopyWebpackPlugin([
{
from: path.resolve(workingDirectory, ‘src’, ‘servers’, ‘web’, (isProduction ? ‘production-robots.txt’ : ‘pre-production-robots.txt’)),
to: path.resolve(workingDirectory, ‘dist’, ‘server’, ‘client’, ‘robots.txt’)
}
]),
]
}

[Vue.js] i try to mount a component in a component vue Subscribe to RSS

i i try to mount a component in a component, this component its a partial, in especifict its a paginator, which i need to integrate, i use props in the paginate component.
but there is a problem, in the console appears the next messagge “Failed to mount component: template or render function not defined.” when new in vue.js js, i using router-view i dont know if this
it is affecting en the problem the code its the next :

Pedido.vue

<template>
<div id=”pedido” style=”margin-top:50px”>
<div class=”row justify-content-center”>
<div class=”col-md-12”>
<div class=”card”>
<div class=”card-header”>
<h4 class=”card-title”>Pedidos</h4>
<div class=”card-tools” style=”position: absolute;right: 1rem;top: .5rem;”>
<button type=”button” class=”btn btn-info” >
Nuevo
<i class=”fas fa-plus”></i>
</button>
<button type=”button” class=”btn btn-primary” >
Recargar
<i class=”fas fa-sync”></i>
</button>
</div>
</div>

<div class=”card-body”>
<div class=”mb-3”>
<div class=”row”>
<div class=”col-md-2”>
<strong>Buscar por :</strong>
</div>
<div class=”col-md-3”>
<select class=”form-control” id=”fileds”>
<option value=”total”>Codigo</option>
<option value=”name”>Nombre</option>
<option value=”email”>Apellido</option>
<option value=”phone”>Telefono</option>
<option value=”address”>Direccion</option>
</select>
</div>
<div class=”col-md-7”>
<input type=”text” class=”form-control” placeholder=”Buscar”>
</div>
</div>
</div>
<div class=”table-responsive”>
<table class=”table table-hover table-bordered table-striped”>
<thead>
<tr>
<th scope=”col”>Codigo</th>
<th scope=”col”>Nombre</th>
<th scope=”col”>Apellido</th>
<th scope=”col”>Telefono</th>
<th scope=”col”>Rut</th>
<th scope=”col” class=”text-center”>Action</th>
</tr>
</thead>
<tbody>
<tr v-for=”(pedido, index) in pedidos” :key=”pedido.codigo”>
<th scope=”row”>{ index + 1}</th>
<td>{ pedido.nombre_cliente}</td>
<td>{ pedido.apellido_cliente }</td>
<td>{ pedido.telefono_cliente}</td>
<td>{ pedido.rut_cliente }</td>
<td class=”text-center”>
<button type=”button” class=”btn btn-info btn-sm”>
<i class=”fas fa-eye”></i>
</button>
<button type=”button” class=”btn btn-primary btn-sm”>
<i class=”fas fa-edit”></i>
</button>
<button
type=”button”

class=”btn btn-danger btn-sm”
\>
<i class=”fas fa-trash-alt”></i>
</button>
</td>
</tr>
<tr >
<td colspan=”6”>
<div class=”alert alert-danger” role=”alert”>No se ah encontrado resultados :(</div>
</td>
</tr>
</tbody>
</table>

<div class=”card-footer”>
<pagination
v-if=”pagination.last_page > 1”
:pagination=”pagination”
:offset=”5”
@paginate=”getData()”
\></pagination>

</div>

</div>

</div>
</div>
</div>
</div>

</div>
</template>

<script>

export default {

data(){

return{

pedidos:[],

pagination: {
current_page: 1,

},

}
},
mounted() {
console.log(‘Component mounted.’)
this.getData();

},
methods:{
getData(){
this.$Progress.start();
axios.get(“api/pedidos?page=” + this.pagination.current_page)
.then(response =>{
this.pedidos = response.data.data;
this.pagination = response.data.meta;
this.$Progress.finish();
})
.catch(e =>{
console.log(e)
this.$Progress.fail();
})
//.then(({ data }) => (this.pedidos = data));
}
},
}
</script>

this its PaginationComponent.vue:

<template>
<nav aria-label=”…”>
<ul class=”pagination justify-content-center”>
<li class=”page-item” :class=”{ disabled: pagination.current_page <= 1 }”>
<a class=”page-link” @click.prevent=”changePage(1)” >First page</a>
</li>
<li class=”page-item” :class=”{ disabled: pagination.current_page <= 1 }”>
<a class=”page-link” @click.prevent=”changePage(pagination.current_page - 1)”>Previous</a>
</li>

<li class=”page-item” v-for=”page in pages” :key=”page” :class=”isCurrentPage(page) ? ‘active’ : ‘’”>
<a class=”page-link” @click.prevent=”changePage(page)”>{ page }
<span v-if=”isCurrentPage(page)” class=”sr-only”>(current)</span>
</a>
</li>

<li class=”page-item” :class=”{ disabled: pagination.current_page >= pagination.last_page }”>
<a class=”page-link” @click.prevent=”changePage(pagination.current_page + 1)”>Next</a>
</li>
<li class=”page-item” :class=”{ disabled: pagination.current_page >= pagination.last_page }”>
<a class=”page-link” @click.prevent=”changePage(pagination.last_page)”>Last page</a>
</li>
</ul>
</nav>
</template>

<script>
export default {
props:[‘pagination’, ‘offset’],
methods: {
isCurrentPage(page){
return this.pagination.current_page === page
},
changePage(page) {
if (page > this.pagination.last_page) {
page = this.pagination.last_page;
}
this.pagination.current_page = page;
this.$emit(‘paginate’);
}
},
computed: {
pages() {
let pages = []

let from = this.pagination.current_page - Math.floor(this.offset / 2)

if (from < 1) {
from = 1
}

let to = from + this.offset -1

if (to > this.pagination.last_page) {
to = this.pagination.last_page
}

while (from <= to) {
pages.push(from)
from++
}

return pages
}
}
}
</script>

app.js

Vue.component(‘pagination’, require(‘./components/partial/PaginationComponent.vue’));

const app = new Vue({
el: ‘#app’,
router
});

this its the error

but in the extension of vue.js in the console i see the
properties of the object, this is fine,
but I do not know what I’m doing wrong, like I said I’m new to this.

extension of vue

I hope they understand me,
I would greatly appreciate the help.

Solution :

Pedido.vue

export default {
components: { pagination },
data(){ ….

maybe is this problem

Solution 2:

On the file app.js you apart from especify where you are mounting the component (in this case on the div with id “app”), you also need to tell vue.js what to render.

the component on the app.js file should include a template or a render function, that’s why you are getting the error “Failed to mount component: template or render function not defined.

You can add it like this:

const app = new Vue({
el: ‘#app’,
router,
template: ‘<pagination/>’
});

Or using the render function like this:

import Pagination from ‘./components/partial/PaginationComponent.vue’

const app = new Vue({
el: ‘#app’,
router,
render: (h) => h(Pagination)
});

[Vue.js] How can I change the number of the row using show 10/25/50/100/All entries in Vue JS? Subscribe to RSS

to change the number of the row depends on the options I select. For example, I choose 25 in my select to display all the rows on my table. This is the value I put on my select 10/25/50/100/All when I choose it automatically changes the number of rows and “Showing N to N of N entries”. How can I do that? Can somebody help me with my problem? Here’s my jsfiddle https://jsfiddle.net/rgka8m01/17/

showEntries: function() {
if (value == 10) {
return Math.ceil(this.categories.length / this.perPage)
} else if (value == 25) {
return Math.ceil(this.categories.length / 25)
} else if (value == 50) {
return Math.ceil(this.categories.length / 50)
} else if (value == 100) {
return Math.ceil(this.categories.length / 100)
} else if (value == ‘All’) {
return Math.ceil(this.categories.length / 1000)
}
}

Solution :

i mutated the code and commented the mutations above each line check this sample https://jsfiddle.net/0hn1dsc7/ and tell me if that’s what you want

showEntries: function(value) {
this.endIndex = value;
}

[Vue.js] How the data should be working with components?

I’m working on Angular and vue.js projects.

I wounder how should I working with data on components? Say there is page (is a component) with two child components that show some data.

for example:

<div id=”page-1”>
<user-list></user-list>
<product-list></products-list>
</div>

Who should fetch the data? the page component and pass to children? or each component should be fetch it own data? What are the best practices?

Solution :

It depends on how do you want to design the application. Both approaches are fine and depend on the context.

1. Smart Component vs Non-Smart (dumb) component: If you are writing a reusable component library then you should make the components dumb and expose various Input and Output properties to the consumer component [i.e. a Smart Component]. Example -

<smart-component>
<re-usable-dumb-component [inputProp1]=”property1OnSmartComponent”
[inputProp2]=”property2OnSmartComponent”
(outputProperty1FromDumbComponent)=”property1HandlerInSmartComponent($event)”>
</re-usable-dumb-component>
</smart-component>

The dumb component will not do any of the business decision, it should only render the UI as per its input property [@Input()] and output the result [@Output()] to the smart component. So it should follow this pattern -

Input Props to Dumb Components -> Dumb Components Render UI -> Emit the result [via output properties] -> Result is handled by SMart Component

The smart component will have the responsibility to fetch the data and feed the dumb component so that dumb component can do its functionality. Smart Component will also have its business logic and react on output data sent by the dumb components

2. All Smart Components: In this design, The data is fetched by the components itself. In this approach, the code/components will not be reusable as each component will fetch and make the business decision depends on the data fetched by the component. There is a possibility where the smart component will have the UI [i.e. a component which shows Dropdown along with the label] which you would like to use in a different part of the application with different data but you won’t be able to use it because of smart component is tightly coupled with the logic as per the data.

Conclusion - You should have a design by understanding the dumb vs smart component concept. Use Dumb component if you want to reuse the component. If you don’t have such need then the smart component is also fine but remember it makes the tight coupling between the data and UI and makes the component less reusable.

[Vue.js] vuejs development server compiler getting stuck at 49% Subscribe to RSS

there is a vue.js JS project which gets stuck at 49% or sometimes 62% when I run npm run serve. After it gets stuck, it never compiles and keeps at the same percentage for hours.

there is tried googling this issue so many times, but it doesn’t seem that anyone else has this problem.

Please, can anybody tell me if it is due to a package, am I doing something wrong here.

Thanks a bunch!

Solution :

I solved it temporarily by running NODE_ENV=production npm run serve, it seems it only compiles on production environment. Although didn’t find a proper solution for that.

[Vue.js] style part of the text within a list object in Vuejs Subscribe to RSS

I try many way to style part of the data object using computed, watch, and method property in vuejs. I still have no clue what can I do to make just the “healthy” word within the ‘It is healthy!’ string into different style.

<template>
<div=’container’>
<div v-for=”item in food”>
{ item }
</div>
</div>
</template>
<script>
export default{
data(){
return{
food: [
{ name: ‘fish’, message: ‘It is great!’},
{ name: ‘carrot’, message: ‘It is healthy!’},
],
}
}
}
</script>

Solution :

Here’s a working example using methods to split each message and determine if it should be highlighted:

<template>
<div class=”container”>
<div v-for=”(value, name) in food” :key=”name”>
<span v-for=”(word, index) in words(value)” :key=”index”>
<span v-if=”isHealthy(word)” class=”healthy”>{ word } </span>
<span v-else>{ word } </span>
</span>
</div>
</div>
</template>

<script>
export default {
data() {
return {
food: { fish: ‘It is great!’, carrot: ‘It is healthy!’ },
};
},
methods: {
words(string) {
return string.split(/\s+/);
},
isHealthy(string) {
return /healthy/i.test(string);
},
},
};
</script>

<style scoped>
.healthy {
color: red;
}
</style>

The above demonstrates a simple way to accomplish this - you may find corner cases where it fails. You could imagine a more complex version of words which extracts a list of sub-strings both with and without the word “healthy”. That would produce a more shallow HTML structure.

Solution 2:

I created CodePen example:

Codepen

HTML:

<div id=”app”>
<div>
<div v-for=”(value, name) in food” v-key=”name”>
{ name }: <span v-html=”isHealthy(value)”></span>
</div>
</div>
</div>

CSS:

.healthy {
color: green;
font-weight: 700;
}

JS:

new Vue({
el: “#app”,
data: () => ({
food: { fish: ‘It is great!’, carrot: ‘It is healthy!’ }
}),
methods: {
isHealthy(str) {
if(str.includes(“healthy”)) {
return str.replace(“healthy”, “<span class=’healthy’>healthy</span>”);
}
return str;
}
}
});

Solution 3:

Essentially you need to add some kind of identifying class on the word “healthy”.
This requires modifying the original food data. You can use computed to generate a new highlightedFood data, that replaces “healthy” with a <span class=”highlight”>healthy</span>. You can simply style that however you want in the style tag.

<template>
<div id=”app”>
<div v-for=”(item, index) in highlightedFood” :key=”index”>
<div v-html=”item”></div>
</div>
</div>
</template>

<script>
export default {
name: “App”,
data() {
return {
food: [
{ name: “fish”, message: “It is great!” },
{ name: “carrot”, message: “It is healthy!” }
]
};
},
computed: {
highlightedFood() {
return this.food.map(item => {
return {
name: item.name,
message: item.message.replace(
“healthy”,
“<span class=’highlight’>healthy</span>”
)
};
});
}
}
};
</script>

<style>
.highlight {
color: green;
}
</style>

Note, if you use scoped CSS, you’ll have to use the deep combinator:

<style scoped>

#app >>> .highlight {
color: green;
}
</style>

More info on deep selectors: https://vue-loader.vuejs.org/guide/scoped-css.html#deep-selectors

[Vue.js] How do perform state changes in my Vue.js page when navigating back through browser history after using `pushState`? Subscribe to RSS

I’m writing a fairly simple search page with vue.js (my first real vue.js project) and there is the following situation set up:

When a query is passed in via the URL, I parse the value out of the URL, populate the search box in the page and perform the search. This works
When the user edits text the search box, after a brief debounce pause I do the search via an API call, present the results, construct a new URL from the current page URL + the search query as a query parameter and push it into the browser history using window.history.pushState. This works
When the user presses the back button, the URL in the browser address bar changes back to the previous history entry (and therefore the previous search query), but the page does not update any of it’s content and none of The vue.js methods like created or mounted are called. I understand that this is probably intentional because the whole point of this API is to avoid a page reload, but I’d like to update the state of my page so that the search box and results match the URL in the address bar. I can’t find a way to do that.

when not using The vue.js Router as I don’t think I need it. This is a single page site with just this search on it.

Thanks!

Solution :

Thanks to Slim in the comment above, the solution to this was indeed to listen to the popstate event. I ended up with code something like this inside my created function:

var vm = this
window.addEventListener(“popstate”, function(event) {
if (event.state) {
vm.query = event.state.query
} else {
vm.query = “”
}
});

This of course assumes that I was passing the query in the state when calling pushState, which I already was!