Vue全家桶入门基础教程


Posted in Vue.js onMay 14, 2021

1. Vue概述

Vue(读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式JavaScript框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。

渐进式: 声明式渲染→组件系统→客户端路由→集中式状态管理→项目构建

可以使用其中的一个或者多个

优点:

  • 易用:熟悉HTML,CSS.JavaScript知识后,可快速上手Vue
  • 灵活:在一个库和一套完整框架之间自如伸缩
  • 高效:20kB运行大小,超快虚拟DOM

 2. Vue的基本使用

2.1 传统开发模式对比

//原生JS
 <div id="msg"></div>
  <script type="text/javascript">
    var msg = 'Hello World'
    var div = document.querySelector('#msg');
    div.innerHTML = msg
  </script>
//jQuery
<div id="msg"></div>
  <script type="text/javascript" src="js/jquery.js"></script>
  <script type="text/javascript">
    var msg = 'Hello World';
    $('#msg').html(msg);
  </script>

2.2 Vue.js之HelloWorld基本步骤

引入Vue的方法:

1.下载Vue.js,然后在<script type='text/javascript' src='js/vue.js'></script>引入

2.使用CDN方法。 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.js"></script>

Vue的基本使用步骤:

​ 1、需要提供标签用于填充数据

​ 2、引入Vue.js库文件

​ 3、可以使用vue的语法做功能了

​ 4、把vue提供的数据填充到标签里面

//1.HelloWorld.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title></title>
</head>

<body>
  <div id="app">
      //插值表达式
    <div>{{num}}</div> 
    <div><button @click='handle'>点击</button></div>
  </div>
 //引入vue
  <script type='text/javascript' src='js/vue.js'></script>
  <script type='text/javascript'>
    var vm = new Vue({
      el: '#app',
      data: {
        num: 0
      },
      methods: {
        handle: function () {
          this.num++;
        }
      }
    });
  </script>
</body>

</html>

Vue全家桶入门基础教程

2.3 Vue.js之HelloWorld细节分析

1. 实例参数分析

  • el:元素的挂载位置(值可以是CSS选择器或者DOM元素)关联起来
  • data:模型数据(值是一个对象)
  • methods,该属性用于在Vue对象中定义方法。

2.插值表达式用法

  • 将数据填充到HTML标签中
  • 插值表达式支持基本的计算操作

3. Vue代码运行原理分析

概述编译过程的概念(Vue语法经过Vue框架编译成原生JS语法,才能够被浏览器执行)

Vue全家桶入门基础教程

3. Vue 模板语法

3.1 模板语法概述

前端渲染:把数据填充到HTML标签中

Vue全家桶入门基础教程

前端渲染方式:

  • 原生js拼接字符串
  • 使用前端模板引擎
  • 使用vue特有的模板语法(推荐)

原生js拼接字符串基本上就是将数据以字符串的方式拼接到HTML标签中。

缺点:不同开发人员的代码风格差别很大,随着业务的复杂,后期的维护变得逐渐困难起来。

使用前端模板引擎是基于模板引擎art-template的一段代码,与拼接字符串相比,代码明显规范了很多,它拥有自己的一套模板语法规则。

优点:大家都遵循同样的规则写代码,代码可读性明显提高了,方便后期的维护。

缺点:没有专门提供事件机制。

插值表达式 {{变量}}

  • 使用'mustache'语法 {{ msg }}(双花括号)
  • mustache 标签将会被替换为 data 对象上对应的 msg 属性的值。
  • 只要绑定的数据对象上的 msg 属性发生改变,插值内容也会随之更新。
<div id="app">
      <!-- this 指向 vm -->
      <p> {{ msg }} </p>
   </div>
   
   <script>
	var vm = new Vue({
    	el: ‘#app',
  		data: {
  			msg: 'hello vue.js'
  		}
  	})
	</script>

模板语法概述

  • 插值表达式
  • 指令
  • 事件绑定
  • 属性绑定
  • 样式绑定
  • 分支循环结构

3.2 指令

1.什么是指令?

  • 自定义属性:如在html5中定义,属性均可随意命名。
  • 指令的本质就是自定义属性
  • 指令的格式:以v-开始(比如:v-cloak)

2.v-cloak指令用法

插值表达式存在的问题:“闪动”

如何解决该问题:使用v-cloak指令

v-cloak指令的用法
  1、提供样式
   属性选择器
    [v-cloak]{
      display: none;
    }
  2、在插值表达式所在的标签中添加v-cloak指令

背后的原理:先通过样式隐藏内容,然后在内存中进行值的替换,替换好之后再显示最终的结果

//02-指令v-cloak的用法.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style type="text/css">
  [v-cloak]{
    display: none;
  }
  </style>
</head>
<body>
  <div id="app">
    <div v-cloak>{{msg}}</div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var app = new Vue({
      el: '#app',
      data: {
        msg: 'Hello Vue'
      }
    });
  </script>
</body>
</html>

3 .数据绑定指令

  • v-text填充纯文本

用于将数据填充到标签中,作用于插值表达式类似,但是没有闪动问题

  • v-html填充HTML片段

用于将HTML片段填充到标签中,但是可能有安全问题

  • v-pre填充原始信息

显示原始信息,跳过编译过程(分析编译过程)

//03-数据填充相关3个指令用法.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <div>{{msg}}</div>
    <div v-text='msg'></div>
    <div v-html='msg1'></div>
    <div v-pre>{{msg}}</div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        msg: 'Hello Vue',
        msg1: '<h1>HTML</h1>'
      }
    });
  </script>
</body>
</html>

Vue全家桶入门基础教程

4.数据响应式

  • 如何理解响应式

html5中的响应式(屏幕尺寸的变化导致样式的变化)
数据的响应式(数据的变化导致页面内容的变化)

  • 数据绑定:将数据填充到标签中,默认是响应式的
  • v-once只编译一次,显示内容之后不再具有响应式功能

v-once的应用场景:如果显示的信息后续不需要再修改,可以使用v-once提高性能。

//04-指令v-once的用法.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <h2>{{message}}</h2>
    <h2 v-once>{{message}}</h2>
  </div>
  <script>
    const app = new Vue({
      el: "#app",
      data: {
        message: "你好啊"
      }
    })
  </script>
</body>

</html>

Vue全家桶入门基础教程

3.3 双向数据绑定

1.什么是双向数据绑定?

Vue全家桶入门基础教程

2.双向数据绑定分析

Vue中使用v-model指令来实现标签内容的绑定(双向绑定).如表单元素和数据的双向绑定

v-model只能用于表单类型,就是输入性控件,其他控件不能用,用v-bind

<input type='text' v-model='uname'/>
//05.双向数据绑定.html
  <!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
  </head>
  <body>
    <div id="app">
      <div>{{msg}}</div>
      <div>
        <input type="text" v-model='msg'>
      </div>
    </div>
    <script type="text/javascript" src="js/vue.js"></script>
    <script type="text/javascript">
      /* 双向数据绑定
        1、从页面(用户)到数据
        2、从数据到页面  */
      var vm = new Vue({
        el: '#app',
        data: {
          msg: 'Hello Vue'
        }
      });
    </script>
  </body>
  </html>

Vue全家桶入门基础教程

案例解析:

当我们在输入框输入内容时,因为input中的v-model绑定了msg,所以会实时将输入的内容传递给msg,msg发生改变。

当msg发生改变时,因为上面我们使用Mustache语法,将msg的值插入到DOM中,所以DOM会发生响应的改变。

3.MVVM设计思想

Vue全家桶入门基础教程

MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开

  • View层:视图层

在我们前端开发中,通常就是DOM层。主要的作用是给用户展示各种信息。

  • Model层:数据层

数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据。

  • VueModel层:视图模型层

视图模型层是View和Model沟通的桥梁。

一方面它通过Data Binding(数据绑定),将Model的改变实时的反应到View中

另一方面它通过DOM Listener(DOM监听),当DOM发生一些事件(点击、滚动、touch等)时,可以监听到,并在需要的情况下改变对应的Data。

3.4 事件绑定

1.Vue如何处理事件?

  • v-on指令用法:用于绑定HTML事件,如鼠标点击事件
  • 当前button绑定鼠标点击事件,点击则调用doSomething方法

在这里doSomething() 是一个函数,可以写在methods的方法中,供该标签调用.

<button v-on:click="doSomething">...</button>

v-on语法糖(简写形式)@

<input type='button' @click='num++'/>
//06-事件基本用法.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <div>{{num}}</div>
    <div>
        //4种都可以实现
      <button v-on:click='num++'>点击</button>
      <button @click='num++'>点击1</button>
      <button @click='handle'>点击2</button>
      <button @click='handle()'>点击3</button>
    </div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        num: 0
      },
      methods: {
        handle: function () {
          // 这里的this是Vue的实例对象
          console.log(this === vm)
          // 在函数中 想要使用data里面的数据 一定要加this 
          this.num++;v
        }
      }
    });
  </script>
</body>

</html>

2.事件函数的调用方式

直接绑定函数名称

<button v-on:click='say'>Hello</button>

调用函数

<button v-on:click='say()'>Hello</button>

3.事件函数参数传递

事件函数参数传递

<button v-on:click='say('hi',$event)'>Hello</button>
//07-事件函数传参.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <div>{{num}}</div>
        <div>
            <!-- 如果事件直接绑定函数名称,那么默认会传递事件对象作为事件函数的第一个参数 -->
            <button v-on:click='handle1'>点击1</button>
            <!-- 2、如果事件绑定函数调用,那么事件对象必须作为最后一个参数显示传递,
                 并且事件对象的名称必须是$event -->
            <button v-on:click='handle2(123, 456, $event)'>点击2</button>
        </div>
    </div>
    <script type="text/javascript" src="js/vue.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el: '#app',
            data: {
                num: 0
            },
            methods: {
                handle1: function(event) {
                    console.log(event.target.innerHTML)
                },
                handle2: function(p, p1, event) {
                    console.log(p, p1)
                    console.log(event.target.innerHTML)
                    this.num++;
                }
            }
        });
    </script>
</body>

</html>

Vue全家桶入门基础教程

4.事件修饰符

.stop 阻止冒泡

<a v-on:click.stop="handle">跳转</a>

.prevent阻止默认行为

<a v-on:click.prevent="handle">跳转</a>
//08-事件修饰符.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <div>{{num}}</div>
    <div @click='handle0'>
      <button @click.stop='handle1'>点击1</button>
    </div>
    <div>
      <a href="http://www.baidu.com" @click.prevent='handle2'>百度</a>
    </div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        num: 0
      },
      methods: {
        handle0: function () {
          this.num++;
        },
        handle1: function (event) {
          // js阻止冒泡
          // event.stopPropagation();
        },
        handle2: function (event) {
          // js阻止默认行为
          // event.preventDefault();
        }
      }
    });
  </script>
</body>

</html>

未加事件修饰符:

Vue全家桶入门基础教程

加事件修饰符:

Vue全家桶入门基础教程

5.按键修饰符

.enter 回车键

<input v-on:keyup.enter='submit'>

.delete删除键

<input v-on:keyup.delete='handle'>
//09-按键修饰符.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <form action="">
      <div>
        用户名: <input type="text" v-on:keyup.delete='clearContent' v-model='uname'>
      </div>
      <div>
        密码:<input type="text" v-on:keyup.enter='handleSubmit' v-model='pwd'>
      </div>
      <div>
        <input type="button" v-on:click='handleSubmit' value="提交">
      </div>
    </form>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    Vue.config.keyCodes.f1 = 113
    var vm = new Vue({
      el: '#app',
      data: {
        uname: '',
        pwd: '',
        age: 0
      },
      methods: {
        clearContent:function(){
          // 按delete键的时候,清空用户名
          this.uname = '';
        },
        handleSubmit: function(){
          console.log(this.uname,this.pwd)
        }
      }
    });
  </script>
</body>
</html>

Vue全家桶入门基础教程

6.自定义按键修饰符

全局config.keyCodes 对象

规则:自定义按键修饰符名字是自定义的,但是对应的值必须是按键对应event.keyCode值

Vue.config.keyCodes.f1 = 112
//10-自定义事件修饰符.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title></title>
  <script type='text/javascript' src='js/vue.js'></script>
</head>

<body>
  <div id="app">
    <input type="text" @keyup.f1='handle' v-model='msg'>
  </div>
  <script type='text/javascript'>
    Vue.config.keyCodes.f1 = 65
    const app = new Vue({
      el: "#app",
      data: {
        msg: ''
      },
      methods: {
        handle: function (event) {
          console.log(event.keyCode);
        }
      }
    })
  </script>
</body>

</html>

Vue全家桶入门基础教程

案例:简单计算器

Vue全家桶入门基础教程

需求:实现简单的加法计算,分别输入数值a和数值,点击计算按钮,结果显示在下面。

步骤:

  • 通过v-model指令实现数值a和数值b的绑定
  • 给计算按钮绑定事件,实现计算逻辑
  • 将计算结果绑定到对应位置
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title></title>
  <script type='text/javascript' src='js/vue.js'></script>
</head>

<body>
  <div id="app">
    <h2>简单计算器</h2>
    <div>数值A:<input type="text" v-model="a"></div>
    <div>数值B:<input type="text" @keyup.enter='Sum' v-model="b"></div>
    <div><button @click='Sum'>计算</button></div>
    <div>计算结果:</div>
    <div v-text='result'></div>
  </div>
  <script type='text/javascript'>
    const app = new Vue({
      el: "#app",
      data: {
        a: '',
        b: '',
        result: ''
      },
      methods: {
        Sum: function () {
          //实现计算逻辑 表单输入默认是字符串 加this很重要
          this.result = parseInt(this.a) + parseInt(this.b)
        }
      }
    })
  </script>
</body>

</html>

Vue全家桶入门基础教程

3.5 属性绑定

1.Vue如何动态处理属性?

v-bind是处理HTML中的标签属性的,例如

就是一个标签,也是一个标签,我们绑定上的src进行动态赋值。

v-bind指令用法

<a v-bind:href='url'>跳转</a>

缩写形式

<a :href='url'>跳转</a>
//12-属性绑定基本用法.html
<!DOCTYPE html>
 <html lang="en">

 <head>
   <meta charset="UTF-8">
   <title></title>
 </head>

 <body>
   <div id="app">
     <a v-bind:href="url">百度</a>
     <button @click='handle'>切换</button>
   </div>
   <script type='text/javascript' src='js/vue.js'></script>
   <script type='text/javascript'>
     const app = new Vue({
       el: "#app",
       data: {
         url: 'http://www.baidu.com'
       },
       methods: {
         handle: function () {
           //修改url地址
           this.url = 'http://www.itcast.com'
         }
       }
     })
   </script>
 </body>

 </html>

Vue全家桶入门基础教程

2.v-model的低层实现原理分析

不使用v-model也可以实现双向绑定

<input v-bind:value="msg" v-on:input="msg=$event.target.value">
//13-指令v-model的本质.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <div>{{msg}}</div>
    <input type="text" v-bind:value="msg" v-on:input='handle'>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        msg: 'hello'
      },
      methods: {
        handle: function(event){
          // 使用输入域中的最新的数据覆盖原来的数据
          this.msg = event.target.value;
        }
      }
    });
  </script>
</body>
</html>

Vue全家桶入门基础教程

3.6 样式绑定

1. class样式处理

对象语法

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

数组语法

<div v-bind:class="[activeClass, errorClass]"></div>
//14-样式绑定之class绑定对象用法.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style type='text/css'>
    .active {
      border: 1px solid red;
      width: 100px;
      height: 100px;
    }
    .error {
      background-color: pink;
    }
  </style>
</head>

<body>
  <div id="app">
    <div :class="{active:isActive,error:isError}">测试样式</div>
    <button @click='handle'>切换</button>
  </div>
</body>
<script type='text/javascript' src='js/vue.js'></script>
<script type='text/javascript'>
  const app = new Vue({
    el: "#app",
    data: {
      isActive: true,
      isError: true,
    },
    methods: {
      handle: function () {
        //控制isActive在true和false之间切换
        this.isActive = !this.isActive
        this.isError = !this.isError
      }
    }
  })
</script>

</html>
//15-样式绑定之class绑定数组用法.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style type="text/css">
    .active {
      border: 1px solid red;
      width: 100px;
      height: 100px;
    }
    .error {
      background-color: pink;
    }
  </style>
</head>
<body>
  <div id="app">
    <div v-bind:class='[activeClass, errorClass]'>测试样式</div>
    <button v-on:click='handle'>切换</button>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        activeClass: 'active',
        errorClass: 'error'
      },
      methods: {
        handle: function(){
          this.activeClass = '';
          this.errorClass = '';
        }
      }
    });
  </script>
</body>
</html>

Vue全家桶入门基础教程

//16-样式绑定之class绑定3个细节用法.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style type="text/css">
    .active {
      border: 1px solid red;
      width: 100px;
      height: 100px;
    }
    .error {
      background-color: orange;
    }
    .test {
      color: blue;
    }
    .base {
      font-size: 28px;
    }
  </style>
</head>
<body>
  <div id="app">
    <div v-bind:class='[activeClass, errorClass, {test: isTest}]'>测试样式</div>
    <div v-bind:class='arrClasses'></div>
    <div v-bind:class='objClasses'></div>
    <div class="base" v-bind:class='objClasses'></div>

    <button v-on:click='handle'>切换</button>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      样式绑定相关语法细节:
      1、对象绑定和数组绑定可以结合使用
      2、class绑定的值可以简化操作
      3、默认的class如何处理?默认的class会保留
      
    */
    var vm = new Vue({
      el: '#app',
      data: {
        activeClass: 'active',
        errorClass: 'error',
        isTest: true,
        arrClasses: ['active','error'],
        objClasses: {
          active: true,
          error: true
        }
      },
      methods: {
        handle: function(){
          // this.isTest = false;
          this.objClasses.error = false;
        }
      }
    });
  </script>
</body>
</html>

2. style样式处理

对象语法

<div v-bind:style="{ color: activeColor, fontSize: fontSize }"></div>

数组语法

<div v-bind:style="[baseStyles, overridingStyles]"></div>
//17-样式绑定之style绑定用法.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>

</head>

<body>
  <div id="app">
    <div v-bind:style='{border: borderStyle, width: widthStyle, height: heightStyle}'></div>
    <div v-bind:style='objStyles'></div>
    <div v-bind:style='[objStyles, overrideStyles]'></div>
    <button v-on:click='handle'>切换</button>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        borderStyle: '1px solid blue',
        widthStyle: '100px',
        heightStyle: '200px',
        objStyles: {
          border: '1px solid green',
          width: '200px',
          height: '100px'
        },
        overrideStyles: {
          border: '5px solid orange',
          backgroundColor: 'blue'
        }
      },
      methods: {
        handle: function () {
          this.heightStyle = '100px';
          this.objStyles.width = '100px';
        }
      }
    });
  </script>
</body>

</html>

Vue全家桶入门基础教程

3.7 分支循环结构

1.分支结构

  • v-if
  • v-else
  • v-else-if
  • v-show

2.v-if与v-show的区别

  • v-if控制元素是否渲染到页面
  • v-show控制元素是否显示(已经渲染到了页面)
  • v-if当条件为false时,压根不会有对应的元素在DOM中。v-show当条件为false时,仅仅是将元素的display属性设置为none而已
  • 当需要在显示与隐藏之间切换很频繁时,使用v-show.当只有一次切换时,通过使用v-if
//18-分支结构.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  
</head>
<body>
  <div id="app">
    <div v-if='score>=90'>优秀</div>
    <div v-else-if='score<90&&score>=80'>良好</div>
    <div v-else-if='score<80&&score>60'>一般</div>
    <div v-else>比较差</div>
    <div v-show='flag'>测试v-show</div>
    <button v-on:click='handle'>点击</button>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*v-show的原理:控制元素样式是否显示 display:none*/
    var vm = new Vue({
      el: '#app',
      data: {
        score: 10,
        flag: false
      },
      methods: {
        handle: function(){
          this.flag = !this.flag;
        }
      }
    });
  </script>
</body>
</html>

Vue全家桶入门基础教程

3.循环结构

  • v-for遍历数组 v-for的语法类似于JavaScript中的for循环。格式如下:item in items的形式。

其中item为自定义属性(改为abc都行),items为需要遍历的数据,index为索引

<li v-for='item in list'>{{item}}</li>
<li v-for='(item,index) in list'>{{item}} + '---' +{{index}}</li>

key的作用:帮助Vue区分不同的元素对开发功能没有效果,仅仅帮助vue提高性能,要确保key的唯一性

<li :key='item.id' v-for='(item,index) in list'>{{item}} + '---' {{index}}</li>
//19-循环结构-遍历数组.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  
</head>
<body>
  <div id="app">
    <div>水果列表</div>
    <ul>
      <li v-for='item in fruits'>{{item}}</li>
      <li v-for='(item, index) in fruits'>{{item + '---' + index}}</li>
      <li :key='item.id' v-for='(item, index) in myFruits'>
        <span>{{item.ename}}</span>
        <span>-----</span>
        <span>{{item.cname}}</span>
      </li>

    </ul>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        fruits: ['apple', 'orange', 'banana'],
        myFruits: [{
          id: 1,
          ename: 'apple',
          cname: '苹果'
        },{
          id: 2,
          ename: 'orange',
          cname: '橘子'
        },{
          id: 3,
          ename: 'banana',
          cname: '香蕉'
        }]
      }
    });
  </script>
</body>
</html>

Vue全家桶入门基础教程

4. 循环结构

v-for遍历对象

<div v-for='(value, key, index) in object'></div> value值 key键 index索引

v-if和v-for结合使用

<div v-if='value==12' v-for='(value, key, index) in object'></div>
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>

</head>

<body>
  <div id="app">
    <div v-if='v==13' v-for='(value,key,index) in obj'>{{value + '---' + key + '---' + index}}</div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        obj: {
          uname: 'zhangsan',
          age: 13,
          gender: 'female'
        }
      }
    });
  </script>
</body>

</html>

Vue全家桶入门基础教程

3.8 v-model、v-on、v-bind使用说明

v-model

v-model指令来实现表单标签内容的双向绑定.如表单元素和数据的双向绑定

v-model只能用于表单类型,就是输入性控件,其他控件不能用,用v-bind

一个input标签绑定了msg这个变量,那么只要input输入发生改变,msg的值也就跟着改变,反过来也是一样,这种绑定是双向绑定

<input type='text' v-model='msg'>

v-on

v-on指令用法:用于绑定HTML事件,如鼠标点击事件

当前button绑定鼠标点击事件,点击则调用doSomething方法

<button v-on:click="doSomething">...</button>

v-bind

v-bind是处理HTML中的标签属性的,默认情况下标签自带属性的值是固定的,在为了能够动态的给这些属性添加值,可以使用v-bind 例如是一个标签,我们绑定上的src进行动态赋值。

<img :src='msg'>

4. 基础案例:Tab选项卡

步骤:

1.实现静态UI效果

用传统的方式实现标签结构和样式

2.基于数据重构UI效果

将静态的结构和样式重构为基于Vue模板语法的形式

处理事件绑定和js控制逻辑

3.声明式编程

模板的结构和最终显示的效果基本一致

Vue全家桶入门基础教程

//21-选项卡案例.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style type="text/css">
    .tab ul {
      overflow: hidden;
      padding: 0;
      margin: 0;
    }

    .tab ul li {
      box-sizing: border-box;
      padding: 0;
      float: left;
      width: 100px;
      height: 45px;
      line-height: 45px;
      list-style: none;
      text-align: center;
      border-top: 1px solid blue;
      border-right: 1px solid blue;
      cursor
    }

    .tab ul li:first-child {
      border-left: 1px solid blue;
    }

    .tab ul li.active {
      background-color: orange;
    }

    .tab div {
      width: 500px;
      height: 300px;
      display: none;
      text-align: center;
      font-size: 30px;
      line-height: 300px;
      border: 1px solid blue;
      border-top: 0px;
    }

    .tab div.current {
      display: block;
    }
  </style>
</head>

<body>
  <div id="app">
    <div class="tab">
      <ul>
        <li @click='change(index)' :class='currentIndex==index?"active":""' :key=' item.id'
          v-for='(item,index) in list'>
          {{item.title}}</li>
      </ul>
      <div :class='currentIndex==index?"current":""' :key='item.id' v-for='(item,index) in list'>
        <img :src="item.path">
      </div>
    </div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        currentIndex: 0, //选项卡当前的索引
        list: [{
            id: 1,
            title: 'apple',
            path: 'img/apple.png'
          },
          {
            id: 2,
            title: 'orange',
            path: 'img/orange.png'
          }, {
            id: 3,
            title: 'lemon',
            path: 'img/lemon.png'
          }
        ]
      },
      methods: {
        change: function (index) {
          //在这里实现选项卡切换操作:操作类名,通过currentIndex
          this.currentIndex = index;
        }
      }
    })
  </script>
</body>

</html>

Vue全家桶入门基础教程

5. Vue常用特性

 5.1 常用特性概览

  • 表单操作
  • 自定义指令
  • 计算属性
  • 过滤器
  • 侦听器
  • 生命周期

 5.2 表单操作

1.基于Vue的表单操作

  • Input单行文本
  • textarea多行文
  • select 下拉多选
  • radio 单选框
  • checkbox多选框

Vue全家桶入门基础教程

//01-表单基本操作.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <style type="text/css">
      form div {
        height: 40px;
        line-height: 40px;
      }
      form div:nth-child(4) {
        height: auto;
      }
      form div span:first-child {
        display: inline-block;
        width: 100px;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <form action="http://www.baidu.com">
        <div>
          <span>姓名:</span>
          <span>
            <input type="text" v-model="uname" />
          </span>
        </div>
        <div>
          <span>性别:</span>
          <span>
            <input type="radio" id="male" value="1" v-model="gender" />
            <label for="male">男</label>
            <input type="radio" id="female" value="2" v-model="gender" />
            <label for="female">女</label>
          </span>
        </div>
        <div>
          <span>爱好:</span>
          <input type="checkbox" id="ball" value="1" v-model="hobby" />
          <label for="ball">篮球</label>
          <input type="checkbox" id="sing" value="2" v-model="hobby" />
          <label for="sing">唱歌</label>
          <input type="checkbox" id="code" value="3" v-model="hobby" />
          <label for="code">写代码</label>
        </div>
        <div>
          <span>职业:</span>
          <select v-model="occupation" multiple>
            <option value="0">请选择职业</option>
            <option value="1">教师</option>
            <option value="2">软件工程师</option>
            <option value="3">律师</option>
          </select>
        </div>
        <div>
          <span>个人简介:</span>
          <textarea v-model="desc"></textarea>
        </div>
        <div>
          <input type="submit" value="提交" @click.prevent="handle" />
        </div>
      </form>
    </div>
    <script type="text/javascript" src="js/vue.js"></script>
    <script type="text/javascript">
      var vm = new Vue({
        el: "#app",
        data: {
          uname: "",
          gender: "", //单选为值
          hobby: [""], //多选为数组
          occupation: [""],
          desc: "",
        },
        methods: {
          handle: function () {},
        },
      });
    </script>
  </body>
</html>

Vue全家桶入门基础教程

2.表单域修饰符

  • number:表单输入的字符串转化为数值
  • trim:去掉开始和结尾的空格
  • lazy:将input事件切换为change事件 input事件立即触发 change事件失去焦点触发
<input v-model.number='age' type='number'
//02-表单域修饰符用法.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <input type="text" v-model.number='age'>
    <input type="text" v-model.trim='info'>
    <input type="text" v-model.lazy='msg'>
    <div>{{msg}}</div>
    <button @click='handle'>点击</button>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        age: '',
        info: '',
        msg: ''
      },
      methods: {
        handle: function () {
          console.log(this.age + 1)
          console.log(this.info.length)
        }
      }
    });
  </script>
</body>

</html>

Vue全家桶入门基础教程

5.3 自定义指令

1.为何需要自定义指令?

内置指令不满足需求

2.自定义指令的语法规则(获取元素焦点)

//注册一个全局自定义指令'v-focus' 
//focus为指令名称  调用时加v-
Vue.directive('focus'{
    //当被绑定非的元素插入到DOM中时调用
	inserted:function(el){
	//获取元素的焦点
	el.focus()
	}
})

3.自定义指令用法

<input type="text" v-focus>

一个指令定义对象可以提供如下几个钩子函数(均为可选):

  • bind:只调用一次,指令第一次绑定到元素时调用,在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)。

指令钩子函数会被传入以下参数:

e1:指令所绑定的元素,可以用来直接操作DOM.

binding:一个对象,包含以下属性:

  • name:指令名,不包括v-前缀。
  • value:指令的绑定值,例如:v-my-directive="1 + 1"中,绑定值为2
  • oldvalue:指令绑定的前一个值,仅在update和componentUpdated钩子中可用。无论值是否改变都可用。
//03-自定义指令基本用法.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <input type="text" v-focus>
    <input type="text">
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    Vue.directive('focus', {
      inserted: function (el) {
        // el表示指令所绑定的元素
        el.focus();
      }
    });
    var vm = new Vue({
      el: '#app',
      data: {

      },
      methods: {
        handle: function () {

        }
      }
    });
  </script>
</body>

</html>

Vue全家桶入门基础教程

4.带参数的自定义指令(改变元素背景色)

Vue.directive('color',{
	inserted:function(el,binding){
		el.style.backgroundColor =binding.value.color;
	}
})

5.指令的用法

<input type="text" v-color='{color:'orange'}'>
//04-带参数的自定义指令.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title></title>
</head>

<body>
  <div id="app">
    <input type="text" v-color='msg'>
  </div>
  <script type='text/javascript' src='js/vue.js'></script>
  <script type='text/javascript'>
    Vue.directive('color', {
      bind: function (el, binding) {
        //根据指令的参数设置背景色
        el.style.backgroundColor = binding.value.color
      }
    });
    const app = new Vue({
      el: "#app",
      data: {
        msg: {
          color: 'pink'
        }
      },
      methods: {}
    })
  </script>
</body>

</html>

Vue全家桶入门基础教程

6.局部指令:只能在本组件中使用

directives:{
	focus:{
	//指令的定义
	inserted:function(el){
	el.focus()
		}
	}
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <input type="text" v-color='msg'>
    <input type="text" v-focus>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        msg: {
          color: 'red'
        }
      },
      methods: {
        handle: function(){
          
        }
      },
      directives: {
        color: {
          bind: function(el, binding){
            el.style.backgroundColor = binding.value.color;
          }
        },
        focus: {
          inserted: function(el) {
            el.focus();
          }
        }
      }
    });
  </script>
</body>
</html>

Vue全家桶入门基础教程

5.4 计算属性

1.为何需要计算属性?

Vue中的computed属性被称为计算属性,计算属性是写在实例的computed选项

表达式的计算逻辑可能会比较复杂,使用计算属性可以使模板内容更加简介

2.计算属性的用法

computed: {
        reverseString: function(){
          return this.msg.split('').reverse().join('');
        }
 }
//06-计算属性基本用法.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <div>{{msg}}</div>
    <div>{{reverseString}}</div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        msg: 'nihao'
      },
      computed: {
        reverseString: function () {
            //return不要忘记
          return this.msg.split('').reverse().join('');
        }
      }
    });
  </script>
</body>

</html>

Vue全家桶入门基础教程

3.计算属性和方法的区别

  • 计算属性是基于它们的依赖进行缓存,如果多次使用时,计算属性只会调用一次,性能上计算属性明显比methods好,如果依赖改变则重新缓存
  • 方法不缓存
//07-计算属性与方法的区别.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <div>{{reverseString}}</div>
    <div>{{reverseString}}</div>
    <div>{{reverseMessage()}}</div>
    <div>{{reverseMessage()}}</div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        msg: 'Nihao',
        num: 100
      },
      methods: {
        reverseMessage: function () {
          console.log('methods')
          return this.msg.split('').reverse().join('');
        }
      },
      computed: {
        reverseString: function () {
          console.log('computed')
          return this.msg.split('').reverse().join('');
        }
      }
    });
  </script>
</body>

</html>

Vue全家桶入门基础教程

5.5 侦听器

Vue全家桶入门基础教程

1. 侦听器的应用场景

数据变化时执行异步或开销较大(比较耗时)的操作

2.侦听器的用法

watch: {
        firstName: function (val) {
          this.fullName = val + ' ' + this.lastName;
        },
        LastName: function (val) {
          this.fullName = this.firstName + ' ' + val;
        },
    }
//08-侦听器基本用法.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <div>
      <span>名:</span>
      <span>
        <input type="text" v-model='firstName'>
      </span>
    </div>
    <div>
      <span>姓:</span>
      <span>
        <input type="text" v-model='lastName'>
      </span>
    </div>
    <div>{{fullName}}</div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        firstName: 'Jim',
        lastName: 'Green',
        fullName: 'Jin Green'
      },
      watch: {
        firstName: function (val) {
          this.fullName = val + ' ' + this.lastName;
        },
        LastName: function (val) {
          this.fullName = this.firstName + ' ' + val;
        },
      }
    });
  </script>
</body>

</html>

Vue全家桶入门基础教程

案例:验证用户名是否可用

需求:输入框中输入姓名,失去焦点时验证是否存在,如果已经存在,提示从新输入,如果不存在,提示可以用。

需求分析:

  1. 通过v-model实现数据绑定
  2. 需要提供提示信息
  3. 需要侦听器监听输入信息的变化
  4. 需要修改触发的事件

侦听器

1、采用侦听器监听用户名的变化

2、调用后台接口进行验证

3、根据验证的结果调整提示信息

//09-侦听器案例.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <div>
      <span>用户名:</span>
      <span>
        <input type="text" v-model.lazy='uname'>
      </span>
      <span>{{tip}}</span>
    </div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        uname: '',
        tip: ''
      },
      methods: {
        checkName: function (uname) {
          //调用接口,但是可以使用定时任务的方式模拟接口调用
          var that = this;
          setTimeout(function () {
            //模拟接口调用
            if (uname == 'admin') {
              that.tip = '用户名已经存在,请更换一个';
            } else {
              that.tip = '用户名可以使用'
            }
          }, 1000)
        }
      },
      watch: {
        uname: function (val) {
          //调用后台接口验证用户名的合法性
          this.checkName(val);
          //修改提示信息
          this.tip = '正在验证中...'
        }
      }
    });
  </script>
</body>

</html>

Vue全家桶入门基础教程

5.6 过滤器

1.过滤器的作用是什么?

格式化数据,比如将字符串格式化为首字母大写,将日期格式化为指定的格式等

2.全局过滤器

Vue.filter('过滤器名称',function(value){
//过滤器业务逻辑
})

3.过滤器的使用

<div>{{msg |upper}}</div>//upper为过滤器名称
<div>{{msg |upper | lower}}</div>//级联操作
<div :id='id | formatId'></div>

4.局部过滤器

filters:{
	upper:function(val){
        return val.charAt(0).toUpperCase() + val.slice(1);
	}
}
//10-过滤器基本用法.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <input type="text" v-model='msg'>
    <div>{{msg | upper}}</div>
    <div>{{msg | upper | lower}}</div>
    <div :abc='msg | upper'>测试数据</div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    Vue.filter('lower', function (val) {
      return val.charAt(0).toLowerCase() + val.slice(1);
    });
    var vm = new Vue({
      el: '#app',
      data: {
        msg: ''
      },
      filters: {
        upper: function (val) {
          //拿到首字母将其变成大写,然后和后面的字母拼接
          return val.charAt(0).toUpperCase() + val.slice(1);
        }
      }
    });
  </script>
</body>

</html>

Vue全家桶入门基础教程

5.带参数的过滤器

Vue.filter('format',function(value,arg){
	//从arg开始接收参数
})

6.过滤器的使用

<div>{{data | format('yyyy-MM-dd')}}</div>

案例:使用过滤器格式化时期

Vue全家桶入门基础教程

//10-过滤器基本用法.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <div>{{date | format('yyyy-MM-dd hh:mm:ss')}}</div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    Vue.filter('format', function(value, arg) {
      function dateFormat(date, format) {
          if (typeof date === "string") {
              var mts = date.match(/(\/Date\((\d+)\)\/)/);
              if (mts && mts.length >= 3) {
                  date = parseInt(mts[2]);
              }
          }
          date = new Date(date);
          if (!date || date.toUTCString() == "Invalid Date") {
              return "";
          }
          var map = {
              "M": date.getMonth() + 1, //月份 
              "d": date.getDate(), //日 
              "h": date.getHours(), //小时 
              "m": date.getMinutes(), //分 
              "s": date.getSeconds(), //秒 
              "q": Math.floor((date.getMonth() + 3) / 3), //季度 
              "S": date.getMilliseconds() //毫秒 
          };

          format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
              var v = map[t];
              if (v !== undefined) {
                  if (all.length > 1) {
                      v = '0' + v;
                      v = v.substr(v.length - 2);
                  }
                  return v;
              } else if (t === 'y') {
                  return (date.getFullYear() + '').substr(4 - all.length);
              }
              return all;
          });
          return format;
      }
      return dateFormat(value, arg);
    })
    var vm = new Vue({
      el: '#app',
      data: {
        date: new Date()
      }
    });
  </script>
</body>
</html>

Vue全家桶入门基础教程

5.7 Vue生命周期

生命周期:事物从诞生到消亡的整个过程

vue的生命周期:每个Vue实例在被创建之前都要经过一系列的初始化过程,这个过程就是.beforeCreate()创建之前

生命周期钩子:就是可以让你在页面生成的不同阶段执行动作的api,作用就是只要页面到了这个阶段就会触发这个对应钩子里的js

1.主要阶段

挂载(初始化相关属性)

beforeCreatecreatedbeforeMountmounted

更新(元素或组件的变更操作)

beforeUpdateupdated

销毁(销毁相关属性)

beforeDestroydestroyed

2.Vue实例的产生过程

  • eforeCreate在实例初始化之后,数据观测和事件配置之前被调用。
  • created在实例创建完成后被立即调用。
  • beforeMount在挂截开始之前被调用。
  • mounted el被新创建的vm.Sel替换,并挂载到实例上去之后调用该钩子。
  • beforeUpdate数据更新时调用,发生在虚拟DOM打补丁之前。
  • updated由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子
  • beforeDestroy实例销毁之前调用。
  • destroyed实例销段后调用。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-biZCGRVM-1620742265770)(Vue全家桶之Vue基础.assets/5.15.png)]

6.综合案例:图书管理

案例:图书管理

Vue全家桶入门基础教程

案例:补充知识

1.数组相关API:变异方法(修改数组)

  • push()
  • pop()末尾删除
  • shift()
  • unshift()
  • splice()删除指定元素
  • sort()排序
  • reverse()

2.数组相关API:替换数组(生成新的数组)

  • filter()
  • concat()
  • slice()从已有的数组中选定元素,返回一个新的数组

3.数组响应式变化:修改响应数据

  • Vue.set(vm.items,indexOfltem,newValue)
  • vm.$set(vm.items,indexOfltem,newValue)

参数一表示要处理的数组名称
参数二表示要处理的数组的索引/对象的属性名
参数三表示要处理的数组的值

1.图书列表

  • 实现静态列表效果
  • 基于数据实现模板效果
  • 处理每行的操作按钮

Vue全家桶入门基础教程

2.添加图书

  • 实现表单的静态效果
  • 添加图书表单域数据绑定
  • 添加按钮事件绑定
  • 实现添加业务逻辑

3.修改图书

  • 修改信息填充到表单
  • 修改后重新提交表单
  • 重用添加和修改的方法

Vue全家桶入门基础教程

4.删除图书

删除按钮绑定事件处理方法

实现删除业务逻辑

Vue全家桶入门基础教程

5.常用特性应用场景

过滤器(格式化日期)自定义指令(获取表单焦点)计算属性(统计图书总数)侦听器(验证图书存在性)生命周期(图书数据处理)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <!-- css样式 -->
  <style type="text/css">
    .grid {
      margin: auto;
      width: 530px;
      text-align: center;
    }

    .grid table {
      border-top: 1px solid #C2D89A;
      width: 100%;
      border-collapse: collapse;
    }

    .grid th,
    td {
      padding: 10;
      border: 1px dashed #F3DCAB;
      height: 35px;
      line-height: 35px;
    }

    .grid th {
      background-color: #F3DCAB;
    }

    .grid .book {
      padding-bottom: 10px;
      padding-top: 5px;
      background-color: #F3DCAB;
    }

    .grid .total {
      height: 30px;
      line-height: 30px;
      background-color: #F3DCAB;
      border-top: 1px solid #C2D89A;
    }
  </style>
</head>

<body>
  <div id="app">
    <div class="grid">
      <div>
        <h1>图书管理</h1>
        <!--二、添加图书 -->
        <div class="book">
          <div>
            <!-- 2.1添加图书表单域数据绑定 -->
            <label for="id">
              编号:
            </label>
            <input type="text" id="id" v-model='id' :disabled="flag" v-focus>
            <label for="name">
              名称:
            </label>
            <input type="text" id="name" v-model='name'>
            <!--2.2添加按钮事件绑定 -->
            <button @click='handle' :disabled="submitFlag">提交</button>
          </div>
        </div>
      </div>
      <div class="total">
        <span>图书总数:</span>
        <span>{{total}}</span>
      </div>
      <!-- 一、图书列表 -->
      <table>
        <thead>
          <tr>
            <th>编号</th>
            <th>名称</th>
            <th>时间</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <!-- 1.1基于数据实现模板效果 -->
          <tr :key='item.id' v-for='item in books'>
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <!-- 调用日期格式化过滤器 -->
            <td>{{item.date | format('yyyy-MM-dd hh:mm:ss')}}</td>
            <td>
              <!-- 1.2处理按钮操作:禁止标签跳转 -->
              <!-- 三、修改图书 -->
              <!-- 3.1修改按钮绑定事件处理方法 -->
              <a href="" @click.prevent='toEdit(item.id)'>修改</a>
              <span>|</span>
              <!-- 四、删除图书 -->
              <!-- 4.1删除按钮绑定事件处理方法 -->
              <a href="" @click.prevent='deleteBook(item.id)'>删除</a>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    // 六、自定义指令(获取表单焦点)
    Vue.directive('focus', {
      inserted: function (el) {
        el.focus();
      }
    });
    // 五、过滤器(格式化日期)
    Vue.filter('format', function (value, arg) {
      function dateFormat(date, format) {
        if (typeof date === "string") {
          var mts = date.match(/(\/Date\((\d+)\)\/)/);
          if (mts && mts.length >= 3) {
            date = parseInt(mts[2]);
          }
        }
        date = new Date(date);
        if (!date || date.toUTCString() == "Invalid Date") {
          return "";
        }
        var map = {
          "M": date.getMonth() + 1, //月份 
          "d": date.getDate(), //日 
          "h": date.getHours(), //小时 
          "m": date.getMinutes(), //分 
          "s": date.getSeconds(), //秒 
          "q": Math.floor((date.getMonth() + 3) / 3), //季度 
          "S": date.getMilliseconds() //毫秒 
        };
        format = format.replace(/([yMdhmsqS])+/g, function (all, t) {
          var v = map[t];
          if (v !== undefined) {
            if (all.length > 1) {
              v = '0' + v;
              v = v.substr(v.length - 2);
            }
            return v;
          } else if (t === 'y') {
            return (date.getFullYear() + '').substr(4 - all.length);
          }
          return all;
        });
        return format;
      }
      return dateFormat(value, arg);
    })
    var vm = new Vue({
      el: '#app',
      data: {
        flag: false,
        submitFlag: false,
        id: '',
        name: '',
        books: []
      },
      methods: {
        handle: function () {
          if (this.flag) {
            // 3.3修改后重新提交表单
            // 就是根据当前的ID去更新数组中对应的数据
            this.books.some((item) => {
              if (item.id == this.id) {
                item.name = this.name;
                // 完成更新操作之后,需要终止循环
                return true;
              }
            });
            //重新提交表单之后把ID放开
            this.flag = false;
          } else {
            // 2.3实现添加业务逻辑
            // 添加图书
            var book = {};
            book.id = this.id;
            book.name = this.name;
            book.date = 2525609975000;
            this.books.push(book);
          }
          // 表单提交后清空表单
          this.id = '';
          this.name = '';
        },
        // 3.2修改按钮事件处理方法
        toEdit: function (id) {
          // 禁止修改ID 根据ID修改数据,一旦改变就无法确认更改那条数据
          this.flag = true;
          console.log(id)
          // 根据ID查询出要编辑的数据
          var book = this.books.filter(function (item) {
            return item.id == id;
          });
          console.log(book)
          // 把获取到的信息填充到表单
          this.id = book[0].id;
          this.name = book[0].name;
        },
        // 4.2删除按钮事件处理方法
        deleteBook: function (id) {
          // 根据id从数组中查找元素的索引
          var index = this.books.findIndex(function (item) {
            return item.id == id;
          });
          // 根据索引删除数组元素 
          // index删除元素的索引 1为删除个数
          this.books.splice(index, 1);
        }
      },
      // 七、计算属性(统计图书总数)
      computed: {
        total: function () {
          return this.books.length;
        }
      },
      // 八、侦听器(验证图书存在性)
      watch: {
        name: function (val) {
          // 验证图书名称是否已经存在
          //some()判断数组中有无满足数据
          var flag = this.books.some(function (item) {
            return item.name == val;
          });
          if (flag) {
            // 图书名称存在 禁用提交按钮
            this.submitFlag = true;
          } else {
            // 图书名称不存在 放开提交按钮,可以提交
            this.submitFlag = false;
          }
        }
      },
      // 九、生命周期(图书数据处理)
      mounted: function () {
        // 该生命周期钩子函数被触发的时候,模板已经可以使用
        // 一般此时用于获取后台数据,然后把数据填充到模板
        var data = [{
          id: 1,
          name: '三国演义',
          date: 2525609975000
        }, {
          id: 2,
          name: '水浒传',
          date: 2525609975000
        }, {
          id: 3,
          name: '红楼梦',
          date: 2525609975000
        }, {
          id: 4,
          name: '西游记',
          date: 2525609975000
        }];
        this.books = data;
      }
    });
  </script>
</body>

</html>

Vue全家桶入门基础教程

以上就是Vue全家桶入门基础教程的详细内容,更多关于Vue全家桶入门的资料请关注三水点靠木其它相关文章!

Vue.js 相关文章推荐
快速解决vue2+vue-cli3项目ie兼容的问题
Nov 17 Vue.js
浅析VUE防抖与节流
Nov 24 Vue.js
vue-cli4.0多环境配置变量与模式详解
Dec 30 Vue.js
vue调用微信JSDK 扫一扫,相册等需要注意的事项
Jan 03 Vue.js
Vuex实现简单购物车
Jan 10 Vue.js
Vue中引入svg图标的两种方式
Jan 14 Vue.js
vue form表单post请求结合Servlet实现文件上传功能
Jan 22 Vue.js
vue登录页实现使用cookie记住7天密码功能的方法
Feb 18 Vue.js
vue实现可移动的悬浮按钮
Mar 04 Vue.js
Vue实现动态查询规则生成组件
May 27 Vue.js
vue-cli4.5.x快速搭建项目
May 30 Vue.js
vue css 相对路径导入问题级踩坑记录
Jun 05 Vue.js
vue实现可拖拽的dialog弹框
vue如何批量引入组件、注册和使用详解
vue组件的路由高亮问题解决方法
Vue通过懒加载提升页面响应速度
Vue详细的入门笔记
如何理解Vue前后端数据交互与显示
Vue实现下拉加载更多
May 09 #Vue.js
You might like
phpstorm编辑器乱码问题解决
2014/12/01 PHP
PHP实现的多文件上传类及用法示例
2016/05/06 PHP
PHP替换Word中变量并导出PDF图片的实现方法
2020/11/26 PHP
js+css使DIV始终居于屏幕中间 左下 左上 右上 右下的代码集合
2011/03/10 Javascript
用jquery实现输入框获取焦点消失文字
2013/04/27 Javascript
js 限制input只能输入数字、字母和汉字等等
2013/12/18 Javascript
JS创建自定义表格具体实现
2014/02/11 Javascript
使用JS画图之点、线、面
2015/01/12 Javascript
JavaScript的React Web库的理念剖析及基础上手指南
2016/05/10 Javascript
js canvas实现擦除动画
2016/07/16 Javascript
jQuery实现table中两列CheckBox只能选中一个的示例
2017/09/22 jQuery
JS去掉字符串末尾的标点符号及删除最后一个字符的方法
2017/10/24 Javascript
jquery实现侧边栏左右伸缩效果的示例
2017/12/19 jQuery
Vue组件库发布到npm详解
2018/02/17 Javascript
微信小程序入门之广告条实现方法示例
2018/12/05 Javascript
js字符串处理之绝妙的代码
2019/04/05 Javascript
解决layui动态添加的元素click等事件触发不了的问题
2019/09/20 Javascript
Angular进行简单单元测试的实现方法实例
2020/08/16 Javascript
[01:45:05]VGJ.T vs Newbee Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
[51:27]LGD vs Liquid 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/19 DOTA
pyramid配置session的方法教程
2013/11/27 Python
使用python将mdb数据库文件导入postgresql数据库示例
2014/02/17 Python
Python去掉字符串中空格的方法
2014/03/11 Python
python里大整数相乘相关技巧指南
2014/09/12 Python
Python线程的两种编程方式
2015/04/14 Python
python写入并获取剪切板内容的实例
2018/05/31 Python
Python常用爬虫代码总结方便查询
2019/02/25 Python
Python3.6+selenium2.53.6自动化测试_读取excel文件的方法
2019/09/06 Python
pycharm激活码快速激活及使用步骤
2020/03/12 Python
Python restful框架接口开发实现
2020/04/13 Python
Python3基于print打印带颜色字符串
2020/07/06 Python
css3编写浏览器背景渐变背景色的方法
2018/03/05 HTML / CSS
婚礼答谢礼品
2015/01/20 职场文书
求职信内容一般写什么?
2015/03/20 职场文书
2015年法制宣传月活动总结
2015/03/26 职场文书
基于PyQt5制作一个群发邮件工具
2022/04/08 Python