框架是一个软件的半成品,在全局范围内给了大的约束。库是工具,在单点上给我们提供功能。框架是依赖库的。Vue 是框架而 jQuery 则是库。
在传统的非模块化 JavaScript 开发中有许多问题:命名冲突、文件依赖、跨环境共享模块、性能优化、职责单一、模块的版本管理、jQuery 等前端库层出不穷,前端代码日益膨胀
AMD 规范及其代表:RequireJS
异步模块定义(Asynchronous Module Definition),它是依赖前置 (因为依赖必须一开始就写好)会先尽早地执行 (依赖) 模块 , 相当于所有的 require 都被提前了
CMD 规范及其代表:SeaJS
(Common Module Definition)模块定义规范
一个模块就是一个文件;它推崇依赖就近想什么时候 require 就什么时候加载,实现了 懒加载, 延迟执行 (as lazy as possible)
MVC 的核心理念是:你应该把管理数据的代码(Model)、业务逻辑的代码(Controller)、以及向用户展示数据的代码(View)清晰的分离开
通过 MVC 框架又衍生出了许多其它的架构,统称 MV*,最常见的是 MVP 与 MVVM
MVVM(Model-View-ViewModel)框架的由来便是 MVP(Model-View-Presenter)模式与 WPF 结合的应用方式时发展演变过来的一种新型架构框架。
Vue 与 Angular 就是一个 MVVM 框架,MVVM 与 MVC 最大的区别是模型与视图实现了双向绑定。
React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西很好用,就在 2013 年 5 月开源了。由于 React 的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以,越来越多的人开始关注和使用,认为它可能是将来 Web 开发的主流工具。支持虚拟 DOM(Virtual DOM)和组件化的开发。
ReactJS 官网地址:
http://facebook.github.io/react/
Github 地址:
https://github.com/facebook/react
AngularJS 是一个前端 MVVM 框架。
angular 的英文字面意思是:有角的; 用角测量的
AngularJS 是协助搭建单页面工程(SPA)的开源前端框架。它通过 MVC 模式使得开发与测试变得更容易。
AngularJS 试图成为 WEB 应用中的一种端对端的解决方案。它将指导开发整个应用。
AngularJS 于 2009 年发布第一个版本,由 Google 进行维护,压缩版 94k。
1.3 版后不再支持 IE8
1.3 版后不支持全局控制器
2.0 版 alpha
git 仓库: https://github.com/angular/
官网: https://www.angularjs.org/
http://www.angularjs.cn / 中文社区
http://www.apjs.net/ 中文网
a web framework for modern web apps
Vue.js 是一个轻巧、高性能、可组件化的 MVVM 库,同时拥有非常容易上手的 API,作者是尤雨溪是中国人。
易用
已经会了 HTML,CSS,JavaScript?即刻阅读指南开始构建应用!
灵活
简单小巧的核心,渐进式技术栈,足以应付任何规模的应用。
性能
17kb min+gzip 运行大小、超快虚拟 DOM 、最省心的优化
当前三大前端 MVC 框架的对比:
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与 现代化的工具链 以及各种 支持类库 结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
如果你已经是有经验的前端开发者,想知道 Vue 与其它库 / 框架有哪些区别,请查看 对比其它框架 。
不适合 SEO、交互频繁的,如游戏之类交互体验网站
浏览器支持:
Vue.js 不支持 IE8 及其以下版本,因为 Vue.js 使用了 IE8 不能模拟的 ECMAScript 5 特性。Vue.js 支持所有 兼容 ECMAScript 5 的浏览器 。
文章中的许多内容都是来自 vue 官网,因为没有其它更加合适的教程。
如果要开发基于 angularJS 的项目,则先要添加对 angularJS 的引用,有如下几个方法:
1)、去 vue2 官网或 git 下载,地址: https://github.com/vuejs/vue
2)、使用 cdn
3)、安装 node.js,使用 npm 获取
具体的安装细节: https://cn.vuejs.org/v2/guide/installation.html
在本文的示例中已经包含了运行环境与帮助文件 chm
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:
示例:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>
- vue2介绍
- </title>
- </head>
- <body>
- <div id="app1">
- {{message}}
- </div>
- <div id="app2">
- <span v-bind:title="message">
- 把鼠标放到这里试试
- </span>
- </div>
- <script src="../js/vue.js" type="text/javascript" charset="utf-8">
- </script>
- <script type="text/javascript">
- //vue应用对象
- var app1 = new Vue({
- el: "#app1",
- data: {
- message: "Hello Vue2!"
- }
- });
- //绑定属性
- var app2 = new Vue({
- el: "#app2",
- data: {
- message: "页面加载时间是:" + new Date().toLocaleDateString()
- }
- });
- </script>
- </body>
- </html>
结果:
这里我们遇到了一点新东西。你看到的 v-bind 特性被称为指令。指令带有前缀 v-,以表示它们是 Vue 提供的特殊特性。可能你已经猜到了,它们会在渲染的 DOM 上应用特殊的响应式行为。在这里,该指令的意思是:"将这个元素节点的 title 特性和 Vue 实例的 message 属性保持一致"。
如果你再次打开浏览器的 JavaScript 控制台,输入
,就会再一次看到这个绑定了 title 特性的 HTML 已经进行了更新。
- app2.message = '新消息'
我们已经成功创建了第一个 Vue 应用!看起来这跟渲染一个字符串模板非常类似,但是 Vue 在背后做了大量工作。现在数据和 DOM 已经被建立了关联,所有东西都是响应式的。我们要怎么确认呢?打开你的浏览器的 JavaScript 控制台 (就在这个页面打开),并修改 app.message 的值,你将看到上例相应地更新。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>vue2介绍</title>
- </head>
- <body>
- <div id="app3">
- <span v-if="isShow">
- isShow为true时你可以看到我
- </span>
- </div>
- <div id="app4">
- <span v-if="isShow">
- <table border="1" cellspacing="1" cellpadding="1" width="50%">
- <tr><th>序号</th><th>名称</th><th>价格</th></tr>
- <tr v-for="(obj,index) in fruits">
- <td>{{index+1}}</td>
- <td>{{obj.name}}</td>
- <td>{{obj.price}}</td>
- </tr>
- </table>
- </span>
- </div>
- <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
- <script type="text/javascript">
- //if指令
- var app3 = new Vue({
- el: "#app3",
- data: {
- isShow: true
- }
- });
- //循环指令
- var app4 = new Vue({
- el: "#app4",
- data: {
- isShow:true,
- fruits: [{
- name: "苹果",
- price: "6.8"
- }, {
- name: "橙子",
- price: "3.5"
- }, {
- name: "香蕉",
- price: "2.3"
- }]
- }
- });
- </script>
- </body>
- </html>
结果:
这个例子演示了我们不仅可以把数据绑定到 DOM 文本或特性,还可以绑定到 DOM 结构。此外,Vue 也提供一个强大的过渡效果系统,可以在 Vue 插入 / 更新 / 移除元素时自动应用 过渡效果 。
为了让用户和你的应用进行交互,我们可以用 v-on 指令添加一个事件监听器,通过它调用在 Vue 实例中定义的方法:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>vue2介绍</title>
- </head>
- <body>
- <div id="app5">
- <button v-on:click="showMe">{{message}}</button>
- <input v-model="message" />
- </div>
- <p id="app6">
- <button v-on:click="n1+=1">+</button><input v-model="n1"/>+ <input v-model="n2"/>= <input v-model="sum"/>
- </p>
- <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
- <script type="text/javascript">
- //事件
- var app5 = new Vue({
- el: "#app5",
- data: {
- message:"vue2事件"
- },
- methods:{
- showMe:function(){
- this.message=this.message.split('').reverse().join('');
- }
- }
- });
- //计算
- var app6 = new Vue({
- el: "#app6",
- data: {
- n1:0,
- n2:0
- },
- computed:{
- sum:function(){
- return parseInt(this.n1)+parseInt(this.n2);
- }
- }
- });
- </script>
- </body>
- </html>
结果:
注意在 showMe 方法中,我们更新了应用的状态,但没有触碰 DOM——所有的 DOM 操作都由 Vue 来处理,你编写的代码只需要关注逻辑层面即可。
Vue 还提供了 v-model 指令,它能轻松实现表单输入和应用状态之间的双向绑定。
组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。仔细想想,几乎任意类型的应用界面都可以抽象为一个组件树:
在 Vue 里,一个组件本质上是一个拥有预定义选项的一个 Vue 实例。在 Vue 中注册组件很简单:
- // 定义名为 todo-item 的新组件
- Vue.component('todo-item', {
- template: '<li>这是个待办项</li>'
- })
现在你可以用它构建另一个组件模板:
- <ol>
- <!-- 创建一个 todo-item 组件的实例 -->
- <todo-item></todo-item>
- </ol>
示例:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>
- vue2介绍
- </title>
- </head>
- <body>
- <div id="app1">
- <ol>
- <todo-item>
- </todo-item>
- </ol>
- <ol>
- <todo-item v-for="item in items">
- </todo-item>
- </ol>
- </div>
- <script src="../js/vue.js" type="text/javascript" charset="utf-8">
- </script>
- <script type="text/javascript">
- //在vue中添加一个名为todo-item组件
- Vue.component("todo-item", {
- template: "<li>这是一个li单项</li>"
- });
- //构件
- var app1 = new Vue({
- el: "#app1",
- data: {
- items: [1, 3, 5, 7, 9]
- }
- });
- </script>
- </body>
- </html>
结果:
但是这样会为每个待办项渲染同样的文本,这看起来并不炫酷。我们应该能从父作用域将数据传到子组件才对。让我们来修改一下组件的定义,使之能够接受一个 prop :
- Vue.component('todo-item', {
- // todo-item 组件现在接受一个
- // "prop",类似于一个自定义特性。
- // 这个 prop 名为 todo。
- props: ['todo'],
- template: '<li>{{ todo.text }}</li>'
- })
现在,我们可以使用 v-bind 指令将待办项传到循环输出的每个组件中:
- <div id="app-7">
- <ol>
- <!--
- 现在我们为每个 todo-item 提供 todo 对象
- todo 对象是变量,即其内容可以是动态的。
- 我们也需要为每个组件提供一个"key",稍后再
- 作详细解释。
- -->
- <todo-item
- v-for="item in groceryList"
- v-bind:todo="item"
- v-bind:key="item.id">
- </todo-item>
- </ol>
- </div>
js:
- Vue.component('todo-item', {
- props: ['todo'],
- template: '<li>{{ todo.text }}</li>'
- })
- var app7 = new Vue({
- el: '#app-7',
- data: {
- groceryList: [
- { id: 0, text: '蔬菜' },
- { id: 1, text: '奶酪' },
- { id: 2, text: '随便其它什么人吃的东西' }
- ]
- }
- })
结果:
- .蔬菜
- .奶酪
- .随便其它什么人吃的东西
示例:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>vue2介绍</title>
- </head>
- <body>
- <div id="app1">
- <ol>
- <todo-item info="Hello Component"></todo-item>
- </ol>
- <ol>
- <student-item v-for="item in students" v-bind:stu="item" v-bind:key="item.name"></student-item>
- </ol>
- </div>
- <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
- <script type="text/javascript">
- //在vue中添加一个名为todo-item组件
- Vue.component("todo-item",{
- props:["info","vtitle"],
- template:"<li>{{info||'empty'}}</li>"
- });
- Vue.component("student-item",{
- props:["stu"],
- template:"<li>{{stu.name}} - {{stu.age}}</li>"
- });
- //构件
- var app1 = new Vue({
- el: "#app1",
- data:{
- students:[
- {"name":"tom","age":18},{"name":"rose","age":80},{"name":"lucy","age":8}
- ]
- }
- });
- </script>
- </body>
- </html>
结果:
尽管这只是一个刻意设计的例子,但是我们已经设法将应用分割成了两个更小的单元。子单元通过 prop 接口与父单元进行了良好的解耦。我们现在可以进一步改进 <todo-item> 组件,提供更为复杂的模板和逻辑,而不会影响到父单元。
在一个大型应用中,有必要将整个应用程序划分为组件,以使开发更易管理。
你可能已经注意到 Vue 组件非常类似于自定义元素——它是 Web 组件规范 的一部分,这是因为 Vue 的组件语法部分参考了该规范。例如 Vue 组件实现了 Slot API 与 is 特性。但是,还是有几个关键差别:
通过一个综合示例来快速了解 Vue2,会使用到模板、过滤器、计算,表达式、组件等等,要求实现一个简单的购物车,运行时的效果如下:
参考代码:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>购物车</title>
- <style type="text/css">
- .bg{
- background:dodgerblue;
- color:white;
- }
- </style>
- </head>
- <body>
- <div id="app1">
- <h2>购物车</h2>
- <table border="1" cellspacing="0" cellpadding="0" width="100%">
- <tr>
- <th>序号</th>
- <th>名称</th>
- <th>单价</th>
- <th>数量</th>
- <th>小计</th>
- <th>操作</th>
- </tr>
- <tr v-for="(pdt,index) in products" v-bind:class="{bg:index%2==0}">
- <td>{{index+1}}</td>
- <td>{{pdt.title}}</td>
- <td>{{pdt.price}}</td>
- <td>
- <button type="button" v-on:click="pdt.quantity<=0?0:(pdt.quantity-=1)">-</button>
- <input v-model="pdt.quantity" style="width: 80px;" v-on:keyup="pdt.quantity=(pdt.quantity<0?0:pdt.quantity)" />
- <button type="button" v-on:click="pdt.quantity+=1">+</button>
- </td>
- <td>{{pdt.quantity*pdt.price | currency(1)}}</td>
- <td>
- <button type="button" v-on:click="remove(index)">移除</button>
- </td>
- </tr>
- <tr>
- <td colspan="6" align="right">
- {{total|currency}}
- </td>
- </tr>
- </table>
- </div>
- <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
- <script type="text/javascript">
- Vue.filter("currency", function(v, n) {
- if(!v) {
- return "";
- }
- return "¥" + v.toFixed(n || 2);
- });
- //实例
- var app1 = new Vue({
- el: "#app1",
- data: {
- orderby:"",
- isAsc:true,
- products: [{
- title: "paint pot",
- quantity: 9,
- price: 3.95
- }, {
- title: "polka dots",
- quantity: 17,
- price: 12.3
- }, {
- title: "pebbles",
- quantity: 5,
- price: 6.71
- }, {
- title: "Mi Note5",
- quantity: 8,
- price: 2985.6
- }, {
- title: "iPhone XS",
- quantity: 10,
- price: 8906.72
- }]
- },
- computed: {
- total: function() {
- var sum = 0;
- for(var i = 0; i < this.products.length; i++) {
- sum += (this.products[i].price * this.products[i].quantity);
- }
- return sum;
- }
- },
- methods:{
- remove:function(i){
- if(confirm('您确定要移除吗?')){
- this.products.splice(i,1);
- }
- }
- }
- });
- </script>
- </body>
- </html>
思考:如果这里还要实现排序应该怎样做?
因为上面的示例中需要用到对象数组与排序,这里单独讲讲:
var arrayObj = new Array();
var arrayObj = new Array([size]);
var arrayObj = new Array([element0[, element1[, ...[, elementN]]]]);
示例:
- var array11 = new Array(); //空数组
- var array12 = new Array(5); //指定长度,可越界
- var array13 = new Array("a","b","c",1,2,3,true,false); //定义并赋值
- var array14=[]; //空数组,语法糖
- var array15=[1,2,3,"x","y"]; //定义并赋值
var testGetArrValue=arrayObj[1];
arrayObj[1]= "值";
- //4.2、访问与修改
- array12[8] = "hello array12"; //赋值或修改
- console.log(array12[8]); //取值
- //遍历
- for (var i = 0; i < array13.length; i++) {
- console.log("arrayl3[" + i + "]=" + array13[i]);
- }
- //枚举
- for (var i in array15) {
- console.log(i + "=" + array15[i]); //此处的i是下标
- }
结果:
将一个或多个新元素添加到数组未尾,并返回数组新长度
arrayObj. push([item1 [item2 [. . . [itemN]]]]);
将一个或多个新元素添加到数组开始,数组中的元素自动后移,返回数组新长度
arrayObj.unshift([item1 [item2 [. . . [itemN]]]]);
将一个或多个新元素插入到数组的指定位置,插入位置的元素自动后移,返回被删除元素数组,deleteCount 要删除的元素个数
arrayObj.splice(insertPos,deleteCount,[item1[, item2[, . . . [,itemN]]]])
示例代码:
- //4.3、添加元素
- var array31 = [5, 8];
- //添加到末尾
- array31.push(9);
- var len = array31.push(10, 11);
- console.log("长度为:" + len + "——" + array31);
- //添加到开始
- array31.unshift(4);
- var len = array31.unshift(1, 2, 3);
- console.log("长度为:" + len + "——" + array31);
- //添加到中间
- var len = array31.splice(5, 1, 6, 7); //从第5位开始插入,删除第5位后的1个元素,返回被删除元素
- console.log("被删除:" + len + "——" + array31);
运行结果:
移除最后一个元素并返回该元素值
arrayObj.pop();
移除最前一个元素并返回该元素值,数组中元素自动前移
arrayObj.shift();
删除从指定位置 deletePos 开始的指定数量 deleteCount 的元素,数组形式返回所移除的元素
arrayObj.splice(deletePos,deleteCount);
示例:
结果:
- //4.4、删除
- var array41 = [1, 2, 3, 4, 5, 6, 7, 8];
- console.log("array41:" + array41);
- //删除最后一个元素,并返回
- var e = array41.pop();
- console.log("被删除:" + e + "——" + array41);
- //删除首部元素,并返回
- var e = array41.shift();
- console.log("被删除:" + e + "——" + array41);
- //删除指定位置与个数
- var e = array41.splice(1, 4); //从索引1开始删除4个
- console.log("被删除:" + e + "——" + array41);
以数组的形式返回数组的一部分,注意不包括 end 对应的元素,如果省略 end 将复制 start 之后的所有元素
arrayObj.slice(start, [end]);
将多个数组(也可以是字符串,或者是数组和字符串的混合)连接为一个数组,返回连接好的新的数组
arrayObj.concat([item1[, item2[, . . . [,itemN]]]]);
示例:
- //4.5、截取和合并
- var array51 = [1, 2, 3, 4, 5, 6];
- var array52 = [7, 8, 9, 0, "a", "b", "c"];
- //截取,切片
- var array53 = array51.slice(2); //从第3个元素开始截取到最后
- console.log("被截取:" + array53 + "——" + array51);
- var array54 = array51.slice(1, 4); //从第3个元素开始截取到索引号为3的元素
- console.log("被截取:" + array54 + "——" + array51);
- //合并
- var array55 = array51.concat(array52, ["d", "e"], "f", "g");
- console.log("合并后:" + array55);
结果:
返回数组的拷贝数组,注意是一个新的数组,不是指向
arrayObj.slice(0);
返回数组的拷贝数组,注意是一个新的数组,不是指向
arrayObj.concat();
因为数组是引用数据类型,直接赋值并没有达到真正实现拷贝,地址引用,我们需要的是深拷贝。
反转元素(最前的排到最后、最后的排到最前),返回数组地址
arrayObj.reverse();
对数组元素排序,返回数组地址
arrayObj.sort();
arrayObj.sort(function(obj1,obj2){});
示例:
结果:
- var array71=[4,5,6,1,2,3];
- array71.sort();
- console.log("排序后:"+array71);
- var array72=[{name:"tom",age:19},{name:"jack",age:20},{name:"lucy",age:18}];
- array72.sort(function(user1,user2){
- return user1.age<user2.age;
- });
- console.log("排序后:");
- for(var i in array72) console.log(array72[i].name+","+array72[i].age);
返回字符串,这个字符串将数组的每一个元素值连接在一起,中间用 separator 隔开。
arrayObj.join(separator);
示例代码:
- //4.8、合并成字符与将字符拆分成数组
- var array81 = [1, 3, 5, 7, 9];
- var ids = array81.join(",");
- console.log(ids);
- //拆分成数组
- var text = "hello nodejs and angular";
- var array82 = text.split(" ");
- console.log(array82);
运行结果:
所有代码:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>数组操作</title>
- </head>
- <body>
- <script type="text/javascript">
- //4.1、创建
- var array11 = new Array(); //空数组
- var array12 = new Array(5); //指定长度,可越界
- var array13 = new Array("a","b","c",1,2,3,true,false); //定义并赋值
- var array14=[]; //空数组,语法糖
- var array15=[1,2,3,"x","y"]; //定义并赋值
- //4.2、访问与修改
- array12[8]="hello array12"; //赋值或修改
- console.log(array12[8]); //取值
- //遍历
- for (var i = 0; i < array13.length; i++) {
- //console.log("arrayl3["+i+"]="+array13[i]);
- }
- //枚举
- for(var i in array15){
- //console.log(i+"="+array15[i]); //此处的i是下标
- }
- //4.3、添加元素
- var array31=[5,8];
- //添加到末尾
- array31.push(9);
- var len=array31.push(10,11);
- console.log("长度为:"+len+"——"+array31);
- //添加到开始
- array31.unshift(4);
- var len=array31.unshift(1,2,3);
- console.log("长度为:"+len+"——"+array31);
- //添加到中间
- var len=array31.splice(5,1,6,7); //从第5位开始插入,删除第5位后的1个元素,返回被删除元素
- console.log("被删除:"+len+"——"+array31);
- //4.4、删除
- var array41=[1,2,3,4,5,6,7,8];
- console.log("array41:"+array41);
- //删除最后一个元素,并返回
- var e=array41.pop();
- console.log("被删除:"+e+"——"+array41);
- //删除首部元素,并返回
- var e=array41.shift();
- console.log("被删除:"+e+"——"+array41);
- //删除指定位置与个数
- var e=array41.splice(1,4); //从索引1开始删除4个
- console.log("被删除:"+e+"——"+array41);
- //4.5、截取和合并
- var array51=[1,2,3,4,5,6];
- var array52=[7,8,9,0,"a","b","c"];
- //截取,切片
- var array53=array51.slice(2); //从第3个元素开始截取到最后
- console.log("被截取:"+array53+"——"+array51);
- var array54=array51.slice(1,4); //从第3个元素开始截取到索引号为3的元素
- console.log("被截取:"+array54+"——"+array51);
- //合并
- var array55=array51.concat(array52,["d","e"],"f","g");
- console.log("合并后:"+array55);
- //4.7、排序
- var array71=[4,5,6,1,2,3];
- array71.sort();
- console.log("排序后:"+array71);
- var array72=[{name:"tom",age:19},{name:"jack",age:20},{name:"lucy",age:18}];
- array72.sort(function(user1,user2){
- return user1.age<user2.age;
- });
- console.log("排序后:");
- for(var i in array72) console.log(array72[i].name+","+array72[i].age);
- //4.8、合并成字符与将字符拆分成数组
- var array81=[1,3,5,7,9];
- var ids=array81.join(",");
- console.log(ids);
- //拆分成数组
- var text="hello nodejs and angular";
- var array82=text.split(" ");
- console.log(array82);
- </script>
- </body>
- </html>
javascript 内置的 sort 函数是多种排序算法的集合,数组在原数组上进行排序,不生成副本。
JavaScript 实现多维数组、对象数组排序,其实用的就是原生的 sort() 方法,用于对数组的元素进行排序。
sort() 方法用于对数组的元素进行排序。语法如下:
- ArrayObject.sort(order);
返回值为对数组的引用
如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。
示例:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>排序</title>
- </head>
- <body>
- <script>
- var numbers=[2,4,6,8,0,1,2,3,7,9];
- numbers.sort();
- console.log(numbers.join(',')); //默认按升序排列
- numbers.reverse(); //反转
- console.log(numbers.join(',')); //将元素用逗号连接成一个字符串
- </script>
- </body>
- </html>
结果:
如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:
- /*
- 默认升序:
- a>b 返回1
- a=b 返回0
- a<b 返回-1
- */
解释:a>b 升序,a<b 降序。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>排序</title>
- </head>
- <body>
- <script>
- var numbers=[2,4,6,8,0,1,2,3,7,9];
- //当a>b的结果为正数时则为升序
- numbers.sort(function(a,b){
- if(a>b){return 1;}
- if(a<b){return -1;}
- return 0;
- });
- console.log(numbers.join(','));
- //简化,注意类型
- numbers.sort(function(a,b){
- return a-b;
- });
- console.log(numbers.join(','));
- //降序
- numbers.sort(function(a,b){
- return b-a;
- });
- console.log(numbers.join(','));
- </script>
- </body>
- </html>
结果:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>排序</title>
- </head>
- <body>
- <script>
- //对象数组
- var pdts = [{
- title: "z-paint pot",
- quantity: 9,
- price: 3.95
- },{
- title: "iPhone XS",
- quantity: 10,
- price: 8906.72
- },{
- title: "polka dots",
- quantity: 17,
- price: 12.3
- }, {
- title: "pebbles",
- quantity: 5,
- price: 6.71
- }, {
- title: "Mi Note5",
- quantity: 8,
- price: 2985.6
- }];
- //按价格升序
- pdts.sort(function(x,y){
- return x.price-y.price;
- });
- document.write(JSON.stringify(pdts));
- document.write("<br/>");
- //按名称排序
- pdts.sort(function(x,y){
- if(x.title>y.title) return 1;
- if(x.title<y.title) return -1;
- return 0;
- });
- document.write(JSON.stringify(pdts));
- </script>
- </body>
- </html>
结果:
如果排序的条件要不断变化,将反复写简单的排序函数,封装可以带来方便:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>
- 排序
- </title>
- </head>
- <body>
- <script>
- //对象数组
- var pdts = [{
- title: "z-paint pot",
- quantity: 9,
- price: 3.95
- },
- {
- title: "iPhone XS",
- quantity: 10,
- price: 8906.72
- },
- {
- title: "polka dots",
- quantity: 17,
- price: 12.3
- },
- {
- title: "pebbles",
- quantity: 5,
- price: 6.71
- },
- {
- title: "Mi Note5",
- quantity: 8,
- price: 2985.6
- }];
- //根据排序关键字与是否为升序产生排序方法
- var sortExp = function(key, isAsc) {
- return function(x, y) {
- if (isNaN(x[key])) { //如果当前排序的不是数字
- if (x[key] > y[key]) return 1 * (isAsc ? 1 : -1);
- if (x[key] < y[key]) return - 1 * (isAsc ? 1 : -1);
- return 0;
- } else {
- return (x[key] - y[key]) * (isAsc ? 1 : -1);
- }
- }
- };
- //按价格升序
- pdts.sort(sortExp("price", true));
- document.write(JSON.stringify(pdts));
- document.write("<br/>------------------------------<br/>");
- pdts.sort(sortExp("price", false));
- document.write(JSON.stringify(pdts));
- document.write("<br/>------------------------------<br/>");
- pdts.sort(sortExp("title", true));
- document.write(JSON.stringify(pdts));
- document.write("<br/>------------------------------<br/>");
- pdts.sort(sortExp("title", false));
- document.write(JSON.stringify(pdts));
- </script>
- </body>
- </html>
结果:
当使用 Vue 时,我们推荐同时在你的浏览器上安装 Vue Devtools,它允许你在一个更加友善的界面中审查和调试你的 Vue 应用。
Vue Devtools 是一个内嵌在 Google Chrome 浏览器中的插件,用于更好的调试 Vue 应用程序
源码: https://github.com/vuejs/vue-devtools#vue-devtools
下载: https://files.cnblogs.com/files/best/vuetools_316.zip
安装方法:
下载后解压,在 chrome 地址栏中输入:chrome://extensions/
直接将 crx 文件插入浏览器,确认就安装成功了。
插件会自动检测当前是否使用了 vue,如果使用了图标会亮起,在开发者工具中有一个调试界面:
a)、请实现一个购物车
https://git.coding.net/zhangguo5/vue2.git
来源: https://www.cnblogs.com/best/p/8109600.html