Ming YIN
Crazy Monster!
💗 ming @ xitu.io 💗
Ming Yin
稀土创始人 🙄
前端工程师 🐶
二流设计师 🙀
ming@xitu.io
ming.today
@kalasoo
Reactive Components for Modern Web Interfaces
数据驱动的组件,为现代化的 Web 界面而生
尤小右 Evan You
@youyuxi
多说 / Google / Meteor
发布于 2014 年 2 月
UI = VM(State)
基于一定的准则写
写起来更容易
代码更易维护
网站的业务逻辑可以不断扩展
性能可以满足需求
<div id="demo">
<p>{{message ? message : "no content"}}</p>
<input v-model="message">
</div>
var demo = new Vue({
el: '#demo',
data: {
message: 'Hello Vue.js!'
}
})
CodePen 加载中
// Object.defineProperty
// getter / setter / watcher object
var a = {}
Object.defineProperty(a, 'b', {
enumerable: false,
value: "static",
get: () => { ... },
set: () => { ... }
})
v1.0.21
大量的配套工具
vue-loader
vue-cli
vue-router
NPM 总下载 58 万+
>8K D/M
主页超过 400 万的 PV
及我这种无良的 👏👏👏
为什么很多人接触了 Vue.js 后很快就爱上了它?
人同时可以处理的信息是有限的
这是你搞不定的
一大堆东西
这是你搞得定的一堆小东西
和你能搞得定的一个关系网
// app.js 定义
var MyComponent = Vue.extend({
template: '<div>A custom component!</div>'
})
// app.js 注册
Vue.component('my-component', MyComponent)
// app.js 创建根实例
new Vue({
el: '#example'
})
<!-- HTML -->
<div id="example">
<my-component></my-component>
</div>
<script src="app.js"></script>
<div id="example">
<div>A custom component!</div>
</div>
// comment.vue
<style lang="sass">
button {
border: 1px solid gray;
&.blue { border-color: blue; }
}
</style>
<template lang="jade">
avatar(:user='user')
input(type='text', v-model='content')
button.blue(@click='submitComment')
</template>
<script>
import Comment from '../models'
import avatar from './components/avatar.vue'
export default {
props: ['user'],
components: {
avatar
},
data () {
return {
content: ''
}
},
methods: {
submitComment (e) {
e.preventDefault();
var comment = new Comment(this.content)
comment.save().then(() => {
alert('评论成功')
this.content = ''
})
}
}
}
</script>
✌
.vue: 一个文件来管理一个组件
A module bundler
一个模块打包工具
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'
},
resolveLoader: {
root: path.join(__dirname, 'node_modules'),
},
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue'
},
{
test: /\.js$/,
loader: 'babel!eslint',
exclude: /node_modules/
},
{
test: /\.html$/,
loader: 'vue-html'
}
]
}
}
.
├── index.html
├── main.js
├── components
│ ├── App.vue
│ ├── ComponentA.vue
│ └── ComponentB.vue
├── package.json
└── webpack.config.js
// webpack.config.js
module.exports = {
// entry point of our application
entry: './main.js',
// where to place the compiled bundle
output: {
path: __dirname,
filename: 'build.js'
},
module: {
// `loaders` is an array of loaders to use.
// here we are only configuring vue-loader
loaders: [
{
test: /\.vue$/,
loader: 'vue'
}
]
}
}
// main.js
var Vue = require('vue')
// require a *.vue component
var App = require('./components/App.vue')
// mount a root Vue instancenew
Vue({
el: 'body',
components: {
// include the required component
// in the options
app: App
}
})
<!-- App.vue -->
<template>
<div class="app">
<component-a></component-a>
<component-b></component-b>
</div>
</template>
<script>
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'
export default {
components: {
ComponentA,
ComponentB
}
}
</script>
Vue.component('child', {
// 声明 props
props: ['msg'],
// prop 可以用在模板内
// 可以用 `this.msg` 设置
template: '<span>{{ msg }}</span>'
})
<!-- 默认为单向绑定 -->
<child :msg="parentMsg"></child>
<!-- 双向绑定 -->
<child :msg.sync="parentMsg"></child>
<!-- 单次绑定 -->
<child :msg.once="parentMsg"></child>
// 监听某一个事件
$on('create-alert', () => { ... })
// 在同一个组件里触发事件
$emit('create-alert', { ... })
// 向上传递一个事件
$dispatch('create-alert', { ... })
// 向下所有的组件传递一个事件
$broadcast('create-alert', { ... })
一个基于 Vue.js 的 State Management 工具
管理那些应用级的共享数据
🔥 Thanks for your time 🔥
🔞 ming@xitu.io 🔞
By Ming YIN
Coding 线下活动上的 Vue.js 分享