Showing posts with label VUE.JS && VUE-CLI. Show all posts
Showing posts with label VUE.JS && VUE-CLI. Show all posts

Thursday, 17 June 2021

Vue how to change page title and favicon dynamically

favicon is the little icon displayed in browser tab

page title the title tag in header <header><title></title></head> is the description that will show up beside favicon in browser tab


by default, those two are located in VueProject/public/favicon.ico and VueProject/public/index.html

index.html contains <div id="app"></div> tag that Vue.JS compiled code will be injected there. Because in main.js there is new Vue({el:'#app' ....})


 https://stackoverflow.com/questions/59152176/how-to-change-page-favicon-title-with-vue-router


The page title can be dynamically changed in code by 

using :

 document.title = `APPLICATION_NAME - ${to.meta.title}`;
Or changed with route's meta tag info :

In addition to adding the 'meta' tag, you have to create a method that recieves the data inside this tag and apply the needed modifications.

  1. Add the 'meta' tag, like you just did above, but also add 'icon' property to it.

    {
     path: "/login",
     name: "Login",
     component: LoginComponent,
     meta: {
       title: "Login",
       icon:"/lock.png" 
     }
    }
    
  2. Go to your main *.vue file into which the various components will be routed through. This file is the one which has the element inside of it. In it, add a $route watcher in the scripts section of the file:

    watch: {
      $route(to) {
         document.title = `APPLICATION_NAME - ${to.meta.title}`;
         const link = document.querySelector("[rel='icon']")
         link.setAttribute('href',to.meta.icon)
      }
    }




Vue JS Errors in browser console, requests to /sockjs-node/info?t=1555629946494

 https://stackoverflow.com/questions/55754906/errors-in-browser-console-requests-to-sockjs-node-infot-1555629946494



https://github.com/vuejs/vue-cli/issues/1616


I finally fixed it using the devServer.public configuration option.

Below is my vue.config.js file:

module.exports = {
    devServer: {
        disableHostCheck: true,
        port: 4000,
        public: '0.0.0.0:4000'
    },
    publicPath: "/"
}

I got my answer from reading this.



// NOTE: if 0.0.0.0 : 4000(port #) does not work, use localhost:4000 instead

Wednesday, 26 May 2021

Vue JS how to import component and use tag name for component including bale and wepack

 https://vuejs.org/v2/guide/components-registration.html

Global Registration

So far, we’ve only created components using Vue.component:

Vue.component('my-component-name', {
  // ... options ...
})

These components are globally registered. That means they can be used in the template of any root Vue instance (new Vue) created after registration. For example:

Vue.component('component-a', { /* ... */ })
Vue.component('component-b', { /* ... */ })
Vue.component('component-c', { /* ... */ })

new Vue({ el: '#app' })
<div id="app">
  <component-a></component-a>
  <component-b></component-b>
  <component-c></component-c>
</div>

Local Registration

Global registration often isn’t ideal. For example, if you’re using a build system like Webpack, globally registering all components means that even if you stop using a component, it could still be included in your final build. This unnecessarily increases the amount of JavaScript your users have to download.

In these cases, you can define your components as plain JavaScript objects:

var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }

Then define the components you’d like to use in a components option:

new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

Or if you’re using ES2015 modules, such as through Babel and Webpack, that might look more like:

import ComponentA from './ComponentA.vue'

export default {
  components: {
    ComponentA
  },
  // ...
}// Through babel and wepack compoenent A tag is still as the following  <component-a></component-a>

Wednesday, 12 May 2021

Vue JS npm run serve at specified port on Dev Mode

vue.config.js
module.exports = {
    devServer: {
        port: 3454    } 

}


https://reactgo.com/change-port-number-vue/ 

Tuesday, 11 May 2021

Vuex Actions && Commits && MappedGetters all in 1

 https://vuex.vuejs.org/guide/actions.html#dispatching-actions


const store = new Vuex.Store({

  state: {

    count: 0

  },

// synchoronus, save to local stroage state.count

  mutations: {

    increment (state) {

      state.count++

    }

  },

// asynchoronus call mutation // commits calls mutation(store.commit)

  actions: {

    increment ({ commit }) {

     commit('increment')

    }

  }

})


// Component

this.$store.dispatch('increment')


--------------------------------------------------------------

store folder /

const store = new Vuex.Store({

  state: {

    todos: [

      { id: 1, text: '...', done: true },

      { id: 2, text: '...', done: false }

    ]

  },

// Get from cache

  getters: {

    doneTodos: state => {

      return state.todos.filter(todo => todo.done)

    }

  }

})


Vue component (creates computed variable "doneTodoScount"

computed: {

  doneTodosCount () {

    return this.$store.getters.doneTodosCount

  }

}



This is equivalent to 

https://vuex.vuejs.org/guide/getters.html#method-style-access

import { mapGetters } from 'vuex'


export default {

  // ...

  computed: {

    // mix the getters into computed with object spread operator

    ...mapGetters([

      'doneTodosCount',

      'anotherGetter',

      // ...

    ])

  }

}





Thursday, 4 February 2021

Spin up a new machine with Vue JS and VUE CLI && Useful Tools

 1. Hyper-v 

                - create external switch

                 - create ubuntu vm


2. In VM, ifconfig to find out IP

3. Install ssh server in VM https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/

4. Install node-js(JS able to run in backend) and npm (pkg manager front-end) https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-18-04

5. Install vue. JS and Vue-CLI(Vue comnad line tool) https://linuxhint.com/install-vue-ubuntu/

6. Existing Vue Project contains package.json that contains vue-cli run in dev mode 

{
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build"
  }
}
7.  cd in to project, use npm install, then npm run serve : https://cli.vuejs.org/guide/cli-service.html#using-the-binary
8. Install tmux, start by calling tmux new, 
tmux ls (is list of session), tmux attach -t 0(session id)
https://cli.vuejs.org/guide/cli-service.html#using-the-binary

9. In actual host, to connect to vm via ssh jxiang@vmIP
10. In visual studio code, to connect to VM use SSHFS, ctrl p open visual studio code 
command pallet, >sshfs create configuration
In configuration add as workspace folder.


Wednesday, 18 November 2020

Vue - Front End, Laravel back end Dev Server and Production differences

 Vue development server requires specification on port and address:

vue.config.js:

const port = process.env.port || process.env.npm_config_port || 9527 // dev port

// dev port
const host = '192.168.20.23';
module.exports = {
  /**
   * You will need to set publicPath if you plan to deploy your site under a sub path,
   * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
   * then publicPath should be set to "/bar/".
   * In most cases please use '/' !!!
   * Detail: https://cli.vuejs.org/config/#publicpath
   */
  publicPath: '/',
  outputDir: 'dist',
  assetsDir: 'static',
  lintOnSave: process.env.NODE_ENV === 'development',
  productionSourceMap: false,
  devServer: {
    port: port,
    host: host,


When vue started in development, it will server at specified port and host.

When vue is deployed to a server, I.E /var/html/vue. It will be served for http port 80 or https port 443 based on server configuration. I.E if server is <virtualhost: *443> DocumentRoot: /var/html/vue then the application will be HTTPS.


For development or production, Vue always need to specify API end point :

.env.production or .env.development file

VUE_APP_BASE_API = 'http://192.168.20.23:8000' Or 'https://myproduction'



For Laravel it works similarly, 

for development, laravel needs to specify where to start development server:

php artisan serve --host=0.0.0.0 --port=8080

and it needs to specify APP_URL in .env, and app.php


When deployed Laravel to production,

when laravel project folder is deployed to /var/html/Laravel/, it depends on whether server is servering HTTP or HTTPS <virtualHost:443>

When serving HTTPS, laravel is HTTPS. Of course when both Vue and Laravel are served, .htaccess file needs to be reconfigured so that Server knows when or which route to use laravel index.php router or Vue Router.

When both served at same port, there is no need to worry about CORS, but for development, if Vue starts at 9527, and laravel starts at 8000, then CORS headers need to be added( By default, Server blocks resource access for different origin , the port and URL has to be same)


For laravel to add CORS :

        // CORS, SERVER_ADDR is server address environment variable, when it is not found, if found not set, null will be used, it will use  'http://192.168.20.23:9527'

        $server_addr = env('SERVER_ADDR', 'http://192.168.20.23:9527');

        header('Access-Control-Allow-Origin: ' . $server_addr);

        header('Access-Control-Allow-Headers: *');

        header('Access-Control-Allow-Method: GET, POST, PUT, DELETE, OPTIONS');

https://www.interserver.net/tips/kb/deploy-laravel-project-apache-ubuntu/





Wednesday, 25 March 2020

Vue error handler (can be used with Vuex)

https://vuejs.org/v2/api/#errorHandler

errorHandler

  • Type: Function
  • Default: undefined
  • Usage:
    Vue.config.errorHandler = function (err, vm, info) {
      // handle error
      // `info` is a Vue-specific error info, e.g. which lifecycle hook
      // the error was found in. Only available in 2.2.0+
    }
    Assign a handler for uncaught errors during component render function and watchers. The handler gets called with the error and the Vue instance.

Vue Element dateoptions to filter dates

   
    <template>
        <el-date-picker
        v-model="row.transaction_date"
        type="date"
        style="width:80%;"
        :picker-options="expireTimeOption"
        >
        </el-date-picker>
     </template>

     ....
       computed : {
     /*
     * VUE ELEMEENT picker-options (https://element.eleme.io/#/en-US/component/datetime-picker#datetimepicker)
     */
    expireTimeOption: function () {
        // Current cutoff date PST string
        var current_date = this.cutoff // date from backend
        return  {
            /*
            * Whether to Disable date in the date picker
            * @param DateObject  Date      The date supplied from date picker in PST  Sat May 02 2020 00:00:00 GMT-0700 (Pacific Daylight Time)
            */
            disabledDate(date) {
              // PST
              console.log('Cut off date is ' + current_date)
              if ( ! current_date) {
                return false
              }
              // Make cut off Date into Date()
              var current_cut_off_date = new Date(current_date)
              // Get Today's date
              var today = new Date()
              // Find out last month of current date
              var resulting_date = new Date(current_date) // current date
              resulting_date.setDate(1) // going to 1st of the month
              resulting_date.setHours(-1) // going to last hour before this date even started.
             
              // If Today is less than cutoff date do nothing
              if (today.getTime() <= current_cut_off_date.getTime()) {
                // Allow transaction date to be last month but not the month before that
                // // Find out last month of resulting_date
                var prev_resulting_date = resulting_date // current date
                prev_resulting_date.setDate(1) // going to 1st of the month
                prev_resulting_date.setHours(-1) // going to last hour before this date even started.
                return date.getTime() <= prev_resulting_date.getTime()
              }

              return date.getTime() <= resulting_date.getTime()
            }
        }

      }
  },


Other references :
https://www.cnblogs.com/steamed-twisted-roll/p/9755651.html
  <el-date-picker
    v-model="exCheckDate"
    type="date"
    :picker-options="pickerOptions"
    value-format="yyyy-MM-dd"
    placeholder="Please select">
  </el-date-picker>

  // js中定义范围
  // picker-options的值是一个对象,他的disabledDate属性可以设置禁用日期,有一个参数是当前选择的日期
  data () {
    return {
      pickerOptions: {}, // 日期设置对象
    }
  },

  created {
   // disabledDate 为true表示不可选,false表示可选
   this.pickerOptions.disabledDate = disabledDate (time) {
      // 设置可选择的日期为今天之后的一个月内
      let curDate = (new Date()).getTime()
      // 这里算出一个月的毫秒数,这里使用30的平均值,实际中应根据具体的每个月有多少天计算
      let day = 30 * 24 * 3600 * 1000
      let dateRegion = curDate + day
      return time.getTime() < Date.now() - 8.64e7 || time.getTime() > dateRegion

      // 设置选择的日期小于当前的日期,小于返回true,日期不可选
      // return time.getTime() < Date.now() - 8.64e7
    },
  }

Vuex with webpack to load every file in modules, and auto import them

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'

Vue.use(Vuex)

// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)

// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  // set './app.js' => 'app'
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})

const store = new Vuex.Store({
  modules,
  getters
})

export default store

Vuex

https://vuex.vuejs.org/guide/getters.html
.
const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})

Node module export/import && JS export/import with default and named

Bump
The module.exports or exports is a special object which is included in every JS file in the Node.js application by default. module is a variable that represents current module and exports is an object that will be exposed as a module. So, whatever you assign to module.exports or exports, will be exposed as a module.
var msg = require('./Messages.js');

console.log(msg);

JS export
The export statement is used when creating JavaScript modules to export functions, objects, or primitive values from the module so they can be used by other programs with the import statement.

There are two types of exports:
  1. Named Exports (Zero or more exports per module)
  2. Default Exports (One per module)
// file test.js
let k; export default k = 12;
// some other file
import m from './test'; // note that we have the freedom to use import m instead of import k, because k was default export
console.log(m);        // will log 12


// In childModule1.js
let myFunction = ...; // assign something useful to myFunction
let myVariable = ...; // assign something useful to myVariable
export {myFunction, myVariable};
// In childModule2.js
let myClass = ...; // assign something useful to myClass
export myClass;
// In parentModule.js
// Only aggregating the exports from childModule1 and childModule2
// to re-export them
export { myFunction, myVariable } from 'childModule1.js';
export { myClass } from 'childModule2.js';
// In top-level module
// We can consume the exports from a single module since parentModule
// "collected"/"bundled" them in a single source
import { myFunction, myVariable, myClass } from 'parentModule.js'
https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export







https://www.tutorialsteacher.com/nodejs/nodejs-module-exports

Friday, 28 February 2020

vue js, vue element, how to add select all

<template>
 <div>
   <el-select v-model="chooseData" multiple placeholder="select" style="width: 300px" @change='selectAll'>
     <el-option v-for="item in selectOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value">
     </el-option>
   </el-select>
 </div>
</template>
<script>
export default {
  data () {
    return {
      selectOptions: [
        { value: 'ALL_SELECT', label: 'select all' },
        { value: '1', label: 'apple' },
        { value: '2', label: 'banana' },
        { value: '3', label: 'orange' },
        { value: '4', label: 'mango' },
        { value: '5', label: 'grape' },
      ],
      oldChooseData: [],
      chooseData: []
    };
  },
  methods: {
    selectAll (val) {
     // Get all possible values
      const allValues = this.selectOptions.map(item => {
        return item.value;
      });
      // Get previously selected values
      const oldVal = this.oldChooseData.length > 0 ? this.oldChooseData : [];

      // if  ALL_SELECT is selected this tim
      if (val.includes('ALL_SELECT')) {
        this.chooseData = allValues;
      }

      //  if  ALL_SELECT selected last time, but not this time => set selected data to []
      if (oldVal.includes('ALL_SELECT') && !val.includes('ALL_SELECT')) {
        this.chooseData = [];
      }


    // If  ALL_SELECT selected last time, and  this time as well, and there is a change in value this time meaning, some previously selected no ALL_SELECT value has been de selected,
then remove ALL_SELECT from list
      if (oldVal.includes('ALL_SELECT') && val.includes('ALL_SELECT')) {
        const index = val.indexOf('ALL_SELECT');
        val.splice(index, 1);
        this.chooseData = val;
      }

      // if ALL_SELECT not selected last time and this time as well,
      // if every other values are selected, add ALL_SELECT to selected data
      if (!oldVal.includes('ALL_SELECT') && !val.includes('ALL_SELECT')) {
        if (val.length === allValues.length - 1) {
          this.chooseData = ['ALL_SELECT'].concat(val);
        }
      }

      //  Save currently selected data for comparison next time
      this.oldChooseData = this.chooseData;
    }
  }
};
</script>
————————————————
:https://blog.csdn.net/sleepwalker_1992/article/details/88876114

Monday, 16 December 2019

How to manually upload files from front end to back end

a) Add Content-Type : 'multipart/form-data; charset=utf-8; boundary=' + Math.random().toString().substr(2) to client request (This only works for POST request, GET can not be added)

in Axios, you can use request interceptor
service.interceptors.request.use(
  config => {
      config.headers['Content-Type'] = 'multipart/form-data; charset=utf-8; boundary=' + Math.random().toString().substr(2)
  }
)


b) Create Form data when submitting the request
        // Make form data
        let params = new FormData();
        params.append('name', this.dummy_name);
        // Files
        for (let file of this.my_files) {
            params.append('files[]', file);
        }
        SendPOST(params).then(() => {
   })

https://stackoverflow.com/questions/47630163/axios-post-request-to-send-form-data


Backend caution ~ :
When using multipart/form-data as client request, all form values need to be manually parsed such as using intval(), json_decode(), str_replace('"', '', my_var)