# 勞基法計算機 ### vue.js 初體驗 ---- [Yuren Ju](https://github.com/yurenju) - [g0v 零時政府](http://g0v.tw/zh-TW/index.html) --- ## 起因 ![](https://i.imgur.com/4ENWvcT.png) --- 大家都自己計算造表格,不如寫一個小計算機讓大家可以在上面試算與分享? --- 就這樣,應該馬上就做好了! ![](https://i.imgur.com/cT2rldf.jpg) --- 先來看一下 [勞基法](http://law.moj.gov.tw/LawClass/LawAll.aspx?PCode=N0030001) 好了! ![](https://i.imgur.com/RlCe44X.png) --- ![](http://i.giphy.com/l2SpOXeMPHNGOqiRi.gif) --- ![](https://i.imgur.com/xcX7oAO.png) BTW, 這只是其中的一條 --- ![](http://i.imgur.com/2yzv4io.jpg) --- ![](http://i.giphy.com/OYL1FqJ4Qs6Iw.gif) --- 等等等等,先跳過太複雜的變形工時 我們還是從簡單的問題開始好了 --- ## 請問一位月薪 36,000 元的勞工 ### 平日加班一小時的薪水應該是多少? --- # 大約 300 元? 每個月工作天約二十天,每天正常工作時數是八小時 最低加班費的算法是乘以 1 ⅓ `36000 / 20 / 8 * (4 / 3) = 300` --- # 錯 --- ### `36000 / 30 / 8 * (4 / 3) = 200` <div style="font-size:0.5em;"> <a href="http://laws.mol.gov.tw/Chi/FLAW/FLAWDOC03.asp?keyword=&lc1=FL014930%2C+20150701%2C+24&sdate=&edate=&datatype=etype&recordNo=7">勞動 2 字第 0960130677 號 函</a> :原約定月薪給付總額相當於 240 小時者(即「平日每小時工資額」係以月薪總額除以 30 再除以 8 核計者) </div> --- ## 所以你假日也是有支薪的 ### 很合理吧? --- ## 請問一位月薪 36,000 元的勞工 週六加班第一小時的 <span style="color:red;">最低法定薪資</span> 應該是多少? <div style="font-size:0.5em;"> 假設該勞工平常日都工作八小時 </div> --- # 新台幣 50 元整 💢 因為你假日有給薪喔~ 所以週六來加班的話根據勞基法 24 條額外加給三分之一以上 <div style="font-size:0.5em;"> 注意這邊是最低法定薪資,但是雇主其實是可以給你更高 </div> --- ## 因為太扯了 所以我有[打電話](https://medium.com/@yurenju/勞基法修法計算機-8f570d45d4ae)去台北市勞動局確認過 目前勞動檢查確實是這樣認定 --- 好吧雖然很扯,但搞清楚規則之後 還是可以照計畫作出來 ![](https://i.imgur.com/cT2rldf.jpg) --- [g0v 勞基法修法計算機](https://g0v.github.io/workweek/) ![](https://i.imgur.com/h3NYYJa.png) --- ## React.js vs Angular.js vs Vue.js ---- [Vue.js comparision](https://cn.vuejs.org/guide/comparison.html) ![](http://i.giphy.com/8rVWwln2VkXh6.gif) --- ## 其實 不管用框架或是純寫 JavaScript 都可以完成,我自己使用框架主要是要讓開發速度加快。熟悉了開發工具不論用哪套其實都可以達到目的 --- ## 背景 1. 這是我第一個 Vue.js 專案 2. 以前寫過 Angular.js 跟 React.js 但是經驗都不算多 3. 原本覺得這是週末小專案,想要很快速寫完 4. 我想用 side project 熟悉一些新工具 --- ### 花個幾分鐘看了一下 vue.js 的文件⋯ 這是現代版本的 Angular.js 吧? --- ## 馬上看到的優點 1. 跟 Angular 十分類似,寫過 Angular 的人入手很快 2. 官方 cli 工具跟 webpack 無縫整合 3. 撰寫 component 十分簡易,可包裝在一個 .vue 檔案 * [Angular.js directive](https://docs.angularjs.org/guide/directive) vs [Vue.js Component](https://cn.vuejs.org/guide/components.html) --- ## 沒考慮多久就決定用 Vue.js 了 ### (順便玩玩新工具) --- ## Template ```shell $ npm install vue-cli $ vue init webpack PROJECT_NAME ``` --- ![](https://i.imgur.com/MpecUOb.png) --- <img style="width: 35%;" src="https://i.imgur.com/aMgNYFB.png"> --- ![](https://i.imgur.com/N3NKiQY.png) --- ![](https://i.imgur.com/I8euAKl.png) --- ![](https://i.imgur.com/yH64z5T.png) --- ![](https://i.imgur.com/N3NKiQY.png) --- <img src="https://i.imgur.com/vtNbQOv.png" style="width: 60%;"> --- ## main.js ```javascript= import Vue from 'vue'; import App from './App'; new Vue({ el: 'body', components: { App }, }); ``` --- ## index.html ```htmlmixed= <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>workweek</title> </head> <body> <app></app> <!-- built files will be auto injected --> </body> </html> ``` --- ## ES6 by babel.js! * ES6 module! * Object Literal Shorthand ```javascript= import Vue from 'vue'; import App from './App'; new Vue({ el: 'body', components: { App }, }); ``` ```javascript= // ES5 new Vue({ el: 'body', components: { App: App }, }); ``` --- ![](http://i.giphy.com/em4i0bDs9Hm2Q.gif) --- ES6 * Arrow function * `items.filter(item => item.is(Text));` * Classes * Destructuring assignment * `var [a, b] = [1, 2];` * [More](http://es6-features.org/) --- ## .Vue file 1. &lt;template&gt; 2. &lt;script&gt; 3. &lt;style&gt; --- ## App.vue ![](https://i.imgur.com/Z2eFJyw.png) --- ## Hello.vue <img src="https://i.imgur.com/IBu01oz.png" style="width: 80%;"> --- ![](https://i.imgur.com/yH64z5T.png) --- <img src="https://i.imgur.com/9P9Gka0.png" style="width:80%"> --- ### 雖然 Vue.js 提供了很好拆分小元件的寫法 身為一個新手而這又是個小週末專案 就把所有東西都到一個叫做 Workweek 的 vue component 吧 :D --- ![](http://i.giphy.com/Tr10zt02CSMOQ.gif) --- ![](https://i.imgur.com/pdSF3gM.png) --- ## 來看看專案裡面用到的 vue.js 功能 --- ## Script 內的常用屬性 * components * props * data() * computed() * methods --- ```javascript= export default { components: { Component1, Component2 }, props: ['prop1', 'prop2'], methods: { method1 (reason) { // ... }, method2 () { // ... } }, data () { // {{data1}} return { data1: 'DATA1', data2: 'DATA2', data3: 'DATA3', }; }, computed: { // {{computed1}} computed1() { // ... }, computed2() { // ... } } }; ``` --- ## data() ```javascript= data () { // ... return { reason: reason, daynames: solutions.DAY_NAMES, workhours: workhours, assumingWorkHours: 240, monthlyPay: monthlyPay, expandDetail: false, regularHoursPerDay: solutions.REGULAR_HOURS_PER_DAY }; }, ``` --- ## computed() ```javascript= export default { data() { /* ... */ }, computed: { hourlyPay: function () { return parseFloat(this.monthlyPay / this.assumingWorkHours); }, regularPay: function () { return this.hourlyPay * 8 * 7; } } }; ``` --- ## methods ```javascript= export default { methods: { toggleExpanding: function (evt) { this.expandDetail = !this.expandDetail; } } }; ``` --- ## Template 內常用語法 --- [Two way binding](https://vuejs.org/guide/#Two-way-Binding) <img src="https://i.imgur.com/euklIgV.png" style="width: 60%;"> --- ## Template 內常用語法 * `v-model` * `v-for` * `v-show / v-if` * `v-bind:model` (簡寫 :model) * `v-on:click` (簡寫 @click) * `{{ variable }}` * `{{{ html }}}` --- ## 很順利地寫完週末小專案了 但是技術債很快就來討債了: 是誰說要所有東西寫在一個元件裡面的? [很悲劇的 Workweek.vue](https://github.com/g0v/workweek/blob/50d126330ddf73cc71f67c90be12c013ec27adae/src/components/Workweek.vue) --- ## Refactoring ![](https://i.imgur.com/yTUfW7F.png) --- ![](https://i.imgur.com/Em0menN.jpg) --- ## offday-condition diagram ![](https://i.imgur.com/ltPp3Rm.png) --- ## offday-condition component ```htmlmixed= <offday-condition v-bind:reason="reason" v-on:reason-changed="reasonChanged"> </offday-condition> ``` 簡寫 ```htmlmixed= <offday-condition :reason="reason" @reason-changed="reasonChanged"> </offday-condition> ``` --- OffdayCondition.vue script ```javascript= export default { props: ['reason'], watch: { reason (val) { this.$dispatch('reason-changed', val); } } }; ``` Workweek.vue script ```javascript= reasonChanged (reason) { this.reason = reason; } ``` --- ## Workweek.vue ```javascript= export default { computed: { currentSolution () { return solutions.current(this.workhours, this.hourlyPay, this.reason); }, oneRestOneOffSolution () { return solutions.oneRestOneOff(this.workhours, this.hourlyPay, this.reason); }, twoOffSolution () { return solutions.twoOff(this.workhours, this.hourlyPay, this.reason); } } } ``` --- ## current-solution component ```htmlmixed= <current-solution :solution="currentSolution" :regular-pay="regularPay" :overtime-pay-winner="mostOvertimePay.current" :expand="expandDetail"> </current-solution> ``` --- ![](https://i.imgur.com/yWiuvQW.png) --- ## 結論 * 現行勞基法很奇怪,確實要修。 * 但是目前修法方向很奇怪 * vue.js 是個好東西啊⋯⋯ * 語法簡單,很像 Angular * 容易包裝元件 * 官方的 cli 工具直接整合了 webpack, babel.js * 從我的經驗來看,開發小型專案很好用 * 還有時間的話可以講一下 static website deploy * 電梯向下 👇 --- ## 如果你的專案是純前端專案 deploy 到 github pages 是個不錯的選擇 --- <img src="https://i.imgur.com/nlOtJ1D.png" style="width:80%;"> --- ## package.json ```javascript= { "name": "workweek", "scripts": { "dev": "node build/dev-server.js", "build": "node build/build.js", "test": "echo \"No tests\"", "lint": "eslint --ext .js,.vue src", "deploy": "node build/deploy.js" } } ``` --- ## .travis.yml ```yaml= language: node_js node_js: - '4' env: global: - GH_REF=github.com/g0v/workweek.git # GH_TOKEN - secure: "..." cache: node_modules script: - npm run build after_success: npm run deploy ``` --- ## deploy.js ```javascript= require('shelljs/global'); rm('-rf', 'out'); exec('git clone "https://' + env.GH_TOKEN + '@' + env.GH_REF + '" --depth 1 -b gh-pages out'); pushd('out'); exec('git config user.name "Automatic Commit"'); exec('git config user.email "workweek@g0v.tw"'); exec('git rm -rf .'); cp('-r', '../dist/', '.'); exec('git add .'); exec('git commit -m "Automatic commit: ' + Date() + '"'); exec('git push "https://' + env.GH_TOKEN + '@' + env.GH_REF + '" gh-pages', {silent: true}); popd(); exit(0); ```
{"metaMigratedAt":"2023-06-14T11:48:35.651Z","metaMigratedFrom":"YAML","title":"勞基法計算機","breaks":true,"disqus":"yurenju-hackmd","contributors":"[]"}
    2506 views