横冲直撞vue(第五篇):事件修饰符、指令系统综合案例

一、事件修饰符

在事件处理程序中调用 event.preventDefault()event.stopPropagation()是非常常见的需求。尽管我们可以在 methods 中轻松实现这点,但更好的方式是:methods 只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。在Vue中,事件修饰符处理了许多DOM事件的细节,让我们不再需要花大量的时间去处理这些烦恼的事情,而能有更多的精力专注于程序的逻辑处理。在Vue中事件修饰符主要有:

  • .stop:等同于JavaScript中的event.stopPropagation(),防止事件冒泡

  • .prevent:等同于JavaScript中的event.preventDefault(),防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播)

  • .capture:与事件冒泡的方向相反,事件捕获由外到内

  • .self:只会触发自己范围内的事件,不包含子元素

  • .once:只会触发一次

.stop:防止事件冒泡

 

<div class="inner" @click="div">
    <!-- .stop阻止所有冒泡 -->
    <input type="button" value="挫他" @click.stop="input">
</div>


  methods: {
        div() {
            console.log("A")
        },
        input() {
            console.log("B")
        }
    }

  

 在没有使用.stop的时候,点击div的区域会在控制台输出A,点击按钮的时候会出现B和A(会从内到外触发)。当我们加上.stop的时候相当于在方法中调用了event.stopPropagation(),这样在点击子事件的时候不会触发父节点事件。

 

.prevent阻止触发事件

 

<a href="http://www.baidu.com" @click.prevent="Label">有问题去google</a>


methods: {
                Label() {
                    console.log("触发a标签的点击事件")
                }
            }

  

 

在没有使用.prevent的时候,点击a标签的时候,会先在控制输出console,然后调转到百度网页,使用.prevent的时候相当于调用了event.preventDefault()只会输出console并不会跳装网页

 

.capture 捕获事件,从外到里执行事件

 <div class="inner" @click.capture="div">
           <input type="button" value="挫他" @click="input">
       </div>


methods: {
               div() {
                   console.log("A")
               },
               input() {
                   console.log("B")
               }
           }

  

在没有使用.capture的时候点击input控制台输出的是B和A,使用.capture的时候点击input控制台输出的是A和B。.capture的作用是点击子节点事件的时候,会从父节点依次向当前子节点事件执行。

 

 

.self 只当事件在该元素本身(比如不是子元素)触发时触发回调

 

 <div class="outer" @click="div">
          <div class="inner" @click.self="div1">
              <input type="button" value="戳他" @click="input">
          </div>
      </div>
 


methods: {
              div() {
                  console.log("A")
              },
              input() {
                  console.log("C")
              },
              div1() {
                  console.log("B")
              }
          }

  

 .self只会触发自己范围内的事件,不会包含子元素,点击div1的时候只会出现B和A,不会出现子节点事件。点击按钮的时候只会出现C和A,不会出现B事件

 

 

.once 事件只触发一次

<input type="button" value="戳他" @click.once="input">
 
methods: {
               input() {
                   console.log("A")
               }
           }
 

  

使用.once修饰的只会执行一次,点击多次控制台也只会输出第一次点击的A

 

 

二、综合案例:简易的学生管理

 

用vue做简易的学生管理

效果

 

 

1、基本的页面代码实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="./lib/bootstrap-3.3.7.css">
</head>
<body>
​
    <div id="app">
            <div class="panel panel-primary">
      <div class="panel-heading">
        <h3 class="panel-title">学生管理</h3>
      </div>
      <div class="panel-body form-inline">
        <label>
          Id:
          <input type="text" class="form-control" v-model="id">
        </label>
​
        <label>
          Name:
          <input type="text" class="form-control" v-model="name">
        </label>
​
        <input type="button" value="添加" class="btn btn-primary">
​
        <label>
          搜索名称关键字:
          <!-- 注意: Vue中所有的指令,在调用的时候,都以 v- 开头 -->
          <input type="text" class="form-control" >
        </label>
      </div>
    </div>
        
​
    <table class="table table-bordered table-hover table-striped">
      <thead>
        <tr>
          <th>Id</th>
          <th>名字</th>
          <th>时间</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <!--v-for 中的数据,都是直接从 data 上的list中直接渲染过来的 -->
​
        <tr v-for="item in studentlist" :key="item.id">
          <td>{{ item.id }}</td>
          <td v-text="item.name"></td>
          <td>{{ item.ctime}}</td>
          <td>
            <a href="">删除</a>
          </td>
        </tr>
      </tbody>
    </table>
​
​
    </div>
​
    
    
    <script src="./lib/vue.js"></script>
    <script type="text/javascript">
        
             // 创建 Vue 实例,得到 ViewModel
             var app = new Vue({
                el:'#app',
                data:{
                    id:'',
                    name:'',
                    keywords:'',
                    studentlist:[
                      { id: 1, name: '张三', ctime:'2018-10-01' },
            { id: 2, name: '李四', ctime:'2019-10-01' },
            { id: 3, name: '王五', ctime:'2019-10-03' },
            { id: 4, name: '王六', ctime:'2019-10-07' },
            { id: 5, name: '张二', ctime:'2019-08-03' }
                    ]
                },
                methods:{
                
                }
             })
    </script>
    
</body>
</html>

  

 

2、增加添加学生功能

通过添加按钮添加学生

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="./lib/bootstrap-3.3.7.css">
</head>
<body>
​
    <div id="app">
            <div class="panel panel-primary">
      <div class="panel-heading">
        <h3 class="panel-title">学生管理</h3>
      </div>
      <div class="panel-body form-inline">
        <label>
          Id:
          <input type="text" class="form-control" v-model="id">
        </label>
​
        <label>
          Name:
          <input type="text" class="form-control" v-model="name">
        </label>
​
        <input type="button" value="添加" class="btn btn-primary" @click='add'>
​
        <label>
          搜索名称关键字:
          <!-- 注意: Vue中所有的指令,在调用的时候,都以 v- 开头 -->
          <input type="text" class="form-control" >
        </label>
      </div>
    </div>
        
​
    <table class="table table-bordered table-hover table-striped">
      <thead>
        <tr>
          <th>Id</th>
          <th>名字</th>
          <th>时间</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <!--v-for 中的数据,都是直接从 data 上的list中直接渲染过来的 -->
​
        <tr v-for="item in studentlist" :key="item.id">
          <td>{{ item.id }}</td>
          <td v-text="item.name"></td>
          <td>{{ item.ctime}}</td>
          <td>
            <a href="">删除</a>
          </td>
        </tr>
      </tbody>
    </table>
​
​
    </div>
​
    
    
    <script src="./lib/vue.js"></script>
    <script type="text/javascript">
        
             // 创建 Vue 实例,得到 ViewModel
             var app = new Vue({
                el:'#app',
                data:{
                    id:'',
                    name:'',
                    keywords:'',
                    studentlist:[
                      { id: 1, name: '张三', ctime:'2018-10-01' },
            { id: 2, name: '李四', ctime:'2019-10-01' },
            { id: 3, name: '王五', ctime:'2019-10-03' },
            { id: 4, name: '王六', ctime:'2019-10-07' },
            { id: 5, name: '张二', ctime:'2019-08-03' }
                    ]
                },
                methods:{
                    add(){
                        // 添加的方法
​
                        // 分析:
                        // 1. 获取到 id 和 name ,直接从 data 上面获取 
                        // 2. 组织出一个对象
                        // 3. 把这个对象,调用 数组的 相关方法,添加到 当前 data 上的 list 中
                        // 4. 注意:在Vue中,已经实现了数据的双向绑定,每当我们修改了 data 中的数据,Vue会默认监听到数据的改动,自动把最新的数据,应用到页面上;
​
                        // 5. 当我们意识到上面的第四步的时候,就证明大家已经入门Vue了,我们更多的是在进行 VM中 Model 数据的操作,同时,在操作Model数据的时候,指定的业务逻辑操作;
​
                          var newstudent = {id:this.id,name:this.name,ctime:new Date()}
                          this.studentlist.push(newstudent)
                          this.id = this.name = '' //清空填写框的内容
                    
          }
                }
​
             })
            </script>
</body>
</html>

  

通过键盘enter添加学生

为文本框回车键绑定事件

<input type="text" class="form-control" v-model="name" @keyup.enter="add">

Vue 提供了绝大多数常用的按键码的别名:

  • .enter

  • .tab

  • .delete (捕获“删除”和“退格”键)

  • .esc

  • .space

  • .up

  • .down

  • .left

  • .right

全局 config.keyCodes 对象自定义按键修饰符别名

// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112

代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="./lib/bootstrap-3.3.7.css">
</head>
<body>
​
    <div id="app">
            <div class="panel panel-primary">
      <div class="panel-heading">
        <h3 class="panel-title">学生管理</h3>
      </div>
      <div class="panel-body form-inline">
        <label>
          Id:
          <input type="text" class="form-control" v-model="id">
        </label>
​
        <label>
          Name:
          <input type="text" class="form-control" v-model="name" @keyup.enter="add">
        </label>
​
        <input type="button" value="添加" class="btn btn-primary" @click='add'>
​
        <label>
          搜索名称关键字:
          <!-- 注意: Vue中所有的指令,在调用的时候,都以 v- 开头 -->
          <input type="text" class="form-control" v-model='keywords'>
        </label>
      </div>
    </div>
        
​
    <table class="table table-bordered table-hover table-striped">
      <thead>
        <tr>
          <th>Id</th>
          <th>名字</th>
          <th>时间</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <!-- 之前, v-for 中的数据,都是直接从 data 上的list中直接渲染过来的 -->
        <!-- 现在, 我们自定义了一个 search 方法,同时,把 所有的关键字,通过传参的形式,传递给了 search 方法 -->
        <!-- 在 search 方法内部,通过 执行 for 循环, 把所有符合 搜索关键字的数据,保存到 一个新数组中,返回 -->
        <tr v-for="item in search(keywords)" :key="item.id">
          <td>{{ item.id }}</td>
          <td v-text="item.name"></td>
          <td>{{ item.ctime}}</td>
          <td>
            <a href="" @click.prevent="del(item.id)">删除</a>
          </td>
        </tr>
      </tbody>
    </table>
​
​
    </div>
​
    
    
    <script src="./lib/vue.js"></script>
    <script type="text/javascript">
        
             // 创建 Vue 实例,得到 ViewModel
             var app = new Vue({
                el:'#app',
                data:{
                    id:'',
                    name:'',
                    keywords:'',
                    studentlist:[
                      { id: 1, name: '张三', ctime:'2018-10-01' },
            { id: 2, name: '李四', ctime:'2019-10-01' },
            { id: 3, name: '王五', ctime:'2019-10-03' },
            { id: 4, name: '王六', ctime:'2019-10-07' },
            { id: 5, name: '张二', ctime:'2019-08-03' }
                    ]
                },
                methods: {
​
                    
​
                    add() {
                            // 添加的方法
​
              // 分析:
              // 1. 获取到 id 和 name ,直接从 data 上面获取 
              // 2. 组织出一个对象
              // 3. 把这个对象,调用 数组的 相关方法,添加到 当前 data 上的 list 中
              // 4. 注意:在Vue中,已经实现了数据的双向绑定,每当我们修改了 data 中的数据,Vue会默认监听到数据的改动,自动把最新的数据,应用到页面上;
​
              // 5. 当我们意识到上面的第四步的时候,就证明大家已经入门Vue了,我们更多的是在进行 VM中 Model 数据的操作,同时,在操作Model数据的时候,指定的业务逻辑操作;
​
              var newstudent = {id:this.id,name:this.name,ctime:'2019-11-03'}
              this.studentlist.push(newstudent)
              this.id = this.name = '' //清空填写框的内容
                        
            },
          del(studentid){
​
            // 删除方式一
                    // this.studentlist.some((item,index)=>{
                    //  if(studentid==item.id){
                    //      this.studentlist.splice(index, 1)
                    //      // 在 数组的 some 方法中,如果 return true,就会立即终止这个数组的后续循环
                    //      return true;
                    //  }
                    // })
​
​
                    // 删除方式二
                    var index = this.studentlist.findIndex(item=>{
                        if(item.id==studentid){
                            return true
                        }
                    })
                    
                    this.studentlist.splice(index,1)
​
          },
​
          search(keywords){// 根据关键字,进行数据的搜索
​
                    // 搜索方式一
                    // var newlist = []
                    // this.studentlist.forEach(item=>{
                    //  if(item.name.indexOf(keywords) != -1){
                    //      newlist.push(item)
                    //  }
​
                    // })
                    // return newlist
                    
                    // 注意:  forEach   some   filter   findIndex   这些都属于数组的新方法,
          //  都会对数组中的每一项,进行遍历,执行相关的操作;
​
​
​
                    // 搜索方式二
                     return this.studentlist.filter(item => {
            // if(item.name.indexOf(keywords) != -1)
​
            // 注意 : ES6中,为字符串提供了一个新方法,叫做  String.prototype.includes('要包含的字符串')
            //  如果包含,则返回 true ,否则返回 false
            //  contain
            if (item.name.includes(keywords)) {
              return item
            }
          })
​
​
​
          }
            }
​
        })
    </script>
</body>
</html>

  

 

 

3、增加删除学生的方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="./lib/bootstrap-3.3.7.css">
</head>
<body>
​
    <div id="app">
            <div class="panel panel-primary">
      <div class="panel-heading">
        <h3 class="panel-title">学生管理</h3>
      </div>
      <div class="panel-body form-inline">
        <label>
          Id:
          <input type="text" class="form-control" v-model="id">
        </label>
​
        <label>
          Name:
          <input type="text" class="form-control" v-model="name">
        </label>
​
        <input type="button" value="添加" class="btn btn-primary" @click='add'>
​
        <label>
          搜索名称关键字:
          <!-- 注意: Vue中所有的指令,在调用的时候,都以 v- 开头 -->
          <input type="text" class="form-control" >
        </label>
      </div>
    </div>
        
​
    <table class="table table-bordered table-hover table-striped">
      <thead>
        <tr>
          <th>Id</th>
          <th>名字</th>
          <th>时间</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <!--v-for 中的数据,都是直接从 data 上的list中直接渲染过来的 -->
​
        <tr v-for="item in studentlist" :key="item.id">
          <td>{{ item.id }}</td>
          <td v-text="item.name"></td>
          <td>{{ item.ctime}}</td>
          <td>
            <a href="" @click.prevent="del(item.id)">删除</a>
          </td>
        </tr>
      </tbody>
    </table>
​
​
    </div>
​
    
    
    <script src="./lib/vue.js"></script>
    <script type="text/javascript">
        
             // 创建 Vue 实例,得到 ViewModel
             var app = new Vue({
                el:'#app',
                data:{
                    id:'',
                    name:'',
                    keywords:'',
                    studentlist:[
                      { id: 1, name: '张三', ctime:'2018-10-01' },
            { id: 2, name: '李四', ctime:'2019-10-01' },
            { id: 3, name: '王五', ctime:'2019-10-03' },
            { id: 4, name: '王六', ctime:'2019-10-07' },
            { id: 5, name: '张二', ctime:'2019-08-03' }
                    ]
                },
                methods: {
​
                    
​
                    add() {
                            // 添加的方法
​
              // 分析:
              // 1. 获取到 id 和 name ,直接从 data 上面获取 
              // 2. 组织出一个对象
              // 3. 把这个对象,调用 数组的 相关方法,添加到 当前 data 上的 list 中
              // 4. 注意:在Vue中,已经实现了数据的双向绑定,每当我们修改了 data 中的数据,Vue会默认监听到数据的改动,自动把最新的数据,应用到页面上;
​
              // 5. 当我们意识到上面的第四步的时候,就证明大家已经入门Vue了,我们更多的是在进行 VM中 Model 数据的操作,同时,在操作Model数据的时候,指定的业务逻辑操作;
​
              var newstudent = {id:this.id,name:this.name,ctime:new Date()}
              this.studentlist.push(newstudent)
              this.id = this.name = '' //清空填写框的内容
                        
            },
          del(studentid){
​
            // 删除方式一
                    // this.studentlist.some((item,index)=>{
                    //  if(studentid==item.id){
                    //      this.studentlist.splice(index, 1)
                    //      // 在 数组的 some 方法中,如果 return true,就会立即终止这个数组的后续循环
                    //      return true;
                    //  }
                    // })
​
​
                    // 删除方式二
                    var index = this.studentlist.findIndex(item=>{
                        if(item.id==studentid){
                            return true
                        }
                    })
                    
                    this.studentlist.splice(index,1)
​
          }
            }
​
        })
    </script>
</body>
</html>

  

 

4、增加搜索功能

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="./lib/bootstrap-3.3.7.css">
</head>
<body>
​
    <div id="app">
            <div class="panel panel-primary">
      <div class="panel-heading">
        <h3 class="panel-title">学生管理</h3>
      </div>
      <div class="panel-body form-inline">
        <label>
          Id:
          <input type="text" class="form-control" v-model="id">
        </label>
​
        <label>
          Name:
          <input type="text" class="form-control" v-model="name">
        </label>
​
        <input type="button" value="添加" class="btn btn-primary" @click='add'>
​
        <label>
          搜索名称关键字:
          <!-- 注意: Vue中所有的指令,在调用的时候,都以 v- 开头 -->
          <input type="text" class="form-control" v-model='keywords'>
        </label>
      </div>
    </div>
        
​
    <table class="table table-bordered table-hover table-striped">
      <thead>
        <tr>
          <th>Id</th>
          <th>名字</th>
          <th>时间</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <!-- 之前, v-for 中的数据,都是直接从 data 上的list中直接渲染过来的 -->
        <!-- 现在, 我们自定义了一个 search 方法,同时,把 所有的关键字,通过传参的形式,传递给了 search 方法 -->
        <!-- 在 search 方法内部,通过 执行 for 循环, 把所有符合 搜索关键字的数据,保存到 一个新数组中,返回 -->
        <tr v-for="item in search(keywords)" :key="item.id">
          <td>{{ item.id }}</td>
          <td v-text="item.name"></td>
          <td>{{ item.ctime}}</td>
          <td>
            <a href="" @click.prevent="del(item.id)">删除</a>
          </td>
        </tr>
      </tbody>
    </table>
​
​
    </div>
​
    
    
    <script src="./lib/vue.js"></script>
    <script type="text/javascript">
        
             // 创建 Vue 实例,得到 ViewModel
             var app = new Vue({
                el:'#app',
                data:{
                    id:'',
                    name:'',
                    keywords:'',
                    studentlist:[
                      { id: 1, name: '张三', ctime:'2018-10-01' },
            { id: 2, name: '李四', ctime:'2019-10-01' },
            { id: 3, name: '王五', ctime:'2019-10-03' },
            { id: 4, name: '王六', ctime:'2019-10-07' },
            { id: 5, name: '张二', ctime:'2019-08-03' }
                    ]
                },
                methods: {
​
                    
​
                    add() {
                            // 添加的方法
​
              // 分析:
              // 1. 获取到 id 和 name ,直接从 data 上面获取 
              // 2. 组织出一个对象
              // 3. 把这个对象,调用 数组的 相关方法,添加到 当前 data 上的 list 中
              // 4. 注意:在Vue中,已经实现了数据的双向绑定,每当我们修改了 data 中的数据,Vue会默认监听到数据的改动,自动把最新的数据,应用到页面上;
​
              // 5. 当我们意识到上面的第四步的时候,就证明大家已经入门Vue了,我们更多的是在进行 VM中 Model 数据的操作,同时,在操作Model数据的时候,指定的业务逻辑操作;
​
              var newstudent = {id:this.id,name:this.name,ctime:new Date()}
              this.studentlist.push(newstudent)
              this.id = this.name = '' //清空填写框的内容
                        
            },
          del(studentid){
​
            // 删除方式一
                    // this.studentlist.some((item,index)=>{
                    //  if(studentid==item.id){
                    //      this.studentlist.splice(index, 1)
                    //      // 在 数组的 some 方法中,如果 return true,就会立即终止这个数组的后续循环
                    //      return true;
                    //  }
                    // })
​
​
                    // 删除方式二
                    var index = this.studentlist.findIndex(item=>{
                        if(item.id==studentid){
                            return true
                        }
                    })
                    
                    this.studentlist.splice(index,1)
​
          },
​
          search(keywords){// 根据关键字,进行数据的搜索
​
                    // 搜索方式一
                    // var newlist = []
                    // this.studentlist.forEach(item=>{
                    //  if(item.name.indexOf(keywords) != -1){
                    //      newlist.push(item)
                    //  }
​
                    // })
                    // return newlist
                    
                    // 注意:  forEach   some   filter   findIndex   这些都属于数组的新方法,
          //  都会对数组中的每一项,进行遍历,执行相关的操作;
​
​
​
                    // 搜索方式二
                     return this.studentlist.filter(item => {
            // if(item.name.indexOf(keywords) != -1)
​
            // 注意 : ES6中,为字符串提供了一个新方法,叫做  String.prototype.includes('要包含的字符串')
            //  如果包含,则返回 true ,否则返回 false
            //  contain
            if (item.name.includes(keywords)) {
              return item
            }
          })
​
​
​
          }
            }
​
        })
    </script>
</body>
</html>

  

 

 

 

 

 

 

 

参考资料

[1]https://www.cnblogs.com/yangk1996/p/10844358.html

posted on 2020-04-14 20:02  Nicholas--  阅读(232)  评论(0编辑  收藏  举报

导航