Software
What's the use of webpack in vue CLI?
Ok, so I'm not being able to comprehend what value "webpack" gives in conext of Vue CLI.
I just installed vue cli globally.
then I made a directory manually and created a c1.vue file in it. With the template, script and style tags and related code.
and i compiled it using the command vue build --prod --lib c1.vue and it produced a c1.css and a c1.js file(s).
I simply add these files to my custom index.html file and use vue using a cdn and everything works !
So what's the point of webpack ?
Can I call a method from a watch and mounted?
I have a functionality (getAllData which does an external data query) which I need to call at two occasions: when the component is mounted and when a prop changes.
I am however getting a TypeError: this.getAllData is not a function when using it in a watch and in mounted.
Since methods can be called from methods, I am wondering whether this is true for methods being called from components such as watch or mounted.
My (simplified) instance is below:
export default { props: ['triggerReload'], data: function () { return { // some variables } }, watch: { triggerReload: this.getAllData() }, methods: { getAllData: function () { // this function correctly fetches external data } }, mounted: this.getAllData() }My workaround will be to either duplicate the code of the function (which is not DRY) or to call an external function (defined outside the Vue instance - which is probably also an anti-pattern) EDIT: this is a component so I do not know how to call an external function and reference the instance (it is not instantiated by var vm = new Vue(...))
Typescript emitted no output when running unit test
I have declared saveral variables in .d.ts files. It works right when running pack or build commands. But when I run unit test cases, things go wrong.
framework: vue+typescript+webpack
test runner: karma
I assume the problem is including .d.ts files is src, and I tried to exclude them. below is my regexp:
/\.\/(?!main\.ts)(?!((\S*\.d\.ts)|(\S*\.scss))$)/tested already, seems it doesn't work. keep throwing these exceptions. drvies me crazy.
anyone knows how to solve this issue?
How to test async method in Vuejs's component when using jest and avoriaz
For instance, I have a component looks like this.
<template> <div id="app"> <button class="my-btn" @click="increment">{{ val }}</button> </div> </template> <script> export default { data: { return { val: 1, }; }, methods: { increment() { fetch('/echo/html/').then((response) => { this.val++; }).catch((error) => { console.log(error); }); }, }, } </script>You can also check this fiddle as a simplified demo
In order to do unit test for this component, I wrote code like this.
// Jest used here test('should work', () => { // wrapper was generated by using avoriaz's mount API // `val` was 1 when mounted. expect(wrapper.data().val).toBe(1); // trigger click event for testing wrapper.find('.my-btn')[0].trigger('click'); // `val` should be 2 when the button clicked. // But how can I force jest to wait until `val` was set? expect(wrapper.data().val).toBe(2); });It didn't work since expect ran before fetch's done, but I've no idea how to let jest wait until promise function done.
So how can I test in this use case?
In Vue.js, POST method is not working using axios.post method
I am new to Vue.js. I am trying to create a simple login form, that will submit the values to a ASP.net Web API. When I click the submit button, I do not see the form data under POST. I am using Fiddler to check the POST data, which shows nothing under "WebForms" tab. On the ASP.net Web API the form object is shown as null. (For the sake of simplicity, I am passing hard code value to the post fields)
Following is the HTML inside login.vue
<template> <v-ons-page> <v-ons-toolbar> <div class="center">Log in </div> </v-ons-toolbar> <p style="text-align: center"> <img src="../assets/Image logo transparent.png" /> </p> <p style="text-align: center"> <v-ons-input modifier="underbar" placeholder="Username" type="text" v-model="user.name" float></v-ons-input> </p> <p style="text-align: center"> <v-ons-input modifier="underbar" type="password" placeholder="Password" v-model="user.password" float></v-ons-input> </p> <p style="text-align: center"> <v-ons-button @click="login($event)"> <div>Log in</div> </v-ons-button> </p> </v-ons-page> </template>Following is the section where POST happens through axios
<script> import axios from 'axios' export default { name: 'login', data: { username: '', password: '' }, computed: { user: { get () { return this.$store.state.user } } }, methods: { login (event) { axios.post('http://localhost:54977/api/Roles', { username: 'Fred', password: 'Flintstone'}) .then(response => { this.$ons.notification.alert('Logeed in. Hurrey!!') }) .catch(e => { this.$ons.notification.alert('No donut for you. :(') this.errors.push(e) }) } } } </script>How to correctly import css/styl files into a JavaScript file?
The file I want to import has this location: src/assets/css/global.styl.
I import it into vue files like this:
src/App.vue
<style lang="stylus"> @import './assets/css/global'I recently installed Storybook for Vue. I'm trying to import global.styl into the index.js file of Storybook for Vue:
src/stories/index.js
import '../assets/css/global.styl' // this works wine
However, I get this error:
ERROR in ./src/assets/css/global.styl Module not found: Error: Can't resolve './assets/img/buttons/radio-selected.svg' in 'E:\alex\vreditor\src\assets\css' @ ./src/assets/css/global.styl 7:12959-13009 @ ./src/stories/index.js @ ./.storybook/config.js @ multi ./~/@storybook/vue/dist/server/config/polyfills.js ./~/@storybook/vue/dist/server/config/globals.js (webpack)-hot-middleware/client.js?reload=true ./.storybook/config.jsWhy is this? and how to solve it?
NOTE: Seems like global.styl is being correctly imported. The problem are the relative paths inside the file:
input[type="radio"]:checked + label { &::before { background-image: url('./assets/img/buttons/radio-selected.svg') // Storybook can't find this. } }How can I disable back button on the browser with vue component?
My vue component like this :
<template> <span class="rating"> ... </span> </template> <script> export default { props: { 'star': null }, ... } </script>If the component is running I want to disable button back in the browser. So the user can not go back to the previous page
How can I do it?
Webpack with babel-loader not emitting valid es5
I have a webpack config that is based off https://github.com/vuejs-templates/webpack-simple/blob/master/template/webpack.config.js It uses vue-loader and babel-loader. The issue is I cannot get it to generate ES5 code so that it will work in the most broad range of clients.
If I use the ES2015 preset, webpack.optimize.UglifyJsPlugin fails to minify the output because Uglify can only handle ES5 (not counting the harmony branch). The errors are similar to: Unexpected token: punc (() and occur in multiple files.
I can work around this by using babili-webpack-plugin which will minify the ES6 code but is very slow. However, when I deploy this code, I see errors being reported back saying Block-scoped declarations (let, const, function, class) not yet supported outside strict mode so I know they are older clients choking on ES6 code.
How can I get proper ES5 code output from babel-loader? I have tried multiple presets, with or without the transform-runtime plugin. Config below:
const webpack = require('webpack'); const globEntries = require('webpack-glob-entries'); const _ = require('lodash'); const path = require('path'); const BabiliPlugin = require("babili-webpack-plugin"); const env = process.env.NODE_ENV; let entries; if (env === 'production') { entries = globEntries('./src/**/vue/*.js'); } else { entries = _.mapValues(globEntries('./src/**/vue/*.js'), entry => [entry, 'webpack-hot-middleware/client?reload=true']); } module.exports = { entry: entries, output: { path: '/', ///no real path is required, just pass "/" publicPath: '/vue', filename: '[name].js', }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', options: { loaders: { scss: 'vue-style-loader!css-loader!sass-loader', sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax', }, // other vue-loader options go here }, }, { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', query: { presets: ['es2015'], plugins: ['transform-runtime'], }, }, }, { test: /\.(png|jpg|gif|svg)$/, loader: 'file-loader', options: { name: '[name].[ext]?[hash]', }, }, ], }, resolve: { alias: { vue$: 'vue/dist/vue.esm.js', }, }, plugins: [ new webpack.HotModuleReplacementPlugin(), // Enable HMR new webpack.NoEmitOnErrorsPlugin(), ], performance: { hints: false, }, devtool: '#eval-source-map', }; if (env === 'staging' || env === 'production') { //module.exports.devtool = env === 'staging' ? '#source-map' : false; module.exports.devtool = '#source-map'; module.exports.output.path = path.resolve(__dirname, './src/v1/parse/cloud/public/vue'); // http://vue-loader.vuejs.org/en/workflow/production.html module.exports.plugins = (module.exports.plugins || []).concat([ new webpack.DefinePlugin({ 'process.env': { NODE_ENV: `"${env}"`, }, }), new webpack.optimize.UglifyJsPlugin({ sourceMap: true, compress: { warnings: false, }, }), // new BabiliPlugin(), new webpack.LoaderOptionsPlugin({ minimize: true, }), ]); }Vue.js data value not updating when adding new value
When new bars value are set, the data is not updated. Please check below;
I'm planning to do dynamic bars and buttons. Once the buttons are clicked, the new values will be updated to bars values.
Here is the link
HTML
<h1><span>Vue.js</span> Progress Bar</h1> <div id="app"> <div v-for="(index, bar) in bars" class="shell"> <div class="bar" :style="{ width: bar + '%' }" .> <span>{{ bar }}%</span> <input type="radio" id="radio-bar" value="{{ index }}" v-model="picked" v-on:change="set(index)"> </div> </div> <span v-for="(index, button) in buttons"> <button value="{{ button }}" @click.prevent="makeProgress(button)">{{ button }}</button> </span> <br> <p>Selected Bar: {{ picked }}</p> <p>Button Value: {{ buttonVal }}</p> </div>JS
var dataURL = 'http://pb-api.herokuapp.com/bars'; var vm = new Vue({ el: "#app", data: { maxColor: "#F22613", bars: [], buttons: [], limit: 0, selectedBar: 0, buttonVal: 0 }, methods: { fetchData: function(params) { this.$http.get(dataURL, function(data) { this.$set('bars', data.bars); this.$set('buttons', data.buttons); this.$set('limit', data.limit); console.log(params); }); }, set: function(index) { this.selectedBar = index; }, makeProgress: function(button) { var self = this; self.buttonVal += button; this.reachMax(); Vue.set(this.bars, 0, 55); }, reachMax() { if(this.buttonVal >= this.limit){ alert('Reached Limit' + this.limit) } } }, created: function() { this.fetchData(); } });axios set headers in config vue js
Right now I use axios like this:
import axios from 'axios' axios.get(apiObjUrl, { headers: { 'Content-type': 'application/x-www-form-urlencoded', } }) .then(({data}) => {How do I set global axios header? (I need to set localization header to use in all my requests)
Laravel Vue SPA vs SSR
Many laravel/vue tutorials use ajax calls to get the data. It seems that the SPA is completely isolated from Laravel. I.e. Laravel is just a data API and the vue app could also simply be hosted on a third party external server (e.g. AWS S3). Is this the recommended way, or should I rather use Laravel for Routing and have separate views that implement individual components and already included data instead of using a SPA?
insert tab pages inside v-ons-tabbar
Here's my component.
<template> <v-ons-page> <v-ons-tabbar :visible="true" :tabs="tabs" position="top"> </v-ons-tabbar> </v-ons-page> </template> <template id="pendingPage"> <v-ons-page> <p>pending items</p> </v-ons-page> </template> <template id="completedPage"> <v-ons-page> <p>completed items</p> </v-ons-page> </template> <script> import Vue from 'vue'; const pendingPage = { template: '#pendingPage' }; const completedPage = { template: '#completedPage' }; export default { data() { return { activeIndex: 0, tabs: [ { label: 'Pending', page: pendingPage }, { label: 'Completed', page: completedPage } ] }; } }; </script>Expected: I expect my component to render two tabs - Pending & Completed.
Problem: It only renders completedPage.
What I am doing wrong here?
How access Vue Js computed properties?
I have the next code with vuejs, i call axios method post and set the authenticated user correctly(cosole show the user), but when i call the computed property in the component the user is empty
export default { data() { return { isAuth: null, } }, computed: { authenticatedUser () { return this.getAuthenticatedUser() } }, created() { this.isAuth = this.$auth.isAuthenticated() this.setAuthenticatedUser() }, methods: { setAuthenticatedUser () { axios.get('/api/user') .then(response => { this.$auth.setAuthenticatedUser(response.data) console.log(this.$auth.getAuthenticatedUser()) }) }, getAuthenticatedUser(){ return this.$auth.getAuthenticatedUser() } }, router }And this my code for get the authenticated user
export default function (Vue) { let authenticatedUser = {}; Vue.auth = { //set token setToken (token, expiration) { localStorage.setItem('token', token) localStorage.setItem('expiration', expiration) }, //get token getToken() { var token = localStorage.getItem('token') var expiration = localStorage.getItem('expiration') if( !token || !expiration) return null if(Date.now() > parseInt(expiration)){ this.destroyToken() return null } else{ return token } }, //destroy token destroyToken() { localStorage.removeItem('token') localStorage.removeItem('expiration') }, //isAuthenticated isAuthenticated() { if(this.getToken()) return true else return false }, setAuthenticatedUser(data){ return authenticatedUser = data; }, getAuthenticatedUser(){ return authenticatedUser; }, } Object.defineProperties(Vue.prototype, { $auth: { get() { return Vue.auth } } }) }When i not use the computed property
When i use the computed property in the model
Append array inside object using $set
I have an object and the structure looks like this
obj: { 1: { 'a': [ [] ], 'b': [ [] ] } }Now, in watcher, I am trying to append 'c' => [ [] ] to this object.
I tried using this.obj[key]['c'] = [ [] ], but it doesn't watch changes on the props when I do it this way. I am almost sure that I need to use $set
this.$set(this.obj, key, { ['c']: [ [] ] }) - using this actually watches it, however it removes 'a' and 'b' properties entirely.
What is the proper way of using $set
(vuejs)this.$router.go() doesn't work in safari of iOS 10.3.2 only
It's works fine in Android's broswer or iPhone's Safari with other versions of iOS. But in 10.3.2, doesn't jump to target page.
Vue.js routing with Express
I've created a portfolio here https://temp-portfolio.herokuapp.com. My issue is that when a user refreshes a page other than index.html or goes straight to another link such as https://temp-portfolio.herokuapp.com/projects the routing doesn't render. I've set up everything using Node.js and Express on Heroku following this guide https://medium.com/@sagarjauhari/quick-n-clean-way-to-deploy-vue-webpack-apps-on-heroku-b522d3904bc8.
I tried rewriting the server to this https://stackoverflow.com/a/44226999/4178637 but the app crashes.
server.js
var express = require('express'); var path = require('path'); var serveStatic = require('serve-static'); app = express(); app.use(serveStatic(__dirname)); var port = process.env.PORT || 5000; app.listen(port); console.log('server started '+ port);index.js
import Vue from 'vue' import Router from 'vue-router' import Nav from '@/components/Nav' import Home from '@/components/Home' import Projects from '@/components/Projects' import Urban from '@/components/Urban' import Seizure from '@/components/Seizure' import Explosion from '@/components/Explosion' import Decadence from '@/components/Decadence' import Threshold from '@/components/Threshold' Vue.use(Router) Vue.component('app-nav', Nav) export default new Router({ routes: [ { path: '/', name: 'Home', component: Home }, { path: '/projects', name: 'Projects', component: Projects }, { path: '/projects/urban', name: 'Urban', component: Urban }, { path: '/projects/seizure', name: 'Seizure', component: Seizure }, { path: '/projects/explosion', name: 'Explosion', component: Explosion }, { path: '/projects/decadence', name: 'Decadence', component: Decadence }, { path: '/projects/threshold', name: 'Threshold', component: Threshold } ], mode: 'history' })main.js
import Vue from 'vue' import App from './App' import router from './router' import './assets/styles/styles.scss' Vue.config.productionTip = false new Vue({ el: '#app', router, template: '<App/>', components: { App } })Can't access data variable inside watcher, inside .map()
My root looks like this. I have defined types and history variables inside data and in watch, I am trying to access another variable rather than the one I am watching. Trying to access history variable outside .map() works however using it inside .map() returns undefined
new Vue({ el: '#root', data: { types: {}, history: {} } watch: { types: { handler(obj) { console.log(this.history) // works types.map(function(val) { console.log(this.history) // undefined }) } } } }Cannot access other data values inside watch
In my root, i have a setup like this,
new Vue({ el: '#root', data: { types: {}, history: {} } watch: { types: { handler(obj) { console.log(this.history) // gives me undefined } } } }this.history throws undefined even though it is initialised as an empty object in data. Also, in this watcher, I can not use my methods inside methods: {}, it also says undefined.
However, if I do $vm0.history in my console, it doesn't say undefined.
What is the proper way of achieving this?
vue js: How get parent id in directive (eg v-if)
How get id from class="video" and use in directive v-if?
Should my Vue.js code have multiple small instances or a single big instance?
I'm starting with vue.js. My question is about design patterns.
Should I have multiple Vue instances like this one:
var example = new Vue({ el: '#post-list', data: { posts: [ { title: 'Foo' }, { title: 'Bar' } ] } }); var example2 = new Vue({ el: '#post-list2', data: { posts: [ { title: 'Foo' }, { title: 'Bar' } ] } });Or should I try to group my Vue code inside a big #app element like this:
var app= new Vue({ el: '#app', data: { posts1: [ { title: 'Foo' }, { title: 'Bar' } ], posts2: [ { title: 'Foo' }, { title: 'Bar' } ] } });I'm looking for code maitenance and performance. What are the advantages of each approach? Is there a better pattern to follow?