Vue.js /vju:/
数据驱动+组件化的前端开发
What are Vue.js 弄啥嘞?
- 一个轻量的 MVVM 前端框架
UI = VM(State)
-
MVVM?
- Model - View - ViewModel
- 数据改变, UI 随之改变
Vue.js 闪光点
- 专注于视图(View)层
- 数据驱动
- 上手简单、简洁优雅的 API
- 快速、高性能
- 基于组件
- 轻量且无其他库的依赖 (~24kb min+gzip)
Vue.js – Intro
专注于视图(View)层
- Vue 类似于 React 只是 MV* 架构中的视图层
-
虽然作者灵感来源于 Angular,但有本质的差别:
- Angular 是大而全的“重”框架
-
数据绑定机制不同
- 与 Angular/React/Ember/Ployer/Riot 的对比看 这个链接
Vue.js – Intro
数据驱动
- 模板表达式
- 计算属性
- 自动追踪依赖
Vue.js – Intro
上手简单、简洁优雅的 API
- 一点儿 HTML 模板
- 一点儿 JSON 数据
- 创建一个 Vue 实例
- 搞定...
Vue.js – Intro
<!-- HTML -->
<div id="demo">
<p>
{{msg ? msg : "no content"}}
</p>
<input type="text" v-model="msg">
</div>
// json 数据
var jsonData = {
msg: 'Hello Vue.js!'
};
// vue 实例
var vm = new Vue({
el : '#demo',
data: jsonData
});
举个栗子
Vue.js – Intro
Vue 中的指令缩写
<!-- 1. 动态绑定一个或多个属性 -->
<!-- 绑定 attribute -->
<img v-bind:src="imageSrc">
<!-- 缩写 -->
<img :src="imageSrc">
<!-- 绑定 class -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]"></div>
<!-- 绑定 style -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>
<!-- 2. 绑定事件: click、submit、keyup...甚至自定义事件如 my-event -->
<a v-on:click="someFunc"></a>
<a @click="someFunc"></a>
<my-component @my-event="handleThis"></my-component>
Vue.js – Intro
快速、高性能
- 精确有效的异步批量 DOM 更新
- 尤其对比于 Angular 1 的脏检查
vm.msg = 'one';
vm.msg = 'two';
vm.msg = 'three';
// 只会触发一次 DOM 更新
Vue.js – Intro
基于组件
- 使用解耦、可复用的组件来构造界面
- 基本步骤:
- 定义
- 注册
- 使用
Vue.js – Intro
// 组件定义
var MyComponent = Vue.extend({
template: '<div>A custom component!</div>'
// template: '#tmpl'
});
// 全局注册
Vue.component('my-component', MyComponent);
// 创建根实例
new Vue({
el: '#example'
});
组件栗子
<!-- 组件的使用 -->
<div id="example">
<my-component></my-component>
</div>
<!-- template 使用 id
<template id="tmpl">
<div>
A custom component!
</div>
</template>
-->
<!-- HTML -->
<div id="example">
<div>A custom component!</div>
</div>
Vue.js – Intro
组件间的数据交流
1. props
- 定义组件数据的传递
- 3种绑定方式
2. event
- 通过事件和回调传递
- 多种信息传递方式
3. inherit
继承-
1.0版本后已被废弃
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 – Intro
轻量且无其他库的依赖
- 开启 min+gzip ~24kb
- vue 2.0:
- min+gzip ~12kb
- 加编译器 min+gzip ~17kb
- React 15 min+gzip ~44kb
- Angular 就不提了...
Vue.js – Intro
栗子展示
Vue.js – Examples
列表渲染
<!-- HTML -->
<div id="app">
<ul>
<li v-for="todo in todos">
{{todo.text}}
</li>
</ul>
</div>
var vm = new Vue({
el: '#app',
data: {
todos: [
{ text: 'Learn JavaScript' },
{ text: 'Learn Vue.js' },
{ text: 'Build Something Awesome' }
]
}
});
Vue.js – Examples
处理用户输入
<!-- HTML -->
<div id="app">
<p>{{msg}}</p>
<button
v-on:click="reverseMsg">
Reverse Message
</button>
</div>
var vm = new Vue({
el: '#app',
data: { msg: 'Hello Vue.js!' },
methods: {
reverseMsg: function() {
this.msg = this.msg.split('')
.reverse()
.join('');
}
}
});
Vue.js – Examples
结合以上
<!-- HTML -->
<div id="app">
<input
v-model="newTodo"
v-on:keyup.enter="addTodo">
<ul>
<li v-for="todo in todos">
<span>{{todo.text}}</span>
<button v-on:click="rmTodo($index)">X</button>
</li>
</ul>
</div>
var vm = new Vue({
el: '#app',
data: {
newTodo: '',
todos: [
{ text: 'Add some todos' }
]
},
methods: {
addTodo: function () {
var text = this.newTodo.trim();
if (text) {
this.todos.push({
text: text
});
this.newTodo = '';
}
},
rmTodo: function (index) {
this.todos.splice(index, 1);
}
}
});
Vue.js – Examples
极简的 markdown 编辑器
<!-- HTML -->
<div id="editor">
<textarea v-model="input" debounce="300"></textarea>
<div v-html="input | marked"></div>
</div>
var vm = new Vue({
el: '#editor',
data: {
input: '# hello'
},
filters: {
marked: marked
}
});
Vue.js – Examples
表格组件
Vue.js – Examples
SVG 图形
Vue.js – Examples
更多栗子参见
Vue.js – Examples
Vue.js – Basics
// Object.defineProperty
// getter / setter / watcher object
var a = {};
Object.defineProperty(a, 'b', {
enumerable: false,
value: "static",
get: () => { ... },
set: () => { ... }
});
Vue.js 的实现原理
如果需要构建大型应用,那么可能还需要以下的工具...
构建大型应用
Vue-cli
- Webpack / Browerify
- Hot reloading
- Linting
- Unit/e2e tests
- CSS extraction
Vue ecosystem
- Vue-router
- Vuex
- Vue-devtools
- Vue-touch
- Vue-validation
- and more...
Vue.js – Basics
单文件组件
Vue.js – Basics
带预处理器的
单文件组件
Vue.js – Basics
scoped 属性
注意:scoped 不会影响 css的作用优先级,因此使用 scoped 不代表不会被外部样式所覆盖!
可以将该样式限制在此组件内部,从而不会与外部同名样式形成冲突。
Vue.js – Basics
Vue.js – jQuery
Vue.js VS jQuery
- What VS How
- 声明式 VS 命令式
- 操作数据 VS 操作 DOM
Vue.js VS jQuery
<div id="demo">
<p>hello jQuery!</p>
<input type="text" value="hello jQuery!">
</div>
// 1.(手动)找到 input 节点
var $input = $('#demo > input');
// 2.(手动)找到 p 节点
var $p = $('#demo > p');
// 3.(手动)监听键盘事件
$input.keyup(function() {
var newText = $input.val() ?
$input.val() :
'no content';
// 4.(手动)更新 dom
$p.text(newText);
});
Vue.js – jQuery
Vue.js VS jQuery
- jQuery 的处理逻辑是【命令式】地【手动】地【操作 DOM】,即在不断地处理怎么(how)做的问题。并且 jQuery 代码往往和 DOM 结构强耦合,不利于修改、单元测试等。
- Vue.js 的处理逻辑是【声明式】地绑定数据和 DOM 后,直接【操作数据】(几乎不直接操作 DOM),即只关心是什么(what)的问题。基于组件接口,可以方便地修改和编写单元测试。
Vue.js – jQuery
我理解的前端开发
UE
Front End
Back End
Project Manager
*.psd
api
Quality
Assurance
Server Side Render
Node.js
Vue.js – jQuery
Vue-Router
Vue.js – Plugins
import Vue from 'vue';
import Router from 'vue-router';
import App from './app.vue';
import ViewA from './view-a.vue';
import ViewB from './view-b.vue';
Vue.use(Router);
const router = new Router();
router.map({
'/a': { component: ViewA },
'/b': { component: ViewB }
});
router.start(App, '#app');
<div>
<h1>This is the layout that won't change</h1>
<router-view>
<!-- matched component renders here -->
</router-view>
</div>
Vue.js – Plugins
vuex
Vuex 栗子
import Vuex from 'vuex';
const state = { counter: 0 };
const mutations = {
INCREMENT (state) { state.counter++ }
};
export default new Vuex.Store({
state,
mutations
});
store.dispatch('INCREMENT');
console.log(store.state.count); // -> 1
Vue.js – Plugins
Vue.js – Plugins
Vuex 栗子说明
Vue.js – Plugins
Vue-devtools
Vue.js – 2.0
Vue.js 2.0
- 轻量级 virtual-DOM(不再是Browser-Only)
- 可以像之前一样让编译器在浏览器中运行 ~17kb
- 也可以将模板预编译后直接运行 ~12kb
- 不需要额外的工作就获得优化的重渲染
- 不需要 shouldComponentUpdate 或 immutable 数据
- 流式服务器端渲染(Streaming Server-side Rendering)
- 既然引入 v-dom 自然支持 ssr 和客户端的 hydration
- 解决同步渲染阻塞的痛点:渲染时返回可读 stream 直接 pipe 到 HTTP 的 responce
- 移动端 native 的探索:weex(by 阿里无线事业部)
Vue.js – ref
参考资料
- 官网: vuejs.org
- 勾股: Vue.js 源码学习笔记
- Github: awesome-vue
- Github: vue-cli
- Github: vue-loader
- Github: vuex
- 知乎专栏: Announcing Vue.js 2.0
- 勾股: Code Review for Vue 2.0 Preview
- Github Issues: weex
- Damian Dulisz: meet-vue-js
- 阴明: vue.js 组件化编程
- Martin Janyš: Vue.js slides
Essential Copying and Pasting From StackOverflow
关于 Vue.js 的小介(an)绍(li)~
By steve young
关于 Vue.js 的小介(an)绍(li)~
骚年,你听说过 Vue 吗?
- 2,620