乐趣区

关于vue.js:Vue基础学习记录二

Vue 罕用个性

表单基本操作

  • 获取单选框中的值

    • 通过 v -model
       <!-- 
          1、两个单选框须要同时通过 v -model 双向绑定 一个值 
          2、每一个单选框必须要有 value 属性  且 value 值不能一样 
          3、当某一个单选框选中的时候 v-model  会将以后的 value 值 扭转 data 中的 数据
  
          gender 的值就是选中的值,咱们只须要实时监控他的值就能够了
      -->
     <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>
  
  <script>
      new Vue({
           data: {
               // 默认会让以后的 value 值为 2 的单选框选中
                  gender: 2,  
              },
      })
  
  </script>
  • 获取复选框中的值

    • 通过 v -model
    • 和获取单选框中的值一样
    • 复选框 checkbox 这种的组合时 data 中的 hobby 咱们要定义成数组 否则无奈实现多选
      <!-- 
          1、复选框须要同时通过 v -model 双向绑定 一个值 
          2、每一个复选框必须要有 value 属性  且 value 值不能一样 
          3、当某一个单选框选中的时候 v-model  会将以后的 value 值 扭转 data 中的 数据
  
          hobby 的值就是选中的值,咱们只须要实时监控他的值就能够了
      -->
  
  <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>
  <script>
      new Vue({
           data: {
                  // 默认会让以后的 value 值为 2 和 3 的复选框选中
                  hobby: ['2', '3'],
              },
      })
  </script>
  • 获取下拉框和文本框中的值

    • 通过 v -model
     <div>
        <span> 职业:</span>
         <!--
              1、须要给 select  通过 v -model 双向绑定 一个值 
              2、每一个 option  必须要有 value 属性  且 value 值不能一样 
              3、当某一个 option 选中的时候 v-model  会将以后的 value 值 扭转 data 中的 数据
               occupation 的值就是选中的值,咱们只须要实时监控他的值就能够了
          -->
         <!-- multiple  多选 -->
        <select v-model='occupation' multiple>
            <option value="0"> 请抉择职业...</option>
            <option value="1"> 老师 </option>
            <option value="2"> 软件工程师 </option>
            <option value="3"> 律师 </option>
        </select>
           <!-- textarea 是 一个双标签   不须要绑定 value 属性的  -->
          <textarea v-model='desc'></textarea>
    </div>
  <script>
      new Vue({
           data: {
                  // 默认会让以后的 value 值为 2 和 3 的下拉框选中
                   occupation: ['2', '3'],
                    desc: 'nihao'
              },
      })
  </script>

表单修饰符

  • .number 转换为数值

    • 留神点:
    • 当开始输出非数字的字符串时,因为 Vue 无奈将字符串转换成数值
    • 所以属性值将实时更新成雷同的字符串。即便前面输出数字,也将被视作字符串。
  • .trim 主动过滤用户输出的首尾空白字符

    • 只能去掉首尾的 不能去除两头的空格
  • .lazy 将 input 事件切换成 change 事件

    • .lazy 修饰符提早了同步更新属性值的机会。行将本来绑定在 input 事件的同步逻辑转变为绑定在 change 事件上
  • 在失去焦点 或者 按下回车键时才更新

    <!-- 主动将用户的输出值转为数值类型 -->
    <input v-model.number="age" type="number">
    
    <!-- 主动过滤用户输出的首尾空白字符   -->
    <input v-model.trim="msg">
    
    <!-- 在“change”时而非“input”时更新 -->
    <input v-model.lazy="msg" >

自定义指令

  • 内置指令不能满足咱们非凡的需要
  • Vue 容许咱们自定义指令

Vue.directive 注册全局指令

<!-- 
  应用自定义的指令,只需在对用的元素中,加上 'v-' 的前缀造成相似于外部指令 'v-if','v-text' 的模式。-->
<input type="text" v-focus>
<script>
// 留神点://   1、在自定义指令中  如果以驼峰命名的形式定义 如  Vue.directive('focusA',function(){}) 
//   2、在 HTML 中应用的时候 只能通过 v-focus-a 来应用 
    
// 注册一个全局自定义指令 v-focus
Vue.directive('focus', {
      // 当绑定元素插入到 DOM 中。其中 el 为 dom 元素
      inserted: function (el) {
            // 聚焦元素
            el.focus();}
});
new Vue({el:'#app'});
</script>

Vue.directive 注册全局指令 带参数

  <input type="text" v-color='msg'>
 <script type="text/javascript">
    /*
      自定义指令 - 带参数
      bind - 只调用一次,在指令第一次绑定到元素上时候调用

    */
    Vue.directive('color', {
      // bind 申明周期, 只调用一次,指令第一次绑定到元素时调用。在这里能够进行一次性的初始化设置
      // el 为以后自定义指令的 DOM 元素  
      // binding 为自定义的函数形参   通过自定义属性传递过去的值 存在 binding.value 外面
      bind: function(el, binding){
        // 依据指令的参数设置背景色
        // console.log(binding.value.color)
        el.style.backgroundColor = binding.value.color;
      }
    });
    var vm = new Vue({
      el: '#app',
      data: {
        msg: {color: 'blue'}
      }
    });
  </script>

自定义指令部分指令

  • 部分指令,须要定义在 directives 的选项 用法和全局用法一样
  • 部分指令只能在以后组件外面应用
  • 当全局指令和部分指令同名时以部分指令为准
<input type="text" v-color='msg'>
 <input type="text" v-focus>
 <script type="text/javascript">
    /*
      自定义指令 - 部分指令
    */
    var vm = new Vue({
      el: '#app',
      data: {
        msg: {color: 'red'}
      },
         // 部分指令,须要定义在  directives 的选项
      directives: {
        color: {bind: function(el, binding){el.style.backgroundColor = binding.value.color;}
        },
        focus: {inserted: function(el) {el.focus();
          }
        }
      }
    });
  </script>

计算属性 computed

  • 模板中放入太多的逻辑会让模板过重且难以保护 应用计算属性能够让模板更加的简洁
  • 计算属性是基于它们的响应式依赖进行缓存的
  • computed 比拟适宜对多个变量或者对象进行解决后返回一个后果值,也就是数多个变量中的某一个值产生了变动则咱们监控的这个值也就会发生变化
 <div id="app">
     <!--  
        当屡次调用 reverseString  的时候 
        只有外面的 num 值不扭转 他会把第一次计算的后果间接返回
        直到 data 中的 num 值扭转 计算属性才会从新产生计算
     -->
    <div>{{reverseString}}</div>
    <div>{{reverseString}}</div>
     <!-- 调用 methods 中的办法的时候  他每次会从新调用 -->
    <div>{{reverseMessage()}}</div>
    <div>{{reverseMessage()}}</div>
  </div>
  <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  属性 定义 和 data 曾经 methods 平级 
      computed: {
        //  reverseString   这个是咱们本人定义的名字 
        reverseString: function(){console.log('computed')
          var total = 0;
          //  当 data 中的 num 的值扭转的时候  reverseString  会主动产生计算  
          for(var i=0;i<=this.num;i++){total += i;}
          // 这里肯定要有 return 否则 调用 reverseString 的 时候无奈拿到后果    
          return total;
        }
      }
    });
  </script>

侦听器 watch

  • 应用 watch 来响应数据的变动
  • 个别用于异步或者开销较大的操作
  • watch 中的属性 肯定是 data 中 曾经存在的数据
  • 当须要监听一个对象的扭转时,一般的 watch 办法无奈监听到对象外部属性的扭转,只有 data 中的数据才可能监听到变动,此时就须要 deep 属性对对象进行深度监听
 <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">
        /*
              侦听器
            */
        var vm = new Vue({
            el: '#app',
            data: {
                firstName: 'Jim',
                lastName: 'Green',
                // fullName: 'Jim Green'
            },
             //watch  属性 定义 和 data 曾经 methods 平级 
            watch: {
                //   留神:这里 firstName  对应着 data 中的 firstName 
                //   当 firstName 值 扭转的时候  会主动触发 watch
                firstName: function(val) {this.fullName = val + ' ' + this.lastName;},
                //   留神:这里 lastName 对应着 data 中的 lastName 
                lastName: function(val) {this.fullName = this.firstName + ' ' + val;}
            }
        });
    </script>

过滤器

  • Vue.js 容许自定义过滤器,可被用于一些常见的文本格式化。
  • 过滤器能够用在两个中央:双花括号插值和 v -bind 表达式。
  • 过滤器应该被增加在 JavaScript 表达式的尾部,由“管道”符号批示
  • 反对级联操作
  • 过滤器不扭转真正的 data,而只是扭转渲染的后果,并返回过滤后的版本
  • 全局注册时是 filter,没有 s 的。而部分过滤器是 filters,是有 s 的
  <div id="app">
    <input type="text" v-model='msg'>
      <!-- upper 被定义为接管单个参数的过滤器函数,表达式  msg  的值将作为参数传入到函数中 -->
    <div>{{msg | upper}}</div>
    <!--  
      反对级联操作
      upper  被定义为接管单个参数的过滤器函数,表达式 msg 的值将作为参数传入到函数中。而后持续调用同样被定义为接管单个参数的过滤器 lower,将 upper 的后果传递到 lower 中
     -->
    <div>{{msg | upper | lower}}</div>
    <div :abc='msg | upper'> 测试数据 </div>
  </div>

<script type="text/javascript">
   //  lower  为全局过滤器     
   Vue.filter('lower', function(val) {return val.charAt(0).toLowerCase() + val.slice(1);
    });
    var vm = new Vue({
      el: '#app',
      data: {msg: ''},
       //filters  属性 定义 和 data 曾经 methods 平级 
       //  定义 filters 中的过滤器为部分过滤器 
      filters: {
        //   upper  自定义的过滤器名字 
        //    upper 被定义为接管单个参数的过滤器函数,表达式  msg  的值将作为参数传入到函数中
        upper: function(val) {
         //  过滤器中肯定要有返回值 这样外界应用过滤器的时候能力拿到后果
          return val.charAt(0).toUpperCase() + val.slice(1);
        }
      }
    });
  </script>

过滤器中传递参数

    <div id="box">
        <!--
            filterA 被定义为接管三个参数的过滤器函数。其中 message 的值作为第一个参数,一般字符串 'arg1' 作为第二个参数,表达式 arg2 的值作为第三个参数。-->
        {{message | filterA('arg1', 'arg2') }}
    </div>
    <script>
        // 在过滤器中 第一个参数 对应的是  管道符后面的数据   n  此时对应 message
        // 第 2 个参数  a 对应 实参  arg1 字符串
        // 第 3 个参数  b 对应 实参  arg2 字符串
        Vue.filter('filterA',function(n,a,b){if(n<10){return n+a;}else{return n+b;}
        });
        
        new Vue({
            el:"#box",
            data:{message: "哈哈哈"}
        })

    </script>

生命周期

  • 事物从出世到死亡的过程
  • Vue 实例从创立 到销毁的过程,这些过程中会随同着一些函数的自调用。咱们称这些函数为钩子函数

    挂载(初始化相干属性)
    ① beforeCreate
    ② created
    ③ beforeMount
    ④ mounted
    更新(元素或组件的变更操作)
    ① beforeUpdate
    ② updated
    销毁(销毁相干属性)
    ① beforeDestroy
    ② destroyed

罕用的 钩子函数

beforeCreate 在实例初始化之后,数据观测和事件配置之前被调用 此时 data 和 methods 以及页面的 DOM 构造都没有初始化 什么都做不了
created 在实例创立实现后被立刻调用此时 data 和 methods 曾经能够应用 然而页面还没有渲染进去
beforeMount 在挂载开始之前被调用 此时页面上还看不到实在数据 只是一个模板页面而已
mounted el 被新创建的 vm.$el 替换,并挂载到实例下来之后调用该钩子。数据曾经实在渲染到页面上 在这个钩子函数外面咱们能够应用一些第三方的插件
beforeUpdate 数据更新时调用,产生在虚构 DOM 打补丁之前。页面上数据还是旧的
updated 因为数据更改导致的虚构 DOM 从新渲染和打补丁,在这之后会调用该钩子。页面上数据曾经替换成最新的
beforeDestroy 实例销毁之前调用
destroyed 实例销毁后调用

数组变异办法

  • 在 Vue 中,间接批改对象属性的值无奈触发响应式。当你间接批改了对象属性的值,你会发现,只有数据改了,然而页面内容并没有扭转
  • 变异数组办法即放弃数组办法原有性能不变的前提下对其进行性能拓展
push() 往数组最初面增加一个元素,胜利返回以后数组的长度
pop() 删除数组的最初一个元素,胜利返回删除元素的值
shift() 删除数组的第一个元素,胜利返回删除元素的值
unshift() 往数组最后面增加一个元素,胜利返回以后数组的长度
splice() 有三个参数,第一个是想要删除的元素的下标(必选),第二个是想要删除的个数(必选),第三个是删除 后想要在原地位替换的值
sort() sort() 使数组依照字符编码默认从小到大排序, 胜利返回排序后的数组
reverse() reverse() 将数组倒序,胜利返回倒序后的数组

替换数组

  • 不会扭转原始数组,但总是返回一个新数组
filter filter() 办法创立一个新的数组,新数组中的元素是通过查看指定数组中符合条件的所有元素。
concat concat() 办法用于连贯两个或多个数组。该办法不会扭转现有的数组
slice slice() 办法可从已有的数组中返回选定的元素。该办法并不会批改数组,而是返回一个子数组

动静数组响应式数据

  • Vue.set 让触发视图从新更新一遍,数据动静起来
    Vue.set(vm.items, indexOfItem, newValue)
    vm.$set(vm.items, indexOfItem, newValue)
    ① 参数一示意要解决的数组 / 对象名称
    ② 参数二示意要解决的数组 / 对象的索引
    ③ 参数三示意要解决的数组 / 对象的值
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <ul>
      <li v-for='item in list'>{{item}}</li>
    </ul>
    <div>
      <div>{{info.name}}</div>
      <div>{{info.age}}</div>
      <div>{{info.gender}}</div>
    </div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      动静解决响应式数据
      
    */
    var vm = new Vue({
      el: '#app',
      data: {list: ['apple', 'orange', 'banana'],
        info: {
          name: 'lisi',
          age: 12
        }
      },
    });
    // vm.list[1] = 'lemon';
    // Vue.set(vm.list, 2, 'lemon');
    vm.$set(vm.list, 1, 'lemon');

    // vm.info.gender = 'male';
    vm.$set(vm.info, 'gender', 'female');

    
  </script>
</body>
</html>

图书列表案例

  • 动态列表成果
  • 基于数据实现模板成果
  • 解决每行的操作按钮

1、提供的静态数据

  • 数据寄存在 vue 中 data 属性中
 var vm = new Vue({
      el: '#app',
      data: {
        books: [{
          id: 1,
          name: '三国演义',
          date: ''
        },{
          id: 2,
          name: '水浒传',
          date: ''
        },{
          id: 3,
          name: '红楼梦',
          date: ''
        },{
          id: 4,
          name: '西游记',
          date: ''
        }]
      }
    }); var vm = new Vue({
      el: '#app',
      data: {
        books: [{
          id: 1,
          name: '三国演义',
          date: ''
        },{
          id: 2,
          name: '水浒传',
          date: ''
        },{
          id: 3,
          name: '红楼梦',
          date: ''
        },{
          id: 4,
          name: '西游记',
          date: ''
        }]
      }
    });

2、把提供好的数据渲染到页面上

  • 利用 v-for 循环 遍历 books 将每一项数据渲染到对应的数据中
 <tbody>
    <tr :key='item.id' v-for='item in books'>
       <!-- 对应的 id 渲染到页面上 -->
       <td>{{item.id}}</td>
        <!-- 对应的 name 渲染到页面上 -->
       <td>{{item.name}}</td>
       <td>{{item.date}}</td>
       <td>
         <!-- 阻止 a 标签的默认跳转 -->
         <a href="" @click.prevent> 批改 </a>
         <span>|</span>
             <a href="" @click.prevent> 删除 </a>
       </td>
     </tr>
</tbody>

3、增加图书

  • 通过双向绑定获取到输入框中的输出内容
  • 给按钮增加点击事件
  • 把输入框中的数据存储到 data 中的 books 外面
<div>
  <h1> 图书治理 </h1>
  <div class="book">
       <div>
         <label for="id">
           编号:</label>
          <!-- 3.1、通过双向绑定获取到输入框中的输出的 id  -->
         <input type="text" id="id" v-model='id'>
         <label for="name">
           名称:</label>
           <!-- 3.2、通过双向绑定获取到输入框中的输出的 name  -->
         <input type="text" id="name" v-model='name'>
            <!-- 3.3、给按钮增加点击事件  -->
         <button @click='handle'> 提交 </button>
       </div>
  </div>
</div>
  <script type="text/javascript">
    /*
      图书治理 - 增加图书
    */
    var vm = new Vue({
      el: '#app',
      data: {
        id: '',
        name: '',
        books: [{
          id: 1,
          name: '三国演义',
          date: ''
        },{
          id: 2,
          name: '水浒传',
          date: ''
        },{
          id: 3,
          name: '红楼梦',
          date: ''
        },{
          id: 4,
          name: '西游记',
          date: ''
        }]
      },
      methods: {handle: function(){
          // 3.4 定义一个新的对象 book 存储 获取到输入框中 书 的 id 和名字 
          var book = {};
          book.id = this.id;
          book.name = this.name;
          book.date = '';
         // 3.5 把 book  通过数组的变异办法 push 放到    books 外面
          this.books.push(book);
          //3.6 清空输入框
          this.id = '';
          this.name = '';
        }
      }
    });
  </script>

4 批改图书 - 上

  • 点击批改按钮的时候 获取到要批改的书籍名单

    • 4.1 给批改按钮增加点击事件,须要把以后的图书的 id 传递过来 这样才晓得须要批改的是哪一本书籍
  • 把须要批改的书籍名单填充到表单外面

    • 4.2 依据传递过去的 id 查出 books 中 对应书籍的详细信息
    • 4.3 把获取到的信息填充到表单
 <div id="app">
    <div class="grid">
      <div>
        <h1> 图书治理 </h1>
        <div class="book">
          <div>
            <label for="id">
              编号:</label>
            <input type="text" id="id" v-model='id' :disabled="flag">
            <label for="name">
              名称:</label>
            <input type="text" id="name" v-model='name'>
            <button @click='handle'> 提交 </button>
          </div>
        </div>
      </div>
      <table>
        <thead>
          <tr>
            <th> 编号 </th>
            <th> 名称 </th>
            <th> 工夫 </th>
            <th> 操作 </th>
          </tr>
        </thead>
        <tbody>
          <tr :key='item.id' v-for='item in books'>
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.date}}</td>
            <td>
              <!--- 
                4.1  给批改按钮增加点击事件,须要把以后的图书的 id 传递过来 
                这样才晓得须要批改的是哪一本书籍
                  --->  
              <a href=""@click.prevent='toEdit(item.id)'> 批改 </a>
              <span>|</span>
              <a href="" @click.prevent> 删除 </a>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
 <script type="text/javascript">
    /*
      图书治理 - 增加图书
    */
    var vm = new Vue({
      el: '#app',
      data: {
        flag: false,
        id: '',
        name: '',
        books: [{
          id: 1,
          name: '三国演义',
          date: ''
        },{
          id: 2,
          name: '水浒传',
          date: ''
        },{
          id: 3,
          name: '红楼梦',
          date: ''
        },{
          id: 4,
          name: '西游记',
          date: ''
        }]
      },
      methods: {handle: function(){
          // 3.4 定义一个新的对象 book 存储 获取到输入框中 书 的 id 和名字 
          var book = {};
          book.id = this.id;
          book.name = this.name;
          book.date = '';
         // 3.5 把 book  通过数组的变异办法 push 放到    books 外面
          this.books.push(book);
          //3.6 清空输入框
          this.id = '';
          this.name = '';
        },
        toEdit: function(id){console.log(id)
          //4.2  依据传递过去的 id 查出 books 中 对应书籍的详细信息
          var book = this.books.filter(function(item){return item.id == id;});
          console.log(book)
          //4.3 把获取到的信息填充到表单
          // this.id   和  this.name 通过双向绑定 绑定到了表单中  一旦数据扭转视图自动更新
          this.id = book[0].id;
          this.name = book[0].name;
        }
      }
    });
  </script>

5 批改图书 - 下

  • 5.1 定义一个标识符,次要是管制 编辑状态下以后编辑书籍的 id 不能被批改 即 处于编辑状态下 以后管制书籍编号的输入框禁用
  • 5.2 通过属性绑定给书籍编号的 绑定 disabled 的属性 flag 为 true 即为禁用
  • 5.3 flag 默认值为 false 处于编辑状态 要把 flag 改为 true 即以后表单为禁用
  • 5.4 复用增加办法 用户点击提交的时候仍然执行 handle 中的逻辑如果 flag 为 true 即 表单处于不可输出状态 此时执行的用户编辑数据数据
<div id="app">
    <div class="grid">
      <div>
        <h1> 图书治理 </h1>
        <div class="book">
          <div>
            <label for="id">
              编号:</label>
              <!-- 5.2 通过属性绑定 绑定 disabled 的属性  flag 为 true 即为禁用      -->
            <input type="text" id="id" v-model='id' :disabled="flag">
            <label for="name">
              名称:</label>
            <input type="text" id="name" v-model='name'>
            <button @click='handle'> 提交 </button>
          </div>
        </div>
      </div>
      <table>
        <thead>
          <tr>
            <th> 编号 </th>
            <th> 名称 </th>
            <th> 工夫 </th>
            <th> 操作 </th>
          </tr>
        </thead>
        <tbody>
          <tr :key='item.id' v-for='item in books'>
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.date}}</td>
            <td>
              <a href=""@click.prevent='toEdit(item.id)'> 批改 </a>
              <span>|</span>
              <a href="" @click.prevent> 删除 </a>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>   
<script type="text/javascript">
        /* 图书治理 - 增加图书 */
        var vm = new Vue({
            el: '#app',
            data: {
                // 5.1  定义一个标识符,次要是管制 编辑状态下以后编辑书籍的 id 不能被批改 
                // 即 处于编辑状态下 以后管制书籍编号的输入框禁用 
                flag: false,
                id: '',
                name: '',
              
            },
            methods: {handle: function() {
                   /*
                     5.4  复用增加办法   用户点击提交的时候仍然执行 handle 中的逻辑
                          如果 flag 为 true 即 表单处于不可输出状态 此时执行的用户编辑数据数据    
                   */ 
                    if (this.flag) {
                        // 编辑图书
                        // 5.5  依据以后的 ID 去更新数组中对应的数据  
                        this.books.some((item) => {if (item.id == this.id) {
                                // 箭头函数中 this 指向父级作用域的 this 
                                item.name = this.name;
                                // 实现更新操作之后,须要终止循环
                                return true;
                            }
                        });
                        // 5.6 编辑完数据后表单要处以能够输出的状态
                        this.flag = false;
                    //  5.7  如果 flag 为 false  表单处于输出状态 此时执行的用户增加数据    
                    } else {var book = {};
                        book.id = this.id;
                        book.name = this.name;
                        book.date = '';
                        this.books.push(book);
                        // 清空表单
                        this.id = '';
                        this.name = '';
                    }
                    // 清空表单
                    this.id = '';
                    this.name = '';
                },
                toEdit: function(id) {
                     /*
                     5.3  flag 默认值为 false   处于编辑状态 要把 flag 改为 true 即以后表单为禁                      用 
                     */ 
                    this.flag = true;
                    console.log(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;
                }
            }
        });
    </script>

6 删除图书

  • 6.1 给删除按钮增加事件 把以后须要删除的书籍 id 传递过去
  • 6.2 依据 id 从数组中查找元素的索引
  • 6.3 依据索引删除数组元素
  <tbody>
          <tr :key='item.id' v-for='item in books'>
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.date}}</td>
            <td>
              <a href=""@click.prevent='toEdit(item.id)'> 批改 </a>
              <span>|</span>
               <!--  6.1 给删除按钮增加事件 把以后须要删除的书籍 id 传递过去  --> 
              <a href=""@click.prevent='deleteBook(item.id)'> 删除 </a>
            </td>
          </tr>
</tbody>
  <script type="text/javascript">
    /*
      图书治理 - 增加图书
    */
    var vm = new Vue({
      methods: {deleteBook: function(id){
          // 删除图书
          #// 6.2 依据 id 从数组中查找元素的索引
          // var index = this.books.findIndex(function(item){
          //   return item.id == id;
          // });
          #// 6.3 依据索引删除数组元素
          // this.books.splice(index, 1);
          // -------------------------
         #// 办法二:通过 filter 办法进行删除
        
          # 6.4  依据 filter 办法 过滤出来 id 不是要删除书籍的 id 
          # 因为 filter 是替换数组不会批改原始数据 所以须要 把 不是要删除书籍的 id  赋值给 books 
          this.books = this.books.filter(function(item){return item.id != id;});
        }
      }
    });
  </script>

罕用个性利用场景

1 过滤器

  • Vue.filter 定义一个全局过滤器
 <tr :key='item.id' v-for='item in books'>
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
             <!-- 1.3  调用过滤器 -->
            <td>{{item.date | format('yyyy-MM-dd hh:mm:ss')}}</td>
            <td>
              <a href=""@click.prevent='toEdit(item.id)'> 批改 </a>
              <span>|</span>
              <a href=""@click.prevent='deleteBook(item.id)'> 删除 </a>
            </td>
</tr>

<script>
        #1.1  Vue.filter  定义一个全局过滤器
        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);
            })
#1.2  提供的数据 蕴含一个工夫戳   为毫秒数
   [{
          id: 1,
          name: '三国演义',
          date: 2525609975000
        },{
          id: 2,
          name: '水浒传',
          date: 2525609975000
        },{
          id: 3,
          name: '红楼梦',
          date: 2525609975000
        },{
          id: 4,
          name: '西游记',
          date: 2525609975000
        }];
</script>

2 自定义指令

  • 让表单主动获取焦点
  • 通过 Vue.directive 自定义指定
<!-- 2.2  通过 v - 自定义属性名 调用自定义指令 -->
<input type="text" id="id" v-model='id' :disabled="flag" v-focus>

<script>
    # 2.1   通过 Vue.directive 自定义指定
    Vue.directive('focus', {inserted: function (el) {el.focus();
      }
    });

</script>

3 计算属性

  • 通过计算属性计算图书的总数

    • 图书的总数就是计算数组的长度
 <div class="total">
        <span> 图书总数:</span>
         <!-- 3.2 在页面上 展现进去 -->
        <span>{{total}}</span>
</div>

  <script type="text/javascript">
    /*
      计算属性与办法的区别: 计算属性是基于依赖进行缓存的,而办法不缓存
    */
    var vm = new Vue({
      data: {
        flag: false,
        submitFlag: false,
        id: '',
        name: '',
        books: []},
      computed: {total: function(){
          // 3.1  计算图书的总数
          return this.books.length;
        }
      },
    });
  </script>

生命周期

退出移动版