KEMBAR78
Vue js and Vue Material | PDF
1 / 48
Introduction - by Examples
Vue.JS
Eueung Mulyana
https://eueung.github.io/112016/vuejs
CodeLabs | Attribution-ShareAlike CC BY-SA
Vue.JS Version: 2.1.6
Vue 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 and
integrate with other libraries or existing projects. On the other hand, Vue is also
perfectly capable of powering sophisticated Single-Page Applications when used in
combination with modern tooling and supporting libraries.
Ref: Vue.JS - Guide
Vue.JS
6 / 48
Vue & React
They share many similarities:
utilize a virtual DOM
provide reactive and composable view components
maintain focus in the core library, with concerns such as routing and global
state management handled by companion libraries
In React, everything is Just JavaScript, which sounds very
simple and elegant - until you dig deeper. The unfortunate
reality is that reinventing HTML and CSS within JavaScript,
while solving some issues of the traditional model, can also
cause 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 clearly
inspired by other frameworks. This is a
good thing; it's great to see new
frameworks take some ideas from other
libraries and improve on them.
In particular, you'll see Vue's templating
is very close to Angular, but its
components and component lifecycle
methods are closer to React.
Ref: jfranklin @SitePoint
Basic Examples
7 / 48
<!DOCTYPEhtml>
<htmllang="en">
<head>
<metacharset="utf-8">
<title>Vue.JS</title>
<linkrel="stylesheet"href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic"
<linkrel="stylesheet"href="//fonts.googleapis.com/icon?family=Material+Icons">
<linkrel="stylesheet"href="//unpkg.com/vue-material@latest/dist/vue-material.css">
<style>.main-content{padding:16px;}.red{color:red;}</style>
</head>
<body>
<divid="app">
<md-toolbar><h1class="md-title">LearningVue.JS</h1></md-toolbar>
<divclass="main-content">
<h1>{{message1}}</h1><h3class="red">v-on:click</h3>
<md-buttonclass="md-raisedmd-primary"v-on:click="reverseMessage">Reverse</md-button>
<h3class="red">v-bind:title</h3><pv-bind:title="message2">123123123123123</p>
<h3class="red">v-if</h3><pv-if="seen">v-ifshow-hide:Nowyouseeme</p>
<h3class="red">v-for</h3>
<ol><liv-for="todointodos">{{todo.text}}</li></ol>
<h1>{{message3}}</h1><h3class="red">v-model</h3>
<md-input-container>
<label>EnterMessage</label>
<md-inputv-model="message3"></md-input>
</md-input-container>
<h3class="red">Component</h3>
<ol>
<todo-itemv-for="itemingroceryList"v-bind:todo="item"></todo-item>
</ol>
</div></div>
<scriptsrc="//unpkg.com/vue/dist/vue.js"></script>
<scriptsrc="//unpkg.com/vue-material@latest"></script>
8 / 48
Example #1
9 / 48
Example #1
10 / 48
Example #1
11 / 48
Example #1
Interaction via Console
<!DOCTYPEhtml>
<htmllang="en">
<head>
<metacharset="utf-8">
<title>Vue.JS</title>
<linkrel="stylesheet"href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic"
<linkrel="stylesheet"href="//fonts.googleapis.com/icon?family=Material+Icons">
<linkrel="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>
<divid="app">
<md-toolbar><h1class="md-title">LearningVue.JS</h1></md-toolbar>
<divclass="main-content">
<md-input-container>
<label>EnterTodo</label>
<md-inputv-model="newTodo"></md-input>
</md-input-container>
<md-buttonclass="md-raisedmd-primary"v-on:click="addTodo">AddTodo</md-button>
<ul>
<liv-for="(todo,index)intodos">
<md-buttonclass="md-icon-buttonmd-warn"v-on:click="removeTodo(index)"><md-icon>remove_circle_outline
{{todo.text}}
</li>
</ul>
</div></div>
<scriptsrc="//unpkg.com/vue/dist/vue.js"></script>
<scriptsrc="//unpkg.com/vue-material@latest"></script>
<scripttype="text/javascript">
Vue.use(VueMaterial)
12 / 48
Example #2a
Example #2a
13 / 48
<head>
<metacharset="utf-8">
<title>Vue.JS</title>
<linkrel="stylesheet"href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic"
<linkrel="stylesheet"href="//fonts.googleapis.com/icon?family=Material+Icons">
<linkrel="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>
<divid="app">
<md-toolbar><h1class="md-title">LearningVue.JS</h1></md-toolbar>
<divclass="main-content">
<md-input-container>
<label>EnterTodo</label>
<md-inputv-model="newTodoText"placeholder="Addatodo"></md-input>
</md-input-container>
<md-buttonclass="md-raisedmd-primary"v-on:click="addNewTodo">AddTodo</md-button>
<ul>
<li
is="todo-item"
v-for="(todo,index)intodos"
v-bind:title="todo"
v-on:remove="todos.splice(index,1)">
</li>
</ul>
</div></div>
<scriptsrc="//unpkg.com/vue/dist/vue.js"></script>
<scriptsrc="//unpkg.com/vue-material@latest"></script>
<scripttype="text/javascript">
Vue.use(VueMaterial)
14 / 48
Example #2b
Vue Component
Event
Example #2b
15 / 48
vue-cli
16 / 48
17 / 48
Install & Scaffold
$sudonpminstall-gvue-cli
$vueinitwebpack-simplemyproj
ThiswillinstallVue2.xversionoftemplate.
ForVue1.xuse:vueinitwebpack-simple#1.0myproj
?Projectnamemyproj
?ProjectdescriptionAVue.jsproject
?AuthorEM
vue-cli.Generated"myproj".
Togetstarted:
cdmyproj
npminstall
npmrundev
myproj$tree
.
|--index.html
|--package.json
|--README.md
|--src
| |--App.vue
| |--assets
| | |--logo.png
| |--main.js
|--webpack.config.js
2directories,7files
18 / 48
package.json
myproj$catpackage.json
{
"name":"myproj",
"description":"AVue.jsproject",
"version":"1.0.0",
"author":"EM",
"private":true,
"scripts":{
"dev":"cross-envNODE_ENV=developmentwebpack-dev-server--open--inline--hot
"build":"cross-envNODE_ENV=productionwebpack--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$npminstall
myproj$npmrundev
>myproj@1.0.0dev/home/em/vuedir/myproj
>cross-envNODE_ENV=developmentwebpack-dev-server--open--inline--hot--host0.0
Projectisrunningathttp://0.0.0.0:8080/
webpackoutputisservedfrom/dist/
404swillfallbackto/index.html
myproj$npmrunbuild
vue init webpack-simple 20 / 48
<htmllang="en">
<head>
<metacharset="utf-8">
<title>myproj</title>
</head>
<body>
<divid="app"></div>
<scriptsrc="/dist/build.js"></script>
</body>
</html>
#App.vue
<template>
<divid="app">
<imgsrc="./assets/logo.png">
<h1>{{msg}}</h1>
<h2>EssentialLinks</h2>
<ul>
<li><ahref="https://vuejs.org"target="_blank">CoreDocs</a></li>
<li>...</li>
</ul>
<h2>Ecosystem</h2>
<ul>
<li><ahref="http://router.vuejs.org/"target="_blank">vue-router</a></li>
<li>...</li>
</ul>
</div>
</template>
<script>
exportdefault{
name:'app',
data(){
return{
msg:'WelcometoYourVue.jsApp'
}
}
}
</script>
<style>
#app{
font-family:'Avenir',Helvetica,Arial,sans-serif; 21 / 48
webpack-
simple
index.html
App.vue
main.js
22 / 48
Example #2a
Recycled
$npminstall
$npminstall--savevue-material
$tree
.
|--dist
| |--build.js
|--index.html
|--package.json
|--README.md
|--src
| |--App.vue
| |--css
| | |--app.css
| |--main.js
|--webpack.config.js
$npmrunbuild
$npmrundev
23 / 48
package.json
webpack.config.js
$catpackage.json
{
...
"dependencies":{
"vue":"^2.1.0",
"vue-material":"^0.5.1"
},
...
}
$catwebpack.config.js
module:{
rules:[
...
{
test:/.css$/,
loader:'vue-style-loader!css-loader'
},
...
],
}
...
<!DOCTYPEhtml>
<htmllang="en">
<head>
<metacharset="utf-8">
<linkrel="stylesheet"href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic"
<linkrel="stylesheet"href="//fonts.googleapis.com/icon?family=Material+Icons">
<title>myproj</title>
</head>
<body>
<divid="app"></div>
<scriptsrc="/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 #2a
index.html
src/css/app.css
importVuefrom'vue'
importAppfrom'./App.vue'
importVueMaterialfrom'vue-material'
import'vue-material/dist/vue-material.css'
import'./css/app.css'
Vue.use(VueMaterial)
newVue({
el:'#app',
render:h=>h(App)
})
/*---------------------------*/
<template>
<divid="app">
<md-toolbar><h1class="md-title">LearningVue.JS</h1></md-toolbar>
<divclass="main-content">
<md-input-container>
<label>EnterTodo</label>
<md-inputv-model="newTodo"></md-input>
</md-input-container>
<md-buttonclass="md-raisedmd-primary"v-on:click="addTodo">AddTodo</md-button>
<ul>
<liv-for="(todo,index)intodos">
<md-buttonclass="md-icon-buttonmd-warn"v-on:click="removeTodo(index)"><md-icon>remove_circle_outline</md-icon></md-button>
{{todo.text}}
</li>
</ul>
</div></div>
</template>
<script>
exportdefault{
name:'app',
data(){
return{
newTodo:'',
todos:[{text:'Addsometodos'}]
}
25 / 48
Example #2a
main.js
src/App.vue
Example #2a (webpack) 26 / 48
Vue Components
27 / 48
28 / 48
Example #3
Example #3a
Based on an Article @SitePoint by Jack Franklin
Components are re-organized to a single index.vue
Example #3b
Example #3a + Vue Material
29 / 48
Example #3a
Structure
$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
6directories,10files
{
"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 #3a
package.json
webpack.con g.js
index.html
31 / 48
importVuefrom'vue'
importAppComponentfrom'./App/index.vue'
constvm=newVue({
el:'#app',
components:{
app:AppComponent,
},
render:h=>h('app'),
})
/*---------------------------*/
importVuefrom'vue'
constbus=newVue()
exportdefaultbus
Example #3a
src/main.js
src/bus.js
<template>
<div>
<p>EnteryourusernametogetsomeGithubstats!</p>
<github-input></github-input>
<github-output></github-output>
</div>
</template>
<script>
importGithubInputfrom'../GithubInput/index.vue'
importGithubOutputfrom'../GithubOutput/index.vue'
exportdefault{
name:'App',
components:{
'github-input':GithubInput,
'github-output':GithubOutput,
},
data(){
return{}
},
}
</script>
<stylescoped>
p{
color:red;
}
</style>
32 / 48
Example #3a
src/App/index.vue
<template>
<formv-on:submit.prevent="onSubmit">
<inputtype="text"v-model="username"placeholder="Enteragithubusernamehere"/>
<buttontype="submit">Go!</button>
</form>
</template>
<script>
importbusfrom'../bus'
exportdefault{
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>
<pv-if="currentUsername==null">
EnterausernameabovetoseetheirGithubdata
</p>
<pv-else>
Belowaretheresultsfor{{currentUsername}}:
<github-user-data:data="githubData[currentUsername]"></github-user-data>
</p>
</div>
</template>
<script>
importbusfrom'../bus'
importVuefrom'vue'
importGithubUserDatafrom'../GithubUserData/index.vue'
exportdefault{
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
consturl=`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>
<divv-if="data">
<h4>{{data.name}}</h4>
<p>{{data.company}}</p>
<p>Numberofrepos:{{data.public_repos}}
</div>
</template>
<script>
exportdefault{
name:'GithubUserData',
props:['data'],
data(){
return{}
}
}
</script>
Example #3a
src/GithubUserData/index.vue
Example #3a 36 / 48
Example #3a 37 / 48
38 / 48
Example #3b
Structure
$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
7directories,12files
{
"name":"myproj",
"description":"AVue.jsproject",
"version":"1.0.0",
"author":"EM",
"private":true,
"scripts":{
"dev":"cross-envNODE_ENV=developmentwebpack-dev-server--open--inline--hot--host0.0.0.0"
"build":"cross-envNODE_ENV=productionwebpack--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 #3b
package.json
varpath=require('path')
varwebpack=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:{
//Sincesass-loader(weirdly)hasSCSSasitsdefaultparsemode,wemap
//the"scss"and"sass"valuesforthelangattributetotherightconfigshere.
//otherpreprocessorsshouldworkoutofthebox,noloaderconfiglikethisnessessary.
'scss':'vue-style-loader!css-loader!sass-loader',
'sass':'vue-style-loader!css-loader!sass-loader?indentedSyntax'
}
//othervue-loaderoptionsgohere
}
},
{
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 #3b
webpack.con g.js
<!DOCTYPEhtml>
<htmllang="en">
<head>
<metacharset="utf-8">
<linkrel="stylesheet"href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic"
<linkrel="stylesheet"href="//fonts.googleapis.com/icon?family=Material+Icons">
<title>myproj</title>
</head>
<body>
<divid="app"></div>
<scriptsrc="/dist/build.js"></script>
</body>
</html>
/*---------------------------*/
importVuefrom'vue'
importAppComponentfrom'./App/index.vue'
importVueMaterialfrom'vue-material'
import'vue-material/dist/vue-material.css'
import'./css/app.css'
Vue.use(VueMaterial)
constvm=newVue({
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 #3b
index.html
src/main.js
src/css/app.css
<template>
<divid="app">
<md-toolbar><h1class="md-title">LearningVue.JS</h1></md-toolbar>
<divclass="main-content">
<p>EnteryourusernametogetsomeGithubstats!</p>
<github-input></github-input>
<github-output></github-output>
</div></div>
</template>
<script>
importGithubInputfrom'../GithubInput/index.vue'
importGithubOutputfrom'../GithubOutput/index.vue'
exportdefault{
name:'App',
components:{
'github-input':GithubInput,
'github-output':GithubOutput,
},
data(){
return{}
},
}
</script>
<stylescoped>
p{
color:red;
}
</style>
42 / 48
Example #3b
src/App/index.vue
<template>
<div>
<md-input-container>
<label>GithubUser</label>
<md-inputv-model="username"placeholder="Enteragithubusernamehere"></md-input>
</md-input-container>
<md-buttonclass="md-raisedmd-primary"v-on:click="onSubmit">Go!</md-button>
</div>
</template>
<script>
importbusfrom'../bus'
exportdefault{
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 #3b 44 / 48
Example #3b 45 / 48
Refs
46 / 48
Refs
1. vuejs.org
2. vuejs/vue: Simple yet powerful library for building modern web interfaces.
3. Comparison with Other Frameworks - vue.js
4. Introduction - Vue Material
5. Getting up and Running with the Vue.js 2.0 Framework
6. jackfranklin/vue2-demo-proj
47 / 48
48 / 48
END
Eueung Mulyana
https://eueung.github.io/112016/vuejs
CodeLabs | Attribution-ShareAlike CC BY-SA

Vue js and Vue Material