-- linjianghe, 2016.7.7
一个构建数据驱动的 web 界面的库
Vue.js is a library for building interactive web interfaces.
MVVM
<div id="app">
<app-nav></app-nav>
<app-view>
<app-sidebar></app-sidebar>
<app-content></app-content>
</app-view>
</div>
没有好与不好,只有适合和不适合
<p>result: <span id="result">0</span></p>
<button id="plusBtn">加1</button>
$(function () {
$('#plusBtn').on('click', function () {
var oldVal = parseInt($('#result').text());
$('#result').text(oldVal + 1);
});
});
<p>result: <span v-text="result"></span></p>
<button v-on:click="plusOne">加1</button>
new Vue({
el: 'body',
data: {
result: 0
},
methods: {
plusOne: function () {
this.result++;
}
}
})
jQuery的写法
Vue.js的写法
<p>result: <span id="result">0</span></p>
<button id="plusBtn">加1</button>
<button id="reduceBtn">减1</button>
$(function () {
$('#plusBtn').on('click', function () {
var oldVal = parseInt($('#result').text());
$('#result').text(oldVal + 1);
});
$('#reduceBtn').on('click', function () {
var oldVal = parseInt($('#result').text());
$('#result').text(oldVal - 1);
});
});
<p>result: <span v-text="result"></span></p>
<button v-on:click="plusOne">加1</button>
<button v-on:click="reduceOne">减1</button>
new Vue({
el: 'body',
data: {
result: 0
},
methods: {
plusOne: function () {
this.result++;
},
reduceOne: function () {
this.result--;
}
}
})
jQuery的写法
Vue.js的写法
<p>result: <span id="result">0</span></p>
<p>操作按钮点击数: <span id="clickCount">0</span> 次,
最终的结果是<span id="finalResult"></span></p>
<button id="plusBtn">加1</button>
<button id="reduceBtn">减1</button>
$(function () {
$('#plusBtn').on('click', function () {
var oldVal = parseInt($('#result').text());
$('#result').text(oldVal + 1);
var oldClickCount = parseInt($('#clickCount').text());
$('#clickCount').text(oldClickCount + 1);
$('#finalResult').text($('#result').text());
});
$('#reduceBtn').on('click', function () {
var oldVal = parseInt($('#result').text());
$('#result').text(oldVal - 1);
var oldClickCount = parseInt($('#clickCount').text());
$('#clickCount').text(oldClickCount + 1);
$('#finalResult').text($('#result').text());
});
});
<p>result: <span v-text="result"></span></p>
<p>操作按钮点击数: <span v-text="clickCount"></span> 次,
最终的结果是<span v-text="result"></span></p>
<button v-on:click="plusOne">加1</button>
<button v-on:click="reduceOne">减1</button>
new Vue({
el: 'body',
data: {
result: 0,
clickCount: 0
},
methods: {
plusOne: function () {
this.result++;
this.clickCount++;
},
reduceOne: function () {
this.result--;
this.clickCount++;
}
}
})
jQuery的写法
Vue.js的写法
Template
ViewModel
End Result
Vue 实例在创建时有一系列初始化步骤——例如,它需要建立数据观察,编译模板,创建必要的数据绑定。在此过程中,它也将调用一些生命周期钩子,给自定义逻辑提供运行机会。
/**
* Define a reactive property on an Object.
*
* @param {Object} obj
* @param {String} key
* @param {*} val
*/
function defineReactive(obj, key, val) {
var dep = new Dep();
var property = Object.getOwnPropertyDescriptor(obj, key);
if (property && property.configurable === false) {
return;
}
// cater for pre-defined getter/setters
var getter = property && property.get;
var setter = property && property.set;
var childOb = observe(val);
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter() {
var value = getter ? getter.call(obj) : val;
if (Dep.target) {
dep.depend();
if (childOb) {
childOb.dep.depend();
}
if (isArray(value)) {
for (var e, i = 0, l = value.length; i < l; i++) {
e = value[i];
e && e.__ob__ && e.__ob__.dep.depend();
}
}
}
return value;
},
set: function reactiveSetter(newVal) {
var value = getter ? getter.call(obj) : val;
if (newVal === value) {
return;
}
if (setter) {
setter.call(obj, newVal);
} else {
val = newVal;
}
childOb = observe(newVal);
dep.notify();
}
});
}
...
v-if
v-show
...
import Vuex from 'vuex'
const state = {
count: 0
}
const mutations = {
INCREMENT (state) {
state.count++
}
}
export default new Vuex.Store({
state,
mutations
})
import store from './store.js'
// 变更
store.dispatch('INCREMENT')
// 读取
console.log(store.state.count) // -> 1
store.js
app.js
<template>
<div>
<Display></Display>
<Increment></Increment>
</div>
</template>
<script>
import Display from './Display.vue'
import Increment from './Increment.vue'
export default {
components: {
Display: Display,
Increment: Increment
}
}
</script>
<template>
<div>
<h3>Count is 0</h3>
</div>
</template>
<script>
export default {}
</script>
App.vue,根组件
Display.vue,子组件
<template>
<div>
<button>Increment +1</button>
</div>
</template>
<script>
export default {}
</script>
Increment.vue,子组件
import Vue from 'vue'
import Vuex from 'vuex'
// 告诉 vue “使用” vuex
Vue.use(Vuex)
// 创建一个对象来保存应用启动时的初始状态
const state = {
// TODO: 放置初始状态
}
// 创建一个对象存储一系列我们接下来要写的 mutation 函数
const mutations = {
// TODO: 放置我们的状态变更函数
}
// 整合初始状态和变更函数,我们就得到了我们所需的 store
// 至此,这个 store 就可以连接到我们的应用中
export default new Vuex.Store({
state,
mutations
})
import Display from './Display.vue'
import Increment from './IncrementButton.vue'
import store from '../vuex/store' // import 我们刚刚创建的 store
export default {
components: {
Display: Display,
Increment: Increment
},
store: store // 在根组件加入 store,让它的子组件和 store 连接
}
// action 会收到 store 作为它的第一个参数
// 既然我们只对事件的分发(dispatch 对象)感兴趣。(state 也可以作为可选项放入)
// 我们可以利用 ES6 的解构(destructuring)功能来简化对参数的导入
export const incrementCounter = function ({ dispatch, state }) {
dispatch('INCREMENT', 1)
}
<template>
<div>
<button @click='increment'>Increment +1</button>
</div>
</template>
<script>
import { incrementCounter } from '../vuex/actions'
export default {
vuex: {
actions: {
increment: incrementCounter
}
}
}
</script>
import Vue from 'vue'
import Vuex from 'vuex'
// 告诉 vue “使用” vuex
Vue.use(Vuex)
const state = {
// 应用启动时,count 置为0
count: 0
}
const mutations = {
// mutation 的第一个参数是当前的 state
// 你可以在函数里修改 state
INCREMENT (state, amount) {
state.count = state.count + amount
}
}
// 整合初始状态和变更函数,我们就得到了我们所需的 store
// 至此,这个 store 就可以连接到我们的应用中
export default new Vuex.Store({
state,
mutations
})
<template>
<div>
<h3>Count is {{ counterValue }}</h3>
</div>
</template>
<script>
import { getCount } from '../vuex/getters'
export default {
vuex: {
getters: {
counterValue: state => state.count
}
}
}
</script>
import Vue from 'vue'
import Vuex from '../../../src'
import * as actions from './actions'
// 导入各个模块的初始状态和 mutations
import cart from './modules/cart'
import products from './modules/products'
Vue.use(Vuex)
export default new Vuex.Store({
// 组合各个模块
modules: {
cart,
products
}
})
store.cart.xxx
State:状态,单一状态树
Mutations:变更状态,本质是一个事件系统,必须是同步函数
Actions:操作,可以是同步函数,也可以是异步函数,用于分发 mutations 的函数
https://github.com/vuejs/vue-devtools
注意:需要使用dev版本的Vue.js
1. components:Vue.js组件
2. lego_modules
3. modules
4. pages
1. 与当前业务无关
2. 可以复用在其他项目中
例如 Vue.js版的BootStrap
<vs-alert
show.sync="showVariable"
:state="state"
dismissible>
This is an alert
</vs-alert>
<div class="online">
<video-play></video-play>
<room-header></room-header>
<room-button></room-button>
</div>
如果某个组件只用在特定的组件下,推荐将其放在其目录下
1. html inline到template中
2. css require
3. 引用其他组件import进来