vue基础2

### Vue.js 基础部分

## 一、 Vue.js 简介

### 1. Vue.js 是什么

**Vue.js**也称为 Vue,读音/vju:/,类似 view,错误读音 v-u-e
版本: v2.0

- 是一个构建用户界面的框架
- 是一个轻量级 MVVM(Model-View-ViewModel)框架,和 angular、react 类似,其实就是所谓的数据双向绑定
- 数据驱动+组件化的前端开发(核心思想)
- 通过简单的 API 实现**响应式的数据绑定**和**组合的视图组件**
- 更容易上手、小巧

参考:[官网](https://cn.vuejs.org/)
#### MVVM框架

1.1定义:
Mvvm定义MVVM是Model-View-ViewModel的简写。即模型-视图-视图模型。
【模型】指的是后端传递的数据。
【视图】指的是所看到的页面。
【视图模型】mvvm模式的核心,它是连接view和model的桥梁。
它有两个方向:
一是将【模型】转化成【视图】,即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。
二是将【视图】转化成【模型】,即将所看到的页面转化成后端的数据。

实现的方式是:DOM 事件监听。这两个方向都实现的,我们称之为数据的双向绑定。

Vue就是基于MVVM模式实现的一套框架,
在vue中:
Model:指的是js中的数据,如对象,数组等等。
View:指的是页面视图
viewModel:指的是vue实例化对象

1.2总结:
在MVVM的框架下视图和模型是不能直接通信的。它们通过ViewModel来通信,ViewModel通常要实现一个observer观察者,当数据发生变化,ViewModel能够监听到数据的这种变化,然后通知到对应的视图做自动更新,而当用户操作视图,ViewModel也能监听到视图的变化,然后通知数据做改动,这实际上就实现了数据的双向绑定。

并且MVVM中的View 和 ViewModel可以互相通信。MVVM流程图如下:



### 2.vue 和 angular 的区别

#### 2.1 angular

- 上手较难
- 指令以 ng-xxx 开头
- 所有属性和方法都存储在\$scope 中
- 由 google 维护

#### 2.2 vue

- 简单、易学、更轻量
- 指令以 v-xxx 开头
- HTML 代码+JSON 数据,再创建一个 vue 实例
- 由个人维护:**尤雨溪**,华人,目前就职于阿里巴巴,2014.2 开源了 vue.js 库

![尤雨溪](https://gss1.bdstatic.com/9vo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=d49c7e60ee1190ef15f69a8daf72f673/4afbfbedab64034f29596c8ba6c379310b551da2.jpg)

共同点:`都不兼容低版本IE`,`对 seo 搜索引擎不友好`
对比:GitHub 上 vue(156k) 的 stars 数量大约是 angular(59.6k) 的两倍多

## 二、起步

### 1. 下载核心库 vue.js

    npm init --yes
    npm install vue --save
    版本 v2.6.11 目前最新版本(2020.2.2)

    vue2.0和1.0相比,最大的变化就是引入了Virtual DOM(虚拟DOM),页面更新效率更高,速度更快

### 2. Hello World(对比 angular)

#### 2.1 angular 实现

    js:
        let app=angular.module('myApp',[]);
        app.controller('MyController',['$scope',function($scope){
            $scope.msg='Hello World';
        }]);
    html:
        <html ng-app="myApp">
            <div ng-controller="MyController">
                {{msg}}
            </div>
        </html>

#### 2.2 vue 实现

    js:
        new Vue({
            el:'#itapp', //指定关联的选择器,进行挂载
            data:{ //存储数据
                msg:'Hello World',
                name:'tom'
            }
        });
    html:
        <div id="itapp">
            {{msg}}
        </div>

### 3. 安装 vue-devtools 插件,便于在 chrome 中调试 vue

    直接将vue-devtools解压缩,然后将文件夹中的chrome拖放到扩展程序中(更多工具--扩展程序 )
    或者直接在浏览器中输入 chrome://extensions/打开

    //配置是否允许vue-devtools检查代码,方便调试,生产环境中需要设置为false
     Vue.config.devtools=false;
     Vue.config.productionTip=false; //阻止vue启动时生成生产消息

## 三、 常用指令

### 1. 什么是指令?

    用来扩展html标签的功能
    angular中常用的指令:
        ng-model
        ng-repeat
        ng-click
        ng-show/ng-hide
        ng-if

### 2. vue 中常用的指令

    v-model
    v-for
    v-on
    v-show / v-if / v-if v-else
    v-bind
    v-pre
    v-cloak
    v-once

- v-model
  双向数据绑定,一般用于表单元素

  代码演示:02.html

```javascript
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>常用指令:v-model</title>
    <script src="js/vue.js"></script>
    <script>
        window.onload=function(){
            new Vue({
                // el:'.itany',
                el:'div', //vue2.0中不允许将vue实例挂载到<html>或<body>元素,在vue1.0中是可以的
                data:{
                    name:'', //即使没有值,也不能省略,报错
                    age:21,
                    flag:true,
                    nums:[12,4,23,5],
                    user:{id:9527,name:'唐伯虎'}
                }
            });
        }
    </script>
</head>
<body>
    <!-- <div id="itany"> -->
    <!-- <div class="itany"> -->
    <div>
        用户名:<input type="text" v-model="name">
        <br>
        {{name}} <br>
        {{age}} <br>
        {{flag}} <br>
        {{nums}} <br>
        {{user}}
    </div>
</body>
</html>
```

- v-for
  对数组或对象进行循环操作,使用的是 v-for,不是 v-repeat
  注:在 vue1.0 中提供了隐式变量,如$index、$key
  在 vue2.0 中去除了隐式变量,已被废除

代码演示 代码演示:03.html
```javascript
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>常用指令:v-for</title>
    <script src="js/vue.js"></script>
    <script>
        window.onload=function(){
            new Vue({
                el:'#itany',
                data:{
                    arr:[12,4,5,34,2,11],
                    user:{id:9527,name:'唐伯虎',age:25},
                    arr2:[12,4,5,34,2,11,12],
                    users:[
                        {id:9527,name:'唐伯虎',age:25},
                        {id:1001,name:'秋香',age:22},
                        {id:1002,name:'石榴姐',age:24}
                    ]
                }
            });
        }
    </script>
</head>
<body>
    <div id="itany">
        <!-- {{arr}} -->

        <ul>
            <!-- 普通循环 -->
            <!-- <li v-for="value in arr">{{value}}</li> -->
            <!-- <li v-for="value in user">{{value}}</li> -->

            <!-- 键值循环 -->
            <!-- <li v-for="(v,k) in arr">{{k}}={{v}}</li> -->
            <!-- <li v-for="(v,k) in user">{{k}}={{v}}</li> -->

            <!-- 可以直接循环包含重复数据的集合,可以通过指定:key属性绑定唯一key,当更新元素时可重用元素,提高效率,类似于vue1.0中track-by -->
            <!-- <li v-for="(v,k) in arr2" :key="k">{{v}}</li> -->

            <li v-for="(user,index) in users">
                {{index+1}},{{user.id}},{{user.name}},{{user.age}}
            </li>
        </ul>
    </div>
</body>
</html>
```
- v-on
  用来绑定事件,用法:v-on:事件="函数"

代码演示:04.html

```javascript
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>常用指令:v-on</title>
    <!-- 事件简写和事件对象$event -->
    <script src="js/vue.js"></script>
    <script>
        window.onload=function(){
            let vm=new Vue({
                el:'#itany',
                data:{  //存储数据
                    arr:[12,34,45,23,5]
                },
                methods:{ //存储方法
                    show:function(){
                        console.log('show方法');
                    },
                    add(){
                        // console.log(this); //this表示当前vue实例
                        // console.log(this===vm); //true
                        this.arr.push(666); //使用this访问当前实例中的成员
                        // this.show();
                    },
                    print(e){
                        // console.log(e);
                        console.log(e.target.innerHTML); //DOM对象
                        console.log(this);
                    }
                }
            });
        }
    </script>
</head>
<body>
    <div id="itany">
        <!-- <button onclick="show()">点我</button> -->
        <button v-on:click="show">点我</button>
        <button v-on:click="add()">向数组中添加一个元素</button>
        <br>
        {{arr}}
        <hr>
        <button @click="print($event)">Click Me</button>

        <button v-on:mouseover="show">鼠标经过</button>
        <button v-on:dblclick="show">鼠标双击</button>
    </div>
</body>
</html>
```

- v-show/v-if  
  用来显示或隐藏元素,v-show 是通过 display 实现,v-if 是每次删除后再重新创建,与 angular 中类似

代码演示:05.html

```javascript
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>常用指令:v-show</title>
    <script src="js/vue.js"></script>
    <script>
        window.onload=function(){
            let vm=new Vue({
                el:'#itany',
                data:{ 
                    flag:true
                },
                methods:{ 
                    change(){
                        this.flag=!this.flag;
                    }
                }
            });
        }
    </script>
</head>
<body>
    <div id="itany">
        <!-- <button v-on:click="change">隐藏</button> -->
        <button v-on:click="flag=!flag">隐藏</button>

        <hr>
        <div style="width: 100px;height: 100px; red" v-if="flag">欢迎来到武汉软谋</div>
    </div>
</body>
</html>
```
## 四、 练习:用户管理

    使用BootStrap+Vue.js

    js部分

    window.onload=function(){
            let vm=new Vue({
                el:'.container',
                data:{ 
                    users:[
                        {name:'tom',age:24,email:'[email protected]'},
                        {name:'jack',age:23,email:'[email protected]'}
                    ],
                    user:{},
                    nowIndex:-1 //当前要删除项的索引
                },
                methods:{ 
                    addUser(){
                        this.users.push(this.user);
                        this.user={};
                    },
                    deleteUser(){
                        if(this.nowIndex===-1){ //删除所有
                            this.users=[];
                        }else{
                            this.users.splice(this.nowIndex,1); //从指定索引位置开始删除,删除一个
                        }
                    }
                }
            });
        }

## 五、 事件和属性

### 1. 事件

#### 1.1 事件简写

    v-on:click=""
    简写方式 @click=""


#### 1.2 事件对象\$event

    包含事件相关信息,如事件源、事件类型、偏移量
    target、type、offsetx

代码演示:07.html
```javascript
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件简写和事件对象$event</title>
    <script src="js/vue.js"></script>
    <script>
        window.onload=function(){
            let vm=new Vue({
                el:'#itany',
                methods:{ 
                    show(){
                        console.log(111);
                    },
                    print(e){
                        // console.log(e);
                        console.log(e.target.innerHTML); //DOM对象
                        console.log(this);
                    }
                }
            });
        }
    </script>
</head>
<body>
    <div id="itany">
        <button v-on:click="show">点我</button>
        <button @click="show">点我</button>
        <hr>

        <button @click="print($event)">Click Me</button>
    </div>
</body>
</html>
```
#### 1.3 事件冒泡

    阻止事件冒泡:
        a)原生js方式,依赖于事件对象  stopPropagation
        b)vue方式,不依赖于事件对象
            @click.stop

#### 1.4 事件默认行为

    阻止默认行为:
        a)原生js方式,依赖于事件对象 preventDefault
        b)vue方式,不依赖于事件对象
            @click.prevent

代码演示:08.html
```javascript
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件冒泡和默认行为</title>
    <script src="js/vue.js"></script>
    <script>
        window.onload=function(){
            let vm=new Vue({
                el:'#itany',
                methods:{ 
                    show(){
                        console.log(111);
                        // e.stopPropagation();
                    },
                    print(){
                        console.log(222);
                    },
                    write(){
                        console.log(333);
                    },
                    study(){
                        console.log(444);
                        // e.preventDefault();
                    }
                }
            });
        }
    </script>
</head>
<body>
    <div id="itany">
        <div @click="write">
            <p @click="print">
                <!-- <button @click="show($event)">点我</button> -->
                <button @click.stop="show">点我</button>
            </p>
        </div>
        <hr>

        <!-- <a href="#" @click="study($event)">俺是链接</a> -->
        <a href="#" @click.prevent="study">俺是链接</a>
    </div>
</body>
</html>
```
#### 1.5 键盘事件

    回车:@keydown.13 或@keydown.enter
    上:@keydown.38 或@keydown.up

    默认没有@keydown.a/b/c...事件,可以自定义键盘事件,也称为自定义键码或自定义键位别名

代码演示:09.html

```javascript
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>键盘事件</title>
    <script src="js/vue.js"></script>
    <script>
        /**
         * 自定义键位别名
         */
        Vue.config.keyCodes={
            a:65,
            f1:112
        }

        window.onload=function(){
            let vm=new Vue({
                el:'#itany',
                methods:{ 
                    show(e){
                        console.log(e.keyCode);
                        if(e.keyCode==13){
                            console.log('您按了回车');
                        }
                    },
                    print(){
                        // console.log('您按了回车');
                        // console.log('您按了方向键上');
                        console.log('11111');
                    }
                }
            });
        }
    </script>
</head>
<body>
    <div id="itany">
        <!-- 键盘事件:@keydown、@keypress、@keyup -->
        <!-- 用户名:<input type="text" @keydown="show($event)"> -->
        
        <!-- 简化按键的判断 -->
        <!-- 用户名:<input type="text" @keydown="show($event)"> -->
        <!-- 用户名:<input type="text" @keydown.13="print"> -->
        <!-- 用户名:<input type="text" @keydown.enter="print"> -->
        <!-- 用户名:<input type="text" @keydown.up="print"> -->
        用户名:<input type="text" @keydown.f1="print">
        
        <!-- 事件修饰符 -->
        <button @click.once="print">只触发一次</button>
    </div>
</body>
</html>
```
#### 1.6 事件修饰符

    .stop - 调用 event.stopPropagation()。
    .prevent - 调用 event.preventDefault()。
    .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
    .native - 监听组件根元素的原生事件。
    .once - 只触发一次回调。

### 2. 属性

#### 2.1 属性绑定和属性的简写

    v-bind 用于属性绑定, v-bind:属性=""

    属性的简写:
        v-bind:src="" 简写为 :src=""

代码演示:10.html
```javascript
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>属性绑定和属性的简写</title>
    <script src="js/vue.js"></script>
    <script>
        window.onload=function(){
            let vm=new Vue({
                el:'#itany',
                data:{
                    url:'https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png',
                    w:'200px',
                    h:'100px'
                }
            });
        }
    </script>
</head>
<body>
    <div id="itany">
        <!-- <img src="{{url}}"> -->

        <!-- 可以直接访问vue中的数据,不需要使用{{}} -->
        <!-- <img v-bind:src="url"> -->

        <img :src="url" :width="w" :height="h">
    </div>
</body>
</html>
```
#### 2.2 class 和 style 属性

    绑定class和style属性时语法比较复杂:

代码演示:11.html

```javascript
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>class和style属性</title>
    <script src="js/vue.js"></script>
    <script>
        window.onload=function(){
            let vm=new Vue({
                el:'#itany',
                data:{
                    bb:'aa',
                    dd:'cc',
                    flag:true,
                    num:-2,
                    hello:{aa:true,cc:true},
                    xx:{color:'blue',fontSize:'30px'},
                    yy:{backgroundColor:'#ff7300'}
                }
            });
        }
    </script>
    <style>
        .aa{
            color:red;
            font-size:20px;
        }
        .cc{
            background-color:#ccc;
        }
    </style>
</head>
<body>
    <div id="itany">
        <!-- 
            class属性
         -->
        <!-- <p class="aa">武汉软谋</p> -->  <!-- 可以访问,普通css方式 -->

        <!-- <p :class="aa">武汉软谋</p> --> <!-- 不可以,Vue的属性绑定时不能直接css样式 -->

        <!-- 方式1:变量形式 -->
        <!-- <p :class="bb">武汉软谋</p> -->

        <!-- 方式2:数组形式,同时引用多个 -->
        <!-- <p :class="[bb,dd]">武汉软谋</p> -->

        <!-- 方式3:json形式,常用!!! -->
        <!-- <p :class="{aa:true,cc:flag}">武汉软谋</p> -->
        <!-- <p :class="{aa:num>0}">武汉软谋</p> -->

        <!-- 方式4:变量引用json形式 -->
        <!-- <p :class="hello">武汉软谋</p> -->
        
        <!-- 
            style属性
         -->
         <p :style="[xx,yy]">itany</p>

    </div>
</body>
</html>
```

## 六、 模板

### 1. 简介

    Vue.js使用基于HTML的模板语法,可以将DOM绑定到Vue实例中的数据
    模板就是{{}},用来进行数据绑定,显示在页面中
    也称为Mustache语法

### 2. 数据绑定的方式

    a.双向绑定
        v-model
    b.单向绑定
        方式1:使用两对大括号{{}},可能会出现闪烁的问题,可以使用v-cloak解决
        方式2:使用v-text、v-html

### 3. 其他指令

    v-once 数据只绑定一次
    v-pre 不编译,直接原样显示
代码演示:12.html
```javascript
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板</title>
    <script src="js/vue.js"></script>
    <script>
        window.onload=function(){
            let vm=new Vue({
                el:'#itany',
                data:{
                    msg:'welcome to itany'
                },
                created:function(){
                    // alert(111);
                }
            });
        }
    </script>
    <style>
        /* 必须配置css样式,否则不生效 */
        [v-cloak]{ 
            display:none;
        }
    </style>
</head>
<body>
    <div id="itany">
        <input type="text" v-model="msg">
        <h3>aaa<span v-cloak>{{msg}}</span></h3>        
        <h3 v-text="msg"></h3>
        <h3 v-html="msg"></h3>
        <h3 v-once>{{msg}}</h3>
        <h3 v-pre>{{msg}}</h3>

    </div>
</body>
</html>
```

## 七、 过滤器

### 1. 简介

    用来过滤模型数据,在显示之前进行数据处理和筛选
    语法:{{ data | filter1(参数) | filter2(参数)}}

### 2. 关于内置过滤器

    vue1.0中内置许多过滤器,如:
        currency、uppercase、lowercase
        limitBy
        orderBy
        filterBy
    vue2.0中已经删除了所有内置过滤器,全部被废除
    如何解决:
        a.使用第三方工具库,如lodash、date-fns日期格式化、accounting.js货币格式化等
        b.使用自定义过滤器

### 3. 自定义过滤器

    分类:全局过滤器、局部过滤器

#### 3.l 自定义全局过滤器

    使用全局方法Vue.filter(过滤器ID,过滤器函数)

#### 3.l 自定义局部过滤器

代码演示:13.html

```javascript
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自定义过滤器</title>
    <script src="js/vue.js"></script>
    <script>
        /**
         * 自定义全局过滤器
         */
        Vue.filter('addZero',function(data){
            // console.log(data);
            return data<10?'0'+data:data;
        });
        /*Vue.filter('number',(data,n) => {
            // console.log(data,n);
            return data.toFixed(n);
        });*/
        Vue.filter('date',data => {
            let d=new Date(data);
            return d.getFullYear()+'-'+(d.getMonth()+1)+'-'+d.getDate()+' '+d.getHours()+':'+d.getMinutes()+':'+d.getSeconds();
        });
        

        window.onload=function(){
            let vm=new Vue({
                el:'#itany',
                data:{
                    currentTime:Date.now()
                },
                filters:{ //局部过滤器
                    number:(data,n) => {
                        return data.toFixed(n);
                    }
                }
            });
        }
    </script>
</head>
<body>
    <div id="itany">
        <!-- <h3>{{3 | addZero}}</h3> -->
        
        <!-- 课后作业:自己实现toFiexed()四舍五入的功能 -->
        <h3>{{12.345678 | number(2)}}</h3>
        <!-- <h3>{{12.045 | number(2)}}</h3> -->

        <h3>{{currentTime | date}}</h3>
    
    </div>
</body>
</html>
```

猜你喜欢

转载自www.cnblogs.com/laneyfu/p/12274257.html