Vue js and Vue Material
-
Upload
eueung-mulyana -
Category
Technology
-
view
689 -
download
7
Transcript of Vue js and Vue Material
1 / 48
Introduction - by Examples
Vue.JSEueung Mulyana
https://eueung.github.io/112016/vuejsCodeLabs | Attribution-ShareAlike CC BY-SA
Vue.JS Version: 2.1.6Vue Material Version: 0.5.1
2 / 48
Outline
Introduction
Basic Examples
vue-cli
Vue Components
3 / 48
Introduction
4 / 48
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
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
Basic Examples
7 / 48
<!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
9 / 48
Example #1
10 / 48
Example #1
11 / 48
Example #1Interaction via Console
<!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
Example #2a
13 / 48
<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
Example #2b
15 / 48
vue-cli
16 / 48
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
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" }}
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
vue init webpack-simple20 / 48
<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
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
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' }, ... ], } ...
<!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
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
Example #2a (webpack)26 / 48
Vue Components
27 / 48
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
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
{ "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
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
<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
<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
<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
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
Example #3a36 / 48
Example #3a37 / 48
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
{ "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
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
<!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
<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
<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
Example #3b44 / 48
Example #3b45 / 48
Refs
46 / 48
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
48 / 48
ENDEueung Mulyana
https://eueung.github.io/112016/vuejsCodeLabs | Attribution-ShareAlike CC BY-SA