zoukankan      html  css  js  c++  java
  • 横冲直撞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

  • 相关阅读:
    CSS3 target伪类简介
    不用position,让div垂直居中
    css3 在线编辑工具 连兼容都写好了
    a标签伪类的顺序
    oncopy和onpaste
    【leetcode】1523. Count Odd Numbers in an Interval Range
    【leetcode】1518. Water Bottles
    【leetcode】1514. Path with Maximum Probability
    【leetcode】1513. Number of Substrings With Only 1s
    【leetcode】1512. Number of Good Pairs
  • 原文地址:https://www.cnblogs.com/Nicholas0707/p/12700772.html
Copyright © 2011-2022 走看看