继 AngularJS 和 React 之后,Vue 又为前端框架烧起了一把火,作者是华人,刚刚宣布加盟阿里的跨平台移动开发工具 Weex 担任技术顾问,Vue2 即将发布,作者最近一段时间一直在闭关创作
Vue 属于 MVVM 架构,区别于 MVC,这个可以参考网上的一个解释:
在MVC里,View是可以直接访问Model的!从而,View里会包含Model信息,不可避免的还要包括一些业务逻辑。 MVC模型关注的是Model的不变,所以,在MVC模型里,Model不依赖于View,但是 View是依赖于Model的。不仅如此,因为有一些业务逻辑在View里实现了,导致要更改View也是比较困难的,至少那些业务逻辑是无法重用的
MVVM在概念上是真正将页面与数据逻辑分离的模式,它把数据绑定工作放到一个JS里去实现,而这个JS文件的主要功能是完成数据的绑定,即把model绑定到UI的元素上
部署很简单:
// latest stable $ npm install vue
功能:
模板功能:
<div id="app">
{{ message }}
</div>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
双向绑定机制:
<div id="app">
<p>{{ message }}</p>
<input v-model="message">
</div>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
逻辑:
没有把循环交给模板机制,而是给了 HTML 的属性,非常的智慧
<div id="app">
<ul>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ul>
</div>
new Vue({
el: '#app',
data: {
todos: [
{ text: 'Learn JavaScript' },
{ text: 'Learn Vue.js' },
{ text: 'Build Something Awesome' }
]
}
})
支持的逻辑有:
- v-for 循环
- v-if 布尔if 判断
- v-show 对 CSS 的 display 做切换处理
- v-else 布尔else 判断
事件
把事件也交给了 HTML 的属性来处理,防止外部加载的事件在模板处理以后丢失的好方法
<div id="app">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">Reverse Message</button>
</div>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})
调试
有一个叫做 Vue.js devtools 的 Chrome Developer Tools 集成插件,可以帮助到 Vue 的调试
代码里面注意要添加:
Vue.config.debug = true
Vue.config.devtools = true
组件机制
Vue 的组件机制,类似于一种使用面向对象的方式来撰写小部件的感觉,看一下这个例子:
HTML里面:
<ul id="productListTemplate">
<product-list></product-list>
</ul>
<template id="productList">
<li v-for="product in products">
<div class="product-list-btn">
<a href="/product/info/@{{ product.product.id }}">查看详情</a>
<a href="/product">我要购买</a>
</div>
</li>
</template>
JS里面:
Vue.component('product-list', {
template: '#productList',
data: function() {
return{
products: []
}
},
ready: function () {
this.fetchProducts();
},
methods: {
fetchProducts: function () {
var products = [];
this.$http.get('/api1.0/product/list')
.then((response) => {
this.$set('products', response.body.data.items);
}, (response) => {
products.log(err);
});
},
}
})
new Vue({
el: '#productListTemplate'
})
一段输出页面和分页的代码:
<template id="productList">
<ul class="product-list clearfix">
<div class="col-sm-6 col-md-4" v-for="product in products">
<h3>@{{ product.product.name }}</h3>
<p>@{{ product.product.content }}</p>
</div>
</ul>
<div class="cf-pagination" id="pagination">
<ul class="pagination pagination-lg">
<li v-if="pagination.pre_page"><a href="javascript:void(0)" v-on:click="fetchProducts(pagination.next_page)">«</a></li>
<li :class="pagination.current_page == page ? 'active' : null" v-for="page in pagination.page_area"><a href="javascript:void(0)" v-on:click="fetchProducts(page)">@{{page}}</a></li>
<li v-if="pagination.next_page"><a href="javascript:void(0)" v-on:click="fetchProducts(pagination.next_page)">»</a></li>
</ul>
</div>
</template>
<script>
Vue.component('product-list', Vue.extend({
template: '#productList',
data: function() {
return{
products: [], pagination: []å
}
},
ready: function () {
this.fetchProducts(1);
},
methods: {
fetchProducts: function (page) {
var products = [];
this.$http.get(api_url + '/product/list/?page=' + page)
.then((response) => {
this.$set('products', response.body.data.items);
this.$set('pagination', response.body.data.pagination);
}, (response) => {
products.log(err);
});
},
}
}))
new Vue({
el: '#product-lists'
})
</script>