vue是前端兴起的一个javascript库,相信大家都使用过jQuery,虽然vue和jQuery没有可比性,但从熟悉的角度去理解新的东西或许会容易接受一些,有时候由于思想和模式的转变会带来阵痛,但领悟到了却会有一种如何至宝的感觉。

简单来说jQuery是操作页面的dom对象,而vue是操作页面的data数据,也就是将原来的操作dom的思想转变到操作数据上来。

vue是一个精简的MVVM,是一套构建用户界面的渐进式框架,专注于 MVVM 模型的 ViewModel 层。它通过双向数据绑定把 View 层和 Model 层连接了起来,通过对数据的操作就可以完成对页面视图的渲染。

vue和jQuery两者的侧重点是不一样的,所以在很多场合,我们需要结合起来使用,比如操作dom对象以及一些动画效果时,我们可以使用jQuery,在对复杂的数据操作,比如计算双向绑定,以及表单页面等,我们就可以使用vue来做更容易一些。

作为一个会后端的前端工程师,从seo的角度来说,我更喜欢使用后端mvc模式来操作和绑定数据,而像vue,Angular,React等js库提倡的View与数据分离,其本质上依旧是在前端进行js操作,对seo都不是那么友好,在一些不需要考虑seo系统或平台上(比如移动端),我们可以怎么方便怎么来。

学习vue,我们可以从一个应用最多的实例开始,分页数据绑定,如图:(或预览效果http://www.yealuo.com/Resource/Journal/FileUrl/38FC57B2-345B-4923-9D13-C9B201CE23BA/Index.html

要用vue实现上面的效果图,如何实现呢!

首先我们需要重构静态HTML

<div id="app">
<ul>
<li><h6><a target="_blank" href="http:\\www.yealuo.com/Cntv/Detail?ArticleType=WenZhang&amp;KeyValue=CD9291BC-1BA9-4FE2-B5BF-341A24998722">相忘于江湖/简媜</a></h6></li>
<li><h6><a target="_blank" href="http:\\www.yealuo.com/Cntv/Detail?ArticleType=TuHua&amp;KeyValue=70A807BD-A859-4172-9A6A-FEB21A75008F">2019419绝代尤物</a></h6></li>
<li><h6><a target="_blank" href="http:\\www.yealuo.com/Cntv/Detail?ArticleType=TuHua&amp;KeyValue=6A985247-CC73-4AA1-90D7-8D2F49896279">年少无知</a></h6></li>
<li><h6><a target="_blank" href="http:\\www.yealuo.com/Cntv/Detail?ArticleType=TuHua&amp;KeyValue=52BF13C9-1FCC-4C69-8968-4F0B96278B25">十年</a></h6></li>
<li><h6><a target="_blank" href="http:\\www.yealuo.com/Cntv/Detail?ArticleType=QingBao&amp;KeyValue=5D81C7A6-5861-4055-85BC-4356B4DD522B">关于哥哥张国荣(3)</a></h6></li>
</ul>
<ul class="page-bar">
<!---->
<li><a class="banclick">上一页</a></li>
<li class="active"><a>1</a></li>
<li class=""><a>2</a></li>
<li><a class="">下一页</a></li>
<!---->
<li><a>共<i>2</i>页</a></li>
</ul>
</div>
<style type="text/css"> html, body {
width: 100%;
font-family: "PingFang SC-Medium,sans-serif", "Noto Sans CJK SC,sans-serif", Arial, "Microsoft YaHei";
background-color: #f5f5f5;
} ul, ol, li {
padding:0;margin:0;
list-style: none;
} [v-cloak] {
display: none;
} .cont-item {
padding: 0.35rem 0.1rem;
font-size: 0.14rem;
color: #666;
} .page-bar li:first-child > a {
margin-left: 0px;
} .page-bar a {
border: 1px solid #ddd;
text-decoration: none;
position: relative;
float: left;
padding: 6px 12px;
margin-left: -1px;
line-height: 1.42857143;
color: #337ab7;
cursor: pointer;
} .page-bar a:hover {
background-color: #eee;
} .page-bar a.banclick {
cursor: not-allowed;
} .page-bar .active a {
color: #fff;
cursor: default;
background-color: #337ab7;
border-color: #337ab7;
} .page-bar i {
font-style: normal;
color: #d44950;
margin: 0px 4px;
font-size: 12px;
}
</style>

得到我们想要的静态页面,然后就是使用vue对数据进行绑定

在没有获取后台数据前,我们可以先实现页码单击的模拟,只需要初始化两个数据,一个总页数,一个当前页码就可以了。

(1)实例化vue构造器

<div id="app">
<ul class="page-bar">
<li v-if="page>1"><a>上一页</a></li>
<li v-if="page==1"><a class="banclick">上一页</a></li>
<li v-for="index in indexs" v-bind:class="{ 'active': page == index}">
<a>{{ index }}</a>
</li>
<li v-if="page!=pageTotal"><a>下一页</a></li>
<li v-if="page == pageTotal"><a class="banclick">下一页</a></li>
<li><a>共<i>{{pageTotal}}</i>页</a></li>
</ul>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
page: 1,//当前页码
pageTotal: 14//总页数
},
computed: {
indexs: function () {
var self = this;
var left = 1;
var right = self.pageTotal;
var ar = [];
if (self.pageTotal >= 5) {
if (self.page > 3 && self.page < self.pageTotal - 2) {
left = self.page - 2
right = self.page + 2
} else {
if (self.page <= 3) {
left = 1
right = 5
} else {
right = self.pageTotal
left = self.pageTotal - 4
}
}
}
while (left <= right) {
ar.push(left)
left++
}
return ar
} }
})
</script>

效果图如下:

知识点(1):
在上面的构造器中,我们使用到了vue的内部指令,这里罗列一下vue的内部指令有以下几种:

1、v-bind:响应并更新DOM特性;例如:v-bind:href  v-bind:class  v-bind:title  等等,注意当属性值中出现特殊字符比如-等的时候,需要使用引号。

2、v-on:用于监听DOM事件; 例如:v-on:click  v-on:keyup

3、v-model:数据双向绑定;用于表单输入等;例如:<input v-model="message">

4、v-show:条件渲染指令,为DOM设置css的style属性

5、v-if:条件渲染指令,动态在DOM内添加或删除DOM元素

6、v-else:条件渲染指令,必须跟v-if成对使用

7、v-else-if:判断多层条件,必须跟v-if成对使用;

8、v-text:更新元素的textContent;例如:<span v-text="msg"></span> 等同于 <span>{{msg}}</span>;

9、v-html:更新元素的innerHTML;会把标签名也带上。

10、v-for:循环指令;例如: <li v-for="book in books">{ { book.name } }</li>

11、v-cloak:不需要表达式,这个指令保持在元素上直到关联实例结束编译;v-cloak 是一个解决初始化慢导致页面闪动的最佳实践;

12、v-once:也是一个不需要表达式的指令,作用是定义它的元素或组件只渲染一次,包括元素或组件的所有子节点。

首次渲染后,不再随数据的变化重新渲染,将被视为静态内容;v-once 在业务中也很少使用,当你需要进一步优化性能时,可能会用到。

13、v-pre:不需要表达式,跳过这个元素以及子元素的编译过程,以此来加快整个项目的编译速度;例如:<span v-pre>{{ this will not be compiled }}</span>;

知识点(2):
上面的示例中,我们还用到了vue的计算属性,关键词是computed,在一个计算属性里可以完成各种复杂的逻辑,包括运算、函数调用等,就像上面的示例只要最终返回一个结果就可以了

计算属性还有两个常用的依赖,一是计算属性可以依赖其他计算属性;  二是计算属性不仅可以依赖当前Vue 实例的数据,还可以依赖其他实例的数据,每一个计算属性都包含一个getter 和一个setter ,我们上面的示例是计算属性的默认用法, 只是利用了getter 来读取。

我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。

假设我们有一个性能开销比较大的的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。

如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。

知识点(3):
我们还用到了class 属性绑定,我们大多使用表达式的形式来绑定,表达式的结果类型除了字符串之外,还可以是对象。

1、将 isActive 设置为 true 显示了一个绿色的 div 块,如果设置为 false 则不显示:

<divv-bind:class="{ active: isActive }"></div>

2、还可以在对象中传入多个属性:

<divclass="static"v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>

3、我们也可以直接绑定数据里的一个对象:

<divv-bind:class="classObject"></div>

4、我们可以把一个数组传给 v-bind:class :

<divv-bind:class="[activeClass, errorClass]"></div>

5、我们还可以使用三元表达式来切换列表中的 class :

<divv-bind:class="[errorClass ,isActive ? activeClass : '']"></div>

上面的示例只是做到了分页数据的计算和绑定,并没有实现页码的单击事件,接下来将从绑定事件和调用methods来实现!

(2)绑定事件,假如我们有两个方法,一个是页码单击时调用btnClick(),一个是点击上一页下一页调用pageClick(),HTML代码如下:

<div id="app">
<ul class="page-bar">
<li v-if="page>1"><a v-on:click="page--,pageClick()">上一页</a></li>
<li v-if="page==1"><a class="banclick">上一页</a></li>
<li v-for="index in indexs" v-bind:class="{ 'active': page == index}">
<a v-on:click="btnClick(index)">{{ index }}</a>
</li>
<li v-if="page!=pageTotal"><a v-on:click="page++,pageClick()">下一页</a></li>
<li v-if="page == pageTotal"><a class="banclick">下一页</a></li>
<li><a>共<i>{{pageTotal}}</i>页</a></li>
</ul>
</div>

(3)在methods方法(为了区分我们可以把methods叫执行方法)中定义事件单击的方法:

<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
page: 1,//当前页码
pageTotal: 14//总页数
},
computed: {
indexs: function () {
var self = this;
var left = 1;
var right = self.pageTotal;
var ar = [];
if (self.pageTotal >= 5) {
if (self.page > 3 && self.page < self.pageTotal - 2) {
left = self.page - 2
right = self.page + 2
} else {
if (self.page <= 3) {
left = 1
right = 5
} else {
right = self.pageTotal
left = self.pageTotal - 4
}
}
}
while (left <= right) {
ar.push(left)
left++
}
return ar
} },
//methods方法
methods: {
btnClick: function(data){//页码点击事件
if(data != this.page){
this.page = data
}
console.log('正在单击'+this.page+'页');
},
pageClick: function(){
console.log('现在在'+this.page+'页');
}
}
})
</script>

知识点:
从上面的示例中我们也窥探出computed和methods的区别还有一个就是,methods方法可以直接传递参数给内部所定义的方法,两者在示例中都得到了很好的应用。

效果图:

接下来就是获取后台数据,获取后台数据,这里我们需要引用vue-resource 库,当然我们也可以采用其他方式,比如zepto.js等,然后$.ajax()获取,这在实际应用综合考虑,假如已经引用了一种,其他的就没必要,以减少多文件的加载!

在这里,我们首先引进<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>,然后再在methods方法中继续定义一个getData获取数据的方法,并且在构造器app的data中定义装数据的容器list以及每页需要条数pageSize。

(4)定义获取数据方法

data: {
list:[],
page: 1,//当前页码
pageTotal: 0,//总页数
pageSize: 5//每页加载条数
}
getData: function () {
var self = this;
if (self.page > self.pageTotal && self.pageTotal != 0) return; self.showLoading = true; //发送get请求
this.$http.get("http://www.yealuo.com/YeaTool/GetTable?page=" + self.page + "&rows=" + self.pageSize).then(function (res) {
var data = res.body;
if (data && data.start == '0') { if (data.pageData.total) { self.pageTotal = data.pageData.total; } if (self.pageTotal == 0 || !data.pageData.total) { self.loadTxt = '暂无数据'; } else {
if (self.list.length > 0) {
self.list = data.body;
//self.list = self.list.concat(data.body);//concat是追加数组或叫合并数组的方法(可用于点击加载) } else { self.list = data.body; } } } else { alert(data.errorMsg || "系统异常"); } }, function () {
console.log('请求失败处理');
});
}
},

知识点:
说到钩子函数,我们不得不提到另外一个钩子函数created,区别在于created是在实例创建完成后挂载阶段还没开始,也就是模板还没有进行html渲染就立即调用,而mounted调用时,模板已经进行渲染,如果再实例中并没有操作页面元素,则两者可以替换使用!

相应的,页码单击方法也需要调用获取数据方法:

btnClick: function (data) {//页码点击事件
if (data != this.page) {
this.page = data
}
this.getData();
},
pageClick: function () {
this.getData();
},

(5)监听属性 watch,在上面我们在单击页码的时候重复调用获取数据的方法,在vue中我们还有更好的方式,就是可以通过 watch 来响应数据的变化来执行获取数据的方法

mounted: function () {
this.getData();
},

单击事件中的调用就可以注释掉了。

效果查看:http://www.yealuo.com/Resource/Journal/FileUrl/38FC57B2-345B-4923-9D13-C9B201CE23BA/Index.html

完整dome代码如下:

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<meta charset="utf-8">
<title></title>
<meta name="keywords" content="http://www.yealuo.com/" />
<meta name="description" content="http://www.yealuo.com/" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>
<style type="text/css"> html, body {
width: 100%;
font-family: "PingFang SC-Medium,sans-serif", "Noto Sans CJK SC,sans-serif", Arial, "Microsoft YaHei";
background-color: #f5f5f5;
} ul, ol, li {
padding:0;margin:0;
list-style: none;
} [v-cloak] {
display: none;
} .cont-item {
padding: 0.35rem 0.1rem;
font-size: 0.14rem;
color: #666;
} .page-bar li:first-child > a {
margin-left: 0px;
} .page-bar a {
border: 1px solid #ddd;
text-decoration: none;
position: relative;
float: left;
padding: 6px 12px;
margin-left: -1px;
line-height: 1.42857143;
color: #337ab7;
cursor: pointer;
} .page-bar a:hover {
background-color: #eee;
} .page-bar a.banclick {
cursor: not-allowed;
} .page-bar .active a {
color: #fff;
cursor: default;
background-color: #337ab7;
border-color: #337ab7;
} .page-bar i {
font-style: normal;
color: #d44950;
margin: 0px 4px;
font-size: 12px;
}
</style>
</head>
<body>
<div id="app">
<ul> <li v-for="item in list"><h6 v-html="item.ArticleTitle"></h6></li> </ul> <ul class="page-bar">
<li v-if="page>1"><a v-on:click="page--,pageClick()">上一页</a></li>
<li v-if="page==1"><a class="banclick">上一页</a></li>
<li v-for="index in indexs" v-bind:class="{ 'active': page == index}">
<a v-on:click="btnClick(index)">{{ index }}</a>
</li>
<li v-if="page!=pageTotal"><a v-on:click="page++,pageClick()">下一页</a></li>
<li v-if="page == pageTotal"><a class="banclick">下一页</a></li>
<li><a>共<i>{{pageTotal}}</i>页</a></li>
</ul>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
list:[],
page: 1,//当前页码
pageTotal: 0,//总页数
pageSize: 5//每页加载条数
},
computed: {
indexs: function () {
var self = this;
var left = 1;
var right = self.pageTotal;
var ar = [];
if (self.pageTotal >= 5) {
if (self.page > 3 && self.page < self.pageTotal - 2) {
left = self.page - 2
right = self.page + 2
} else {
if (self.page <= 3) {
left = 1
right = 5
} else {
right = self.pageTotal
left = self.pageTotal - 4
}
}
}
while (left <= right) {
ar.push(left)
left++
}
return ar
} },
//methods方法
methods: {
btnClick: function (data) {//页码点击事件
if (data != this.page) {
this.page = data
}
// this.getData();
},
pageClick: function () {
// this.getData();
}, getData: function () {
var self = this;
if (self.page > self.pageTotal && self.pageTotal != 0) return; self.showLoading = true; //发送get请求
this.$http.get("http://www.yealuo.com/YeaTool/GetTable?page=" + self.page + "&rows=" + self.pageSize).then(function (res) {
var data = res.body;
if (data && data.start == '0') { if (data.pageData.total) { self.pageTotal = data.pageData.total; } if (self.pageTotal == 0 || !data.pageData.total) { self.loadTxt = '暂无数据'; } else {
if (self.list.length > 0) {
self.list = data.body;
//self.list = self.list.concat(data.body);//concat是追加数组或叫合并数组的方法(可用于点击加载) } else { self.list = data.body; } } } else { alert(data.errorMsg || "系统异常"); } }, function () {
console.log('请求失败处理');
});
}
},
watch: {
page: function (oldValue, newValue) {
this.getData();//监听事件
}
},
mounted: function () {
this.getData();
},
})
</script> </body>
</html>

学习vue就是那么简单,一个简单的案例的更多相关文章

  1. maven权威指南学习笔记(三)——一个简单的maven项目

    目标: 对构建生命周期 (build  lifecycle),Maven仓库 (repositories),依赖管理 (dependency management)和项目对象模型 (Project O ...

  2. vue中使用vue-i18n 一个简单的国际化操作

    1.安装:npm install vue-i18n --save-dev 2.在main.js文件中引入: import VueI18n from 'vue-i18n' Vue.use(VueI18n ...

  3. Java学习笔记 11/15:一个简单的JAVA例子

    首先来看一个简单的 Java 程序. 来看下面这个程序,试试看是否看得出它是在做哪些事情! 范例:TestJava.java   // TestJava.java,java 的简单范例  public ...

  4. Python框架学习之用Flask创建一个简单项目

    在前面一篇讲了如何创建一个虚拟环境,今天这一篇就来说说如何创建一个简单的Flask项目.关于Flask的具体介绍就不详细叙述了,我们只要知道它非常简洁.灵活和扩展性强就够了.它不像Django那样集成 ...

  5. 【Java学习笔记】如何写一个简单的Web Service

    本Guide利用Eclipse以及Ant建立一个简单的Web Service,以演示Web Service的基本开发过程: 1.系统条件: Eclipse Java EE IDE for Web De ...

  6. Django学习 之 Django安装与一个简单的实例认识

    一.Django简介 1.MVC与MTV模型 (1)MVC模型 Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的. ...

  7. python Django 学习笔记(二)—— 一个简单的网页

    1,创建一个django项目 使用django-admin.py startproject MyDjangoSite 参考这里 2,建立视图 from django.http import HttpR ...

  8. Python学习笔记23:Django构建一个简单的博客网站(一个)

    在说如何下载和安装Django,本节将重点讨论如何使用Django站点. 一 新建project 命令:django-admin startproject mysite # 有的须要输入:django ...

  9. Tomcat学习笔记(一)一个简单的Web服务器

    内容为<深入剖析Tomcat>第一章重点,以及自己的总结,如有描述不清的,可查看原书. 一.HTTP协议: 1.定义:用于服务器与客户端的通讯的协议,允许web服务器和浏览器通过互联网进行 ...

  10. 【学习笔记】tensorflow实现一个简单的线性回归

    目录 准备知识 Tensorflow运算API 梯度下降API 简单的线性回归的实现 建立事件文件 变量作用域 增加变量显示 模型的保存与加载 自定义命令行参数 准备知识 Tensorflow运算AP ...

随机推荐

  1. 重磅!阿里云Promtheus 正式免费公测

    每日头条 重磅!容器集群监控利器 阿里云Promtheus 正式免费公测 Prometheus 作为容器生态下集群监控的首选方案,是一套开源的系统监控报警框架.2019 年7月3日,阿里云Promth ...

  2. GNU的__builtin_popcount函数

    用来计算32位的unsigned int中的1的个数, 其内部实现是根据查表法来计算的.

  3. 洛谷 P3951 小凯的疑惑 找规律

    目录 题面 题目链接 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例: 输出样例: 说明 思路 证明 AC代码 include<bits/stdc++.h> 题面 ...

  4. virtualenv安装 以及在PyCharm中的使用

    1.安装前条件 python3.7和 pip(可以使用这个命令升级python -m pip install --upgrade pip) 2.安装virtualenv pip install vir ...

  5. php中括号定义数组

    php5.3及之前的版本是不支持中括号定义数组的.5.4之后支持. 错误信息是,不识别“[”

  6. Codeforces 432C

    题目链接 题意: 给出一个长度为n(n<=10^5)的数组a,  数组a是数字1到n的一种排列(打乱顺序). 每次可以选择两个数(不同)进行交换, 但是交换的条件是被选择的两个数的下标之差加1应 ...

  7. MacOS利用Terminal访问远程Linux服务器

    常用命令 默认22端口访问 ssh x.x.x.x 指定端口访问 ssh x.x.x.x -p port 指定用户访问(默认是MacOS当前用户) ssh user@x.x.x.x [-p port] ...

  8. hdu 2844 混合背包【背包dp】

    http://acm.hdu.edu.cn/showproblem.php?pid=2844 题意:有n种纸币面额(a1,a2,...an),每种面额对应有(c1,c2,...cn)张.问这些钱能拼成 ...

  9. TZOJ 4471: Postman FJ (二分+bfs)

    描述 FJ now is a postman of a small town in the hills. The town can be represented by a N×N matrix. Ea ...

  10. KiCad 安装后没有元件怎么办?

    KiCad 安装后没有元件怎么办? 按以下步骤试试. 卸载 KiCad EDA. 按 Win+R 输入 %appdata%/kicad 进入 KiCad 的配置目录. 将里面的内容打包成一个 zip ...