zoukankan      html  css  js  c++  java
  • vue2 学习笔记2

    文中例子代码请参考github

    品牌管理案例

    添加新品牌

    <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>
    
            <!-- 在Vue中,使用事件绑定机制,为元素指定处理函数的时候,如果加了小括号,就可以给函数传参了 -->
            <input type="button" value="添加" class="btn btn-primary" @click="add()">
          </div>
        </div>
    
        <table class="table table-bordered table-hover table-striped">
          <thead>
            <tr>
              <th>Id</th>
              <th>Name</th>
              <th>Ctime</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="item in list" :key="item.id">
              <td>{{ item.id }}</td>
              <td v-text="item.name"></td>
              <td>{{ item.ctime }}</td>
            </tr>
          </tbody>
        </table>
      </div>
    
      <script>
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
          el: '#app',
          data: {
            id: '',
            name: '',
            keywords: '', // 搜索的关键字
            list: [
              { id: 1, name: '奔驰', ctime: new Date() },
              { id: 2, name: '宝马', ctime: new Date() }
            ]
          },
          methods: {
            add() { // 添加的方法
              // console.log('ok')
              // 分析:
              // 1. 获取到 id 和 name ,直接从 data 上面获取
              // 2. 组织出一个对象
              // 3. 把这个对象,调用 数组的 相关方法,添加到 当前 data 上的 list 中
              // 4. 注意:在Vue中,已经实现了数据的双向绑定,每当我们修改了 data 中的数据,Vue会默认监听到数据的改动,自动把最新的数据,应用到页面上;
    
              // 5. 当我们意识到上面的第四步的时候,就证明大家已经入门Vue了,我们更多的是在进行 VM中 Model 数据的操作,同时,在操作Model数据的时候,指定的业务逻辑操作;
    
              var car = { id: this.id, name: this.name, ctime: new Date() }
              this.list.push(car)
              this.id = this.name = ''
            }
          }
        });
      </script>
    </body>
    

    删除品牌

    <body>
      <div id="app">
        <table class="table table-bordered table-hover table-striped">
          <thead>
            <tr>
              <th>Id</th>
              <th>Name</th>
              <th>Ctime</th>
              <th>Operation</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="item in list" :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>
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
          el: '#app',
          data: {
            id: '',
            name: '',
            keywords: '', // 搜索的关键字
            list: [
              { id: 1, name: '奔驰', ctime: new Date() },
              { id: 2, name: '宝马', ctime: new Date() }
            ]
          },
          methods: {
            del(id) { // 根据Id删除数据
              // 分析:
              // 1. 如何根据Id,找到要删除这一项的索引
              // 2. 如果找到索引了,直接调用 数组的 splice 方法
    
              /*第一种实现方式*/
              /* this.list.some((item, i) => {
                if (item.id == id) {
                  this.list.splice(i, 1)
                  // 在 数组的 some 方法中,如果 return true,就会立即终止这个数组的后续循环
                  return true;
                }
              }) */
    
              /*第二种实现方式*/
              var index = this.list.findIndex(item => {
                if (item.id == id) {
                  return true;
                }
              })
              this.list.splice(index, 1)
            }
          }
        });
      </script>
    </body>
    

    根据条件筛选品牌

    1. 1.x 版本中的filterBy指令,在2.x中已经被废除:

    filterBy - 指令

    
    <tr v-for="item in list | filterBy searchName in 'name'">
    
      <td>{{item.id}}</td>
    
      <td>{{item.name}}</td>
    
      <td>{{item.ctime}}</td>
    
      <td>
    
        <a href="#" @click.prevent="del(item.id)">删除</a>
    
      </td>
    
    </tr>
    
    
    1. 在2.x版本中手动实现筛选的方式
    • 筛选框绑定到 VM 实例中的 searchName 属性:
    
    <hr> 输入筛选名称:
    
    <input type="text" v-model="searchName">
    
    
    • 在使用 v-for 指令循环每一行数据的时候,不再直接 item in list,而是 in 一个 过滤的methods 方法,同时,把过滤条件searchName传递进去:
    
    <tbody>
    
          <tr v-for="item in search(searchName)">
    
            <td>{{item.id}}</td>
    
            <td>{{item.name}}</td>
    
            <td>{{item.ctime}}</td>
    
            <td>
    
              <a href="#" @click.prevent="del(item.id)">删除</a>
    
            </td>
    
          </tr>
    
        </tbody>
    
    
    • search 过滤方法中,使用 数组的 filter 方法进行过滤:
    
    search(name) {
    
      return this.list.filter(x => {
    
        return x.name.indexOf(name) != -1;
    
      });
    
    }
    
    

    Vue调试工具vue-devtools的安装步骤和使用

    过滤器

    概念:Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示;

    私有过滤器

    1. HTML元素:
    
    <td>{{item.ctime | dataFormat('yyyy-mm-dd')}}</td>
    
    
    1. 私有 filters 定义方式:
    
    filters: { // 私有局部过滤器,只能在 当前 VM 对象所控制的 View 区域进行使用
    
        dataFormat(input, pattern = "") { // 在参数列表中 通过 pattern="" 来指定形参默认值,防止报错
    
          var dt = new Date(input);
    
          // 获取年月日
    
          var y = dt.getFullYear();
    
          var m = (dt.getMonth() + 1).toString().padStart(2, '0');
    
          var d = dt.getDate().toString().padStart(2, '0');
    
    
    
          // 如果 传递进来的字符串类型,转为小写之后,等于 yyyy-mm-dd,那么就返回 年-月-日
    
          // 否则,就返回  年-月-日 时:分:秒
    
          if (pattern.toLowerCase() === 'yyyy-mm-dd') {
    
            return `${y}-${m}-${d}`;
    
          } else {
    
            // 获取时分秒
    
            var hh = dt.getHours().toString().padStart(2, '0');
    
            var mm = dt.getMinutes().toString().padStart(2, '0');
    
            var ss = dt.getSeconds().toString().padStart(2, '0');
    
    
    
            return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
    
          }
    
        }
    
      }
    
    

    使用ES6中的字符串新方法 String.prototype.padStart(maxLength, fillString='') 或 String.prototype.padEnd(maxLength, fillString='')来填充字符串;

    全局过滤器

    
    // 定义一个全局过滤器
    
    Vue.filter('dataFormat', function (input, pattern = '') {
    
      var dt = new Date(input);
    
      // 获取年月日
    
      var y = dt.getFullYear();
    
      var m = (dt.getMonth() + 1).toString().padStart(2, '0');
    
      var d = dt.getDate().toString().padStart(2, '0');
    
    
    
      // 如果 传递进来的字符串类型,转为小写之后,等于 yyyy-mm-dd,那么就返回 年-月-日
    
      // 否则,就返回  年-月-日 时:分:秒
    
      if (pattern.toLowerCase() === 'yyyy-mm-dd') {
    
        return `${y}-${m}-${d}`;
    
      } else {
    
        // 获取时分秒
    
        var hh = dt.getHours().toString().padStart(2, '0');
    
        var mm = dt.getMinutes().toString().padStart(2, '0');
    
        var ss = dt.getSeconds().toString().padStart(2, '0');
    
    
    
        return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
    
      }
    
    });
    
    

    注意:当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!

    键盘修饰符以及自定义键盘修饰符

    系统内置了一些键盘码,例如enter ,如果不够用可以自定义键盘修饰符,参考文档末尾:js 里面的键盘事件对应的键码。

    1.x中自定义键盘修饰符【了解即可】

    
    Vue.directive('on').keyCodes.f2 = 113;
    
    

    2.x中自定义键盘修饰符

    1. 通过Vue.config.keyCodes.名称 = 按键值来自定义案件修饰符的别名:
    
    Vue.config.keyCodes.f2 = 113;
    
    
    1. 使用自定义的按键修饰符:
    
    <input type="text" v-model="name" @keyup.f2="add">
    
    

    自定义指令

    1. 自定义全局和局部的 自定义指令:
    
        // 自定义全局指令 v-focus,为绑定的元素自动获取焦点:
    
        Vue.directive('focus', {
    
          inserted: function (el) { // inserted 表示被绑定元素插入父节点时调用
    
            el.focus();
    
          }
    
        });
    
    
    
        // 自定义局部指令 v-color 和 v-font-weight,为绑定的元素设置指定的字体颜色 和 字体粗细:
    
          directives: {
    
            color: { // 为元素设置指定的字体颜色
    
              bind(el, binding) {
    
                el.style.color = binding.value;
    
              }
    
            },
    
            'font-weight': function (el, binding2) { // 自定义指令的简写形式,等同于定义了 bind 和 update 两个钩子函数
    
              el.style.fontWeight = binding2.value;
    
            }
    
          }
    
    
    1. 自定义指令的使用方式:
    
    <input type="text" v-model="searchName" v-focus v-color="'red'" v-font-weight="900">
    
    

    实例

    <body>
      <div id="app">
        <div class="panel panel-primary">
          <div class="panel-body form-inline">
            <label>
              搜索名称关键字:
              <!-- 注意: Vue中所有的指令,在调用的时候,都以 v- 开头 -->
              <input type="text" class="form-control" v-model="keywords" id="search" v-focus v-color="'green'">
            </label>
          </div>
        </div>
      </div>
    
      <div id="app2">
        <h3 v-color="'pink'" v-fontweight="900" v-fontsize="50">{{ msg }}</h3>
      </div>
    
      <script>
        // 使用  Vue.directive() 定义全局的指令  v-focus
        // 其中:参数1 : 指令的名称,注意,在定义的时候,指令的名称前面,不需要加 v- 前缀, 
        // 但是: 在调用的时候,必须 在指令名称前 加上 v- 前缀来进行调用
        //  参数2: 是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作
        Vue.directive('focus', {
          bind: function (el) { // 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次
            // 注意: 在每个 函数中,第一个参数,永远是 el ,表示 被绑定了指令的那个元素,这个 el 参数,是一个原生的JS对象
            // 在元素 刚绑定了指令的时候,还没有 插入到 DOM中去,这时候,调用 focus 方法没有作用
            //  因为,一个元素,只有插入DOM之后,才能获取焦点
            // el.focus()
          },
          inserted: function (el) {  // inserted 表示元素 插入到DOM中的时候,会执行 inserted 函数【触发1次】
            el.focus()
            // 和JS行为有关的操作,最好在 inserted 中去执行,放置 JS行为不生效
          },
          updated: function (el) {  // 当VNode更新的时候,会执行 updated, 可能会触发多次
    
          }
        })
    
        // 自定义一个 设置字体颜色的 指令
        Vue.directive('color', {
          // 样式,只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联的样式
          // 将来元素肯定会显示到页面中,这时候,浏览器的渲染引擎必然会解析样式,应用给这个元素
          bind: function (el, binding) {
            // el.style.color = 'red'
            // console.log(binding.name)
            // 和样式相关的操作,一般都可以在 bind 执行
    
            // console.log(binding.value)
            // console.log(binding.expression)
    
            el.style.color = binding.value
          }
        })
    
    
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
          el: '#app',
          data: {
            keywords: '', // 搜索的关键字
          }
        });
    
        // 如何自定义一个私有的过滤器(局部)
        var vm2 = new Vue({
          el: '#app2',
          data: {
              msg: '自定义指令学习。。。',
          },
          directives: { // 自定义私有指令
            'fontweight': { // 设置字体粗细的
              bind: function (el, binding) {
                el.style.fontWeight = binding.value
              }
            },
            'fontsize': function (el, binding) { // 注意:这个 function 等同于 把 代码写到了 bind 和 update 中去
              el.style.fontSize = parseInt(binding.value) + 'px'
            }
          }
        })
    
        // document.getElementById('search').focus()
    
      </script>
    </body>
    

    Vue 1.x 中 自定义元素指令【已废弃,了解即可】

    Vue.elementDirective('red-color', {
      bind: function () {
        this.el.style.color = 'red';
      }
    });
    

    使用方式:

    <red-color>1232</red-color>
    

    vue实例的生命周期

    • 什么是生命周期:从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期!
    • 生命周期钩子:就是生命周期事件的别名而已;
    • 生命周期钩子 = 生命周期函数 = 生命周期事件
    • 主要的生命周期函数分类:
    • 创建期间的生命周期函数:
      • beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性
        • created:实例已经在内存中创建OK,此时 data 和 methods 已经创建OK,此时还没有开始 编译模板
        • beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中
        • mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示
    • 运行期间的生命周期函数:
      • beforeUpdate:状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点
        • updated:实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!
    • 销毁期间的生命周期函数:
      • beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
        • destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

    lifecycle.png-446.9kB

    vue-resource 实现 get, post, jsonp请求

    除了 vue-resource 之外,还可以使用 axios 的第三方包实现实现数据的请求

    1. 之前的学习中,如何发起数据请求?
    2. 常见的数据请求类型? get post jsonp
    3. 测试的URL请求资源地址:
    1. JSONP的实现原理
    • 由于浏览器的安全性限制,不允许AJAX访问 协议不同、域名不同、端口号不同的 数据接口,浏览器认为这种访问不安全;
    • 可以通过动态创建script标签的形式,把script标签的src属性,指向数据接口的地址,因为script标签不存在跨域限制,这种数据获取方式,称作JSONP(注意:根据JSONP的实现原理,知晓,JSONP只支持Get请求);
    • 具体实现过程:
      • 先在客户端定义一个回调方法,预定义对数据的操作;
        • 再把这个回调方法的名称,通过URL传参的形式,提交到服务器的数据接口;
        • 服务器数据接口组织好要发送给客户端的数据,再拿着客户端传递过来的回调方法名称,拼接出一个调用这个方法的字符串,发送给客户端去解析执行;
        • 客户端拿到服务器返回的字符串之后,当作Script脚本去解析执行,这样就能够拿到JSONP的数据了;
    1. vue-resource 的配置步骤:
    • 直接在页面中,通过script标签,引入 vue-resource 的脚本文件;
    • 注意:引用的先后顺序是:先引用 Vue 的脚本文件,再引用 vue-resource 的脚本文件;
    1. 发送get请求:
    getInfo() { // get 方式获取数据
      this.$http.get('http://127.0.0.1:8899/api/getlunbo').then(res => {
        console.log(res.body);
      })
    }
    
    1. 发送post请求:
    postInfo() {
      var url = 'http://127.0.0.1:8899/api/post';
      // post 方法接收三个参数:
      // 参数1: 要请求的URL地址
      // 参数2: 要发送的数据对象
      // 参数3: 指定post提交的编码类型为 application/x-www-form-urlencoded
      this.$http.post(url, { name: 'zs' }, { emulateJSON: true }).then(res => {
        console.log(res.body);
      });
    }
    
    1. 发送JSONP请求获取数据:
    jsonpInfo() { // JSONP形式从服务器获取数据
      var url = 'http://127.0.0.1:8899/api/jsonp';
      this.$http.jsonp(url).then(res => {
        console.log(res.body);
      });
    }
    

    相关文章

    1. vue.js 1.x 文档
    2. vue.js 2.x 文档
    3. String.prototype.padStart(maxLength, fillString)
    4. js 里面的键盘事件对应的键码
    5. pagekit/vue-resource
    6. navicat如何导入sql文件和导出sql文件
    7. 贝塞尔在线生成器
  • 相关阅读:
    数据仓库
    HiveSQL 数据定义语言(DDL)
    HiveSQL 数据操控、查询语言(DML、DQL)
    【ASP.NET Core】Blazor+MiniAPI完成文件下载
    MySQL的WAL(WriteAhead Logging)机制
    MySQL系列 | 索引数据结构大全
    眼见为实,看看MySQL中的隐藏列
    mysql的默认隔离级别:可重复读(Repeatable Read)
    缓存淘汰算法LRU算法
    Android设计模式系列(12)SDK源码之生成器模式(建造者模式)
  • 原文地址:https://www.cnblogs.com/wangkaihua/p/9836880.html
Copyright © 2011-2022 走看看