Vue js and Vue Material

48
1 / 48 Introduction - by Examples Vue.JS Eueung Mulyana https://eueung.github.io/112016/vuejs CodeLabs | Attribution-ShareAlike CC BY-SA

Transcript of Vue js and Vue Material

Page 1: Vue js and Vue Material

1 / 48

Introduction - by Examples

Vue.JSEueung Mulyana

https://eueung.github.io/112016/vuejsCodeLabs | Attribution-ShareAlike CC BY-SA

Page 2: Vue js and Vue Material

Vue.JS Version: 2.1.6Vue Material Version: 0.5.1

2 / 48

Page 3: Vue js and Vue Material

Outline

Introduction

Basic Examples

vue-cli

Vue Components

3 / 48

Page 4: Vue js and Vue Material

Introduction

4 / 48

Page 5: Vue js and Vue Material

5 / 48

Vue is a progressive framework for building user interfaces.Unlike other monolithic frameworks, Vue is designed from

the ground up to be incrementally adoptable.

The core library is focused on the view layer only, and is very easy to pick up andintegrate with other libraries or existing projects. On the other hand, Vue is also

perfectly capable of powering sophisticated Single-Page Applications when used incombination with modern tooling and supporting libraries.

Ref: Vue.JS - Guide

Vue.JS

Page 6: Vue js and Vue Material

6 / 48

Vue & React

They share many similarities:

utilize a virtual DOMprovide reactive and composable view componentsmaintain focus in the core library, with concerns such as routing and globalstate management handled by companion libraries

In React, everything is Just JavaScript, which sounds verysimple and elegant - until you dig deeper. The unfortunatereality is that reinventing HTML and CSS within JavaScript,

while solving some issues of the traditional model, can alsocause pain of its own. Vue, instead, utilizes web technologies

and build on top of them. Ref: Comparison.

Deja Vue?Vue has many features that are clearlyinspired by other frameworks. This is agood thing; it's great to see newframeworks take some ideas from otherlibraries and improve on them.

In particular, you'll see Vue's templatingis very close to Angular, but itscomponents and component lifecyclemethods are closer to React.

Ref: jfranklin @SitePoint

Page 7: Vue js and Vue Material

Basic Examples

7 / 48

Page 8: Vue js and Vue Material

<!DOCTYPE html><html lang="en"><head> <meta charset="utf-8"> <title>Vue.JS</title>

<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic" <link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons"> <link rel="stylesheet" href="//unpkg.com/vue-material@latest/dist/vue-material.css"> <style> .main-content { padding: 16px; } .red { color:red; }</style></head>

<body>

<div id="app"> <md-toolbar> <h1 class="md-title">Learning Vue.JS</h1> </md-toolbar>

<div class="main-content"> <h1>{{ message1 }}</h1><h3 class="red">v-on:click</h3> <md-button class="md-raised md-primary" v-on:click="reverseMessage">Reverse</md-button>

<h3 class="red">v-bind:title</h3><p v-bind:title="message2">123 123 123 123 123</p> <h3 class="red">v-if</h3><p v-if="seen">v-if show-hide: Now you see me</p>

<h3 class="red">v-for</h3> <ol><li v-for="todo in todos">{{ todo.text }}</li></ol>

<h1>{{ message3 }}</h1><h3 class="red">v-model</h3> <md-input-container> <label>Enter Message</label> <md-input v-model="message3"></md-input> </md-input-container>

<h3 class="red">Component</h3> <ol> <todo-item v-for="item in groceryList" v-bind:todo="item"></todo-item> </ol>

</div></div>

<script src="//unpkg.com/vue/dist/vue.js"></script><script src="//unpkg.com/vue-material@latest"></script>

8 / 48

Example #1

Page 9: Vue js and Vue Material

9 / 48

Example #1

Page 10: Vue js and Vue Material

10 / 48

Example #1

Page 11: Vue js and Vue Material

11 / 48

Example #1Interaction via Console

Page 12: Vue js and Vue Material

<!DOCTYPE html><html lang="en"><head> <meta charset="utf-8"> <title>Vue.JS</title>

<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic" <link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons"> <link rel="stylesheet" href="//unpkg.com/vue-material@latest/dist/vue-material.css"> <style> .main-content { padding: 16px; } .red { color:red;} ul {padding-left:0;} li {list-style:none; line-height: 40px;} .md-button {margin-left:0;} </style></head>

<body>

<div id="app"> <md-toolbar> <h1 class="md-title">Learning Vue.JS</h1> </md-toolbar>

<div class="main-content"> <md-input-container> <label>Enter Todo</label> <md-input v-model="newTodo"></md-input> </md-input-container> <md-button class="md-raised md-primary" v-on:click="addTodo">Add Todo</md-button>

<ul> <li v-for="(todo, index) in todos"> <md-button class="md-icon-button md-warn" v-on:click="removeTodo(index)"><md-icon>remove_circle_outline {{ todo.text }} </li> </ul>

</div></div>

<script src="//unpkg.com/vue/dist/vue.js"></script><script src="//unpkg.com/vue-material@latest"></script>

<script type="text/javascript"> Vue.use(VueMaterial)

12 / 48

Example #2a

Page 13: Vue js and Vue Material

Example #2a

13 / 48

Page 14: Vue js and Vue Material

<head> <meta charset="utf-8"> <title>Vue.JS</title>

<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic" <link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons"> <link rel="stylesheet" href="//unpkg.com/vue-material@latest/dist/vue-material.css"> <style> .main-content { padding: 16px; } .red { color:red;} ul {padding-left:0;} li {list-style:none; line-height: 40px;} .md-button {margin-left:0;} </style></head>

<body>

<div id="app"> <md-toolbar> <h1 class="md-title">Learning Vue.JS</h1> </md-toolbar>

<div class="main-content"> <md-input-container> <label>Enter Todo</label> <md-input v-model="newTodoText" placeholder="Add a todo"></md-input> </md-input-container> <md-button class="md-raised md-primary" v-on:click="addNewTodo">Add Todo</md-button>

<ul> <li is="todo-item" v-for="(todo, index) in todos" v-bind:title="todo" v-on:remove="todos.splice(index, 1)"> </li> </ul>

</div></div>

<script src="//unpkg.com/vue/dist/vue.js"></script><script src="//unpkg.com/vue-material@latest"></script>

<script type="text/javascript">

Vue.use(VueMaterial)

14 / 48

Example #2bVue ComponentEvent

Page 15: Vue js and Vue Material

Example #2b

15 / 48

Page 16: Vue js and Vue Material

vue-cli

16 / 48

Page 17: Vue js and Vue Material

17 / 48

Install & Scaffold

$ sudo npm install -g vue-cli

$ vue init webpack-simple myproj

This will install Vue 2.x version of template.

For Vue 1.x use: vue init webpack-simple#1.0 myproj

? Project name myproj? Project description A Vue.js project? Author EM

vue-cli . Generated "myproj".

To get started:

cd myproj npm install npm run dev

myproj$ tree.|-- index.html|-- package.json|-- README.md|-- src| |-- App.vue| |-- assets| | |-- logo.png| |-- main.js|-- webpack.config.js

2 directories, 7 files

Page 18: Vue js and Vue Material

18 / 48

package.json

myproj$ cat package.json { "name": "myproj", "description": "A Vue.js project", "version": "1.0.0", "author": "EM", "private": true, "scripts": { "dev": "cross-env NODE_ENV=development webpack-dev-server --open --inline --hot -host 0.0.0.0" "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" }, "dependencies": { "vue": "̂2.1.0" }, "devDependencies": { "babel-core": "̂6.0.0", "babel-loader": "̂6.0.0", "babel-preset-es2015": "̂6.0.0", "cross-env": "̂3.0.0", "css-loader": "̂0.25.0", "file-loader": "̂0.9.0", "vue-loader": "̂10.0.0", "vue-template-compiler": "̂2.1.0", "webpack": "̂2.1.0-beta.25", "webpack-dev-server": "̂2.1.0-beta.9" }}

Page 19: Vue js and Vue Material

19 / 48

Install & Run

myproj$ npm installmyproj$ npm run dev> [email protected] dev /home/em/vuedir/myproj> cross-env NODE_ENV=development webpack-dev-server --open --inline --hot --host 0.0.0.0

Project is running at http://0.0.0.0:8080/webpack output is served from /dist/404s will fallback to /index.html

myproj$ npm run build

Page 20: Vue js and Vue Material

vue init webpack-simple20 / 48

Page 21: Vue js and Vue Material

<html lang="en"> <head> <meta charset="utf-8"> <title>myproj</title> </head> <body> <div id="app"></div> <script src="/dist/build.js"></script> </body></html>

# App.vue<template> <div id="app"> <img src="./assets/logo.png"> <h1>{{ msg }}</h1> <h2>Essential Links</h2> <ul> <li><a href="https://vuejs.org" target="_blank">Core Docs</a></li> <li>...</li> </ul> <h2>Ecosystem</h2> <ul> <li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li> <li>...</li> </ul> </div></template>

<script>export default { name: 'app', data () { return { msg: 'Welcome to Your Vue.js App' } }}</script>

<style>

#app { font-family: 'Avenir', Helvetica, Arial, sans-serif; 21 / 48

webpack-simpleindex.htmlApp.vuemain.js

Page 22: Vue js and Vue Material

22 / 48

Example #2aRecycled

$ npm install$ npm install --save vue-material

$ tree .|-- dist| |-- build.js|-- index.html|-- package.json|-- README.md|-- src| |-- App.vue| |-- css| | |-- app.css| |-- main.js|-- webpack.config.js

$ npm run build$ npm run dev

Page 23: Vue js and Vue Material

23 / 48

package.jsonwebpack.config.js

$ cat package.json { ... "dependencies": { "vue": "̂2.1.0", "vue-material": "̂0.5.1" }, ...}

$ cat webpack.config.js module: { rules: [ ... { test: /\.css$/, loader: 'vue-style-loader!css-loader' }, ... ], } ...

Page 24: Vue js and Vue Material

<!DOCTYPE html><html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic" <link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons">

<title>myproj</title> </head> <body> <div id="app"></div> <script src="/dist/build.js"></script> </body></html>

# -------------------

.main-content { padding: 16px; } .red { color:red;} ul {padding-left:0;} li {list-style:none; line-height: 40px;} .md-button {margin-left:0;}

24 / 48

Example #2aindex.htmlsrc/css/app.css

Page 25: Vue js and Vue Material

import Vue from 'vue'import App from './App.vue'import VueMaterial from 'vue-material'import 'vue-material/dist/vue-material.css'import './css/app.css'

Vue.use(VueMaterial)

new Vue({ el: '#app', render: h => h(App)})

/* --------------------------- */

<template><div id="app"> <md-toolbar> <h1 class="md-title">Learning Vue.JS</h1> </md-toolbar>

<div class="main-content"> <md-input-container> <label>Enter Todo</label> <md-input v-model="newTodo"></md-input> </md-input-container> <md-button class="md-raised md-primary" v-on:click="addTodo">Add Todo</md-button>

<ul> <li v-for="(todo, index) in todos"> <md-button class="md-icon-button md-warn" v-on:click="removeTodo(index)"><md-icon>remove_circle_outline</md-icon></md-button> {{ todo.text }} </li> </ul></div></div></template>

<script>export default { name: 'app', data () { return { newTodo: '', todos: [ { text: 'Add some todos' } ] } 25 / 48

Example #2amain.jssrc/App.vue

Page 26: Vue js and Vue Material

Example #2a (webpack)26 / 48

Page 27: Vue js and Vue Material

Vue Components

27 / 48

Page 28: Vue js and Vue Material

28 / 48

Example #3

Example #3aBased on an Article @SitePoint by Jack FranklinComponents are re-organized to a single index.vue

Example #3bExample #3a + Vue Material

Page 29: Vue js and Vue Material

29 / 48

Example #3aStructure

$ tree.|-- build| |-- main.js|-- index.html|-- package.json|-- src| |-- App| | |-- index.vue| |-- bus.js| |-- GithubInput| | |-- index.vue| |-- GithubOutput| | |-- index.vue| |-- GithubUserData| | |-- index.vue| |-- main.js|-- webpack.config.js

6 directories, 10 files

Page 30: Vue js and Vue Material

{ "name": "vue2-intro-code", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "live-server", "build": "webpack --watch" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "babel-core": "6.18.2", "babel-loader": "6.2.7", "babel-preset-es2015": "6.18.0", "css-loader": "0.25.0", "live-server": "1.1.0", "vue": "2.1.6", "vue-loader": "10.0.0", "vue-template-compiler": "̂2.1.0", "webpack": "1.13.3" }}

/* --------------------------- */

module.exports = { entry: './src/main', output: { path: './build', filename: 'main.js', }, module: { loaders: [ { test: /\.vue$/, loader: 'vue', }, { test: /\.js$/, loader: 'babel', exclude: /node_modules/, 30 / 48

Example #3apackage.jsonwebpack.con�g.jsindex.html

Page 31: Vue js and Vue Material

31 / 48

import Vue from 'vue'

import AppComponent from './App/index.vue'

const vm = new Vue({ el: '#app', components: { app: AppComponent, }, render: h => h('app'),})

/* --------------------------- */

import Vue from 'vue'

const bus = new Vue()

export default bus

Example #3asrc/main.jssrc/bus.js

Page 32: Vue js and Vue Material

<template><div> <p>Enter your username to get some Github stats!</p> <github-input></github-input> <github-output></github-output></div></template>

<script>import GithubInput from '../GithubInput/index.vue'import GithubOutput from '../GithubOutput/index.vue'

export default { name: 'App', components: { 'github-input': GithubInput, 'github-output': GithubOutput, }, data() { return {} },}</script>

<style scoped>p { color: red;}</style>

32 / 48

Example #3asrc/App/index.vue

Page 33: Vue js and Vue Material

<template><form v-on:submit.prevent="onSubmit"> <input type="text" v-model="username" placeholder="Enter a github username here" /> <button type="submit">Go!</button></form></template>

<script>import bus from '../bus'

export default { name: 'GithubInput', methods: { onSubmit(event) { if (this.username && this.username !== '') { bus.$emit('new-username', this.username) } } }, data() { return { username: '', } }}</script>

33 / 48

Example #3a

src/GithubInput/index.vue

Page 34: Vue js and Vue Material

<template><div> <p v-if="currentUsername == null"> Enter a username above to see their Github data </p> <p v-else> Below are the results for {{ currentUsername }}: <github-user-data :data="githubData[currentUsername]"></github-user-data> </p></div></template>

<script>import bus from '../bus'import Vue from 'vue'import GithubUserData from '../GithubUserData/index.vue'

export default { name: 'GithubOutput', components: { 'github-user-data': GithubUserData, }, created() { bus.$on('new-username', this.onUsernameChange) }, destroyed() { bus.$off('new-username', this.onUsernameChange) }, methods: { onUsernameChange(name) { this.currentUsername = name this.fetchGithubData(name) }, fetchGithubData(name) { if (this.githubData.hasOwnProperty(name)) return

const url = ̀https://api.github.com/users/${name}̀ fetch(url).then(r => r.json()).then(data => { Vue.set(this.githubData, name, data) console.log(JSON.stringify(this.githubData)) }) } }, 34 / 48

Example #3a

src/GithubOutput/index.vue

Page 35: Vue js and Vue Material

35 / 48

<template><div v-if="data"> <h4>{{ data.name }}</h4> <p>{{ data.company }}</p> <p>Number of repos: {{ data.public_repos }}</div></template>

<script>export default { name: 'GithubUserData', props: ['data'], data() { return {} }}</script>

Example #3a

src/GithubUserData/index.vue

Page 36: Vue js and Vue Material

Example #3a36 / 48

Page 37: Vue js and Vue Material

Example #3a37 / 48

Page 38: Vue js and Vue Material

38 / 48

Example #3bStructure

$ tree.|-- dist| |-- build.js| |-- build.js.map|-- index.html|-- package.json|-- src| |-- App| | |-- index.vue| |-- bus.js| |-- css| | |-- app.css| |-- GithubInput| | |-- index.vue| |-- GithubOutput| | |-- index.vue| |-- GithubUserData| | |-- index.vue| |-- main.js|-- webpack.config.js

7 directories, 12 files

Page 39: Vue js and Vue Material

{ "name": "myproj", "description": "A Vue.js project", "version": "1.0.0", "author": "EM", "private": true, "scripts": { "dev": "cross-env NODE_ENV=development webpack-dev-server --open --inline --hot --host 0.0.0.0" "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" }, "dependencies": { "vue": "̂2.1.0", "vue-material": "̂0.5.1" }, "devDependencies": { "babel-core": "̂6.0.0", "babel-loader": "̂6.0.0", "babel-preset-es2015": "̂6.0.0", "cross-env": "̂3.0.0", "css-loader": "̂0.25.0", "file-loader": "̂0.9.0", "vue-loader": "̂10.0.0", "vue-template-compiler": "̂2.1.0", "webpack": "̂2.1.0-beta.25", "webpack-dev-server": "̂2.1.0-beta.9" }}

39 / 48

Example #3bpackage.json

Page 40: Vue js and Vue Material

var path = require('path')var webpack = require('webpack')

module.exports = { entry: './src/main.js', output: { path: path.resolve(__dirname, './dist'), publicPath: '/dist/', filename: 'build.js' }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', options: { loaders: { // Since sass-loader (weirdly) has SCSS as its default parse mode, we map // the "scss" and "sass" values for the lang attribute to the right configs here. // other preprocessors should work out of the box, no loader config like this nessessary. 'scss': 'vue-style-loader!css-loader!sass-loader', 'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax' } // other vue-loader options go here } }, { test: /\.css$/, loader: 'vue-style-loader!css-loader' }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }, { test: /\.(png|jpg|gif|svg)$/, loader: 'file-loader', options: { name: '[name].[ext]?[hash]' }

40 / 48

Example #3bwebpack.con�g.js

Page 41: Vue js and Vue Material

<!DOCTYPE html><html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic" <link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons">

<title>myproj</title> </head> <body> <div id="app"></div> <script src="/dist/build.js"></script> </body></html>

/* --------------------------- */import Vue from 'vue'

import AppComponent from './App/index.vue'import VueMaterial from 'vue-material'import 'vue-material/dist/vue-material.css'import './css/app.css'

Vue.use(VueMaterial)

const vm = new Vue({ el: '#app', components: { app: AppComponent, }, render: h => h('app'),})

/* --------------------------- */.main-content { padding: 16px; } .red { color:red;} ul {padding-left:0;} li {list-style:none; line-height: 40px;} .md-button {margin-left:0;}

41 / 48

Example #3bindex.htmlsrc/main.jssrc/css/app.css

Page 42: Vue js and Vue Material

<template><div id="app"> <md-toolbar> <h1 class="md-title">Learning Vue.JS</h1> </md-toolbar> <div class="main-content">

<p>Enter your username to get some Github stats!</p> <github-input></github-input> <github-output></github-output>

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

<script>import GithubInput from '../GithubInput/index.vue'import GithubOutput from '../GithubOutput/index.vue'

export default { name: 'App', components: { 'github-input': GithubInput, 'github-output': GithubOutput, }, data() { return {} },}</script>

<style scoped>p { color: red;}</style>

42 / 48

Example #3bsrc/App/index.vue

Page 43: Vue js and Vue Material

<template><div> <md-input-container> <label>Github User</label> <md-input v-model="username" placeholder="Enter a github username here"></md-input> </md-input-container> <md-button class="md-raised md-primary" v-on:click="onSubmit">Go!</md-button></div></template>

<script>import bus from '../bus'

export default { name: 'GithubInput', methods: { onSubmit(event) { if (this.username && this.username !== '') { bus.$emit('new-username', this.username) } } }, data() { return { username: '', } }}</script>

43 / 48

Example #3b

src/GithubInput/index.vue

Page 44: Vue js and Vue Material

Example #3b44 / 48

Page 45: Vue js and Vue Material

Example #3b45 / 48

Page 46: Vue js and Vue Material

Refs

46 / 48

Page 47: Vue js and Vue Material

Refs1. vuejs.org2. vuejs/vue: Simple yet powerful library for building modern web interfaces.3. Comparison with Other Frameworks - vue.js4. Introduction - Vue Material5. Getting up and Running with the Vue.js 2.0 Framework6. jackfranklin/vue2-demo-proj

47 / 48

Page 48: Vue js and Vue Material

48 / 48

ENDEueung Mulyana

https://eueung.github.io/112016/vuejsCodeLabs | Attribution-ShareAlike CC BY-SA