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

  • 相关阅读:
    【项目管理和构建】十分钟教程,eclipse配置maven + 创建maven项目(三)
    【项目管理和构建】——Maven下载、安装和配置(二)
    【项目管理和构建】——Maven简介(一)
    Maven 环境变量设置
    【BZOJ282】【洛谷P3829 】【SHOI2012】—信用卡凸包(凸包)
    【BZOJ1076】【SCOI2008】—奖励关(期望+状压dp)
    【BZOJ3687】—简单题(bitset)
    【BZOJ2118】—墨墨的等式(最短路+背包)
    【BZOJ4300】—绝世好题(二进制dp)
    【洛谷P3345】【ZJOI2015】—幻想乡战略游戏(动态点分治)
  • 原文地址:https://www.cnblogs.com/Nicholas0707/p/12700772.html
Copyright © 2011-2022 走看看