vue借鉴了ng?(angularjs 快速上手教程1)

444 阅读6分钟

angularJS不死,只是逐渐凋零

首先这篇文章是关于angularjs的快速上手,不涉及angular。虽然看起来是一家的,
但由于ng(angularjs的简称)在2.X之后的版本进行了不向上兼容的更新,语法也改头换面,名字改为angular
在这个前端技术日新月异的年代,学习ng不是一个最好的选择,但如果你公司用到这个,那就没有选择<_>
这点在国内的百度搜索量也能感受到

那么在全球范围呢

当然vue的热度有一部分是vue这个编辑视频的软件带来的,窥豹一斑。这里热度就作为参考就好
或许你知道ng由谷歌开发,而我们的vue作者尤大大曾是谷歌的工程师,或许是这方面的联系
所以初始的vue在语法上和ng非常相似,当然vue青出于蓝,为减少陌生感,所以在这里我会对比一些ng语法和vue的相似之处,便于理解

例如

ng-app=> 指令定义一个 AngularJS 应用程序(指定根元素)。(vue用el绑定)
ng-model =>输入域的值绑定到应用程序。(vue v-model)
ng-bind =>绑定到 HTML 视图(vue v-bind)
ng-repeat  =>循环数组  (vue之前是 v-repeat 现在是v-for)
其他的诸如  .directive 自定义指令,表达式中添加过滤器等

当然,多的是不同的地方,ng是更接近于框架的东西,他自带路由,很多服务例如依赖注入,XHR、缓存、URL路由和浏览器抽象。他使用的脏值检测的思想来监听数据,vue则是数据劫持和观察订阅者模式。

废话少说,让我们开始探索ng吧

引入依赖

<script src="https://cdn.staticfile.org/angular.js/1.4.6/angular.min.js"></script>

AngularJS 是一个 JavaScript 框架,他的优点之一是通过多样的指令扩展了HTML,我们也不用再频繁的手动去操作DOM

让我们从一个简单的页面起步

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.staticfile.org/angular.js/1.4.6/angular.min.js"></script>//载入AngularJS脚本
</head>
<body>
<div ng-app="">  //ng-app代表这个代码块里面是一个ng程序
  <p>名字 : <input type="text" ng-model="name"></p>  
  //ng-model将输入值被绑定到name这个变量上
  <h1>Hello {{name}}</h1> //双大括号语法会显示ng-model里所绑定的变量
</div>
</body>
</html>

一个最简的ng程序就做好了

你可能会感觉有点奇妙,因为在原生js的做法我们需要自己弄一个事件监听器才能做到这些

ng是如何做到的呢,我们常常说ng是mvc的设计模式(react和vue相似),mvc是模型-视图-控制器设计模式, 简单来说,ng通过控制器保持数据模型和视图之间的同步,一旦模型状态发生改变,AngularJS会立即刷新反映在视图界面中,反之亦然

ng的表达式

ng使用双大括号语法**{{}}**把数据绑定到HTML上

除了我们刚刚使用{{name}}绑定一个变量
我们也可以绑定多个变量{{name + age}}

绑定运算符

<div ng-app="" ng-init="quantity=1;cost=5">
//ng-init表示数据的初始值,一般开发较少用到
<p>总价: {{ quantity * cost }}</p>  //5
</div>

也可以绑定数组,对象,

ng的指令

我们在之前的demo中已经使用了ng-model指令,使用过vue的可能直呼内行,我们来多内行几次

ng-repeat(v-for)

<div ng-app="myNg" ng-controller="myCtrl" >  
    <ul>
        <li ng-repeat="x in name "> {{x}}</li>
    </ul>
</div>
</body>
<script>
    var app = angular.module('myNg',[])
    app.controller('myCtrl',function($scope){
        $scope.name = [1,2,3]
    })
</script>

现在我们把主体代码写成这样,你大概能猜出这是一段遍历数组的代码

var app = angular.module('myNg',[]) 这行代码类似于vue的 var app = new Vue({ el: '#app',}) 他代表AngularJS 应用程序由 ng-app 定义,应用程序在 <div> 内运行,在ng中叫做模型

app.controller 则是我们的控制器,至于$scope你可以把他理解为控制器的作用域
我们都知道,如果在vue中我们想要定义一组变量,我们会这样写
var app = new Vue({
  el: '#app',
  data: {
    message: [1,2,3
    ]
  }
})
我们会在data中定义我们的变量
在ng我们则需要将我们的变量声明到我们的$scope上,当然在1.6版本之后也可以用其他的别名例如vm来代替$scope,这个在后面会讲到
这样繁杂的概念确实让新手一脸萌,为什么有模型还要有控制器,还要有$scope呢,
首先模型是用来声明我们的项目,一般是独一无二的,但是在正常开发中,我们会有很多的页面
如果不区分作用域绝对是一场灾难,所以我们可能会有很多个控制器,来表示对应页面的逻辑。
而$scope 对象来调用控制器,他本质是控制器的应用对象,你可以通过它调用控制器的方法

ng事件

这部分会讲几个vue开发者可能熟悉又陌生的三个指令 ng-click ng-show ng-hide

ng-show ng-hide这两个或许很容易理解,我们可以通过他们来很简便的实现对dom的显示隐藏
<div ng-show="false"></div> //不显示
<div ng-ng="true"></div> //不显示

那为什么点击事件也要用一个指令ng-click呢,我直接click不香吗,你说他们监听click事件? 那我使用on-click不行吗,还真的不行

<div ng-app="myApp" ng-controller="siteCtrl"> 
<p >{{name}}</p>
<button ng-click="click1()">ng-click</button>
<button class="btn " >onclick</button>

</div>
<script>
var app = angular.module('myApp', []).controller('siteCtrl', function($scope) {
    $scope.name='恭喜发财'
    $scope.click1 =  function (){
        $scope.name = '红包不给'
    }
    let btn = document.querySelector(".btn");
    btn.onclick = function () {
            $scope.name = '红包拿来';
        };
});

可以看到,通过onclick监听的方法,在这里失效了。因为ng对数据采用脏值检测的方法,你可以理解为一个大号的监听器,处于性能考虑,他限制监听的颗粒,所以这里非常想使用onclick的话,我们可以在改变数据之后,加上 scope.scope.apply(),手动触发脏值检测

过滤器filter

过滤器非常实用,ng过滤器内置了很多,当然你也可以自己来定义

    <body >
    <div ng-app="myApp" ng-controller="personCtrl">
        <p>姓名为 {{ lastName | uppercase }}</p>
        <input type="text" ng-model="lastName">
        </div>
</body>
<script>
    angular.module('myApp',[]).controller('personCtrl',function($scope){
    })
</script>

<p> {{ lastName | uppercase }}</p> 这就是过滤器的写法 (|)在ng中被称为管道字符,左边是我我们的变量,右边是我们的过滤器。在这里我用的是自带的小写转大写的过滤器

自带的还有这些

  • currency 格式化数字为货币格式。
  • lowercase 格式化字符串为小写。
  • orderBy 根据某个表达式排列数组。
  • uppercase 格式化字符串为大写。
 <p><input type="text" ng-model="test"></p>
<li ng-repeat="x in names | filter:test | orderBy:'x的某个值'">
    {{ (x.name | uppercase) + ', ' + x.country }}
  </li>
 如果这样写就代表 只显示ng-model绑定的值,并且以orderBy里的那个值排列

我们也可以写一个自己需要的

<body >
    <div ng-app="myApp" ng-controller="personCtrl">
        <p> {{ name | double }}</p>
        <input type="text" ng-model="name">
        </div>
</body>
<script>
   var app = angular.module('myApp',[]).controller('personCtrl',function($scope){
        $scope.name = ''
        
    })
    app.filter('double', function() { 
    return function(text) {
        return text+","+text;
    }
});
</script>

AngularJS 服务(Service)

服务这个名字很有迷惑性,事实上我们可以把他理解为ng为我们提供了一种方法使用一些公共类库。

传统的做法是我们会定义定义一些全局的方法,或者引入其他文件里的方法。
ng里的服务有点特殊,他内置了30多个服务,比如$setTimeout,$location,$http,他们的作用从名字也看得出来,我们在使用的时候,需要将他们注入我们的控制器
为什么有的原生方法也成了服务呢?我的理解是一方面ng对这些方法做了适合自己的增强,一方面通过使用才注入的方法,提高性能

我们这里拿$http看一下如何使用

我们先自己弄几个数据,放在data.json中
{
    "sites": [{"Name": "上海"}, {"Name": "自来水"},{"Name": "来自"},{"Name": "海上"}]
}

$http作为参数传递到 controller 中。如果是自己定义的服务使用它,需要在 controller 中定义

var app = angular.module('myApp', []);
app.controller('siteCtrl', function($scope, $http) {
  $http.get("./data.json")
  .then(function (response) {$scope.names = response.data.sites;});
});
代码非常的简单,因为这里ng帮我们封装了请求头参数,对于简单请求我们就可以这样直接调用,
但如果你是直接在自己电脑打开看效果,可能会报一个跨域的错误

我这里编译器使用的是vscode,可以下载一个

当然关于服务还分三种类型,还有自定义服务等,但是那些不是这篇文章的初衷
我这里只是简单介绍一下,如果有需求可以自己去检索

路由

如果一个单页面应用不支持路由,就像书店不卖书,那ng的路由是啥样的呢

我们在平时的网站,每次进一个网页都需要刷新获取服务端的内容,来获取新的内容
刷新会给用户带来不好的用户体验,而路由控制的页面内容只是本地内容的映射,是路径之间的切换,也就是组件的切换。不会请求服务端(数据还是要的)
我们平时访问的网页是这种格式的:http://someweb.com/home
在ng中,具体页面的内容用#!标记实现
如果是上面的网页,就是这样http://runoob.com/#!/home

详细具体实现可以查看这里 ng路由教程

写到这里,感觉似乎有点标题党的味道,其实文章的初衷是因为我在学习ng的时候,发现没有特别合适的入门教程,看到的教程,也都充满了年代感,所以才会有文初的感慨

参考文档

菜鸟教程

详解vm和$scope

ng指令的用法