02-Vue基础学习

关键字:

指令、过滤器、修饰符

  • {{ msg }} 插值表达式
  • v-cloak
  • v-text
  • v-html
  • v-bind 绑定属性机制,简写 :
  • v-on 事件绑定机制,简写 @,语法: v-on:不带on的事件='注册的函数',举例:v-on:mouseover="showFn"
  • 实例中的 this
  • 跑马灯小练习

v-model 和 双向数据绑定 (03.v-model指令的学习.html)

v-model 是唯一一个可以实现双向数据绑定的指令

通常在表单控件中使用input(radio、text、address、email...)、select、checkbox、textarea

复习了 eval() 能够把字符串尽量转成js能够运行的代码,容易被注入病毒,正式开发中尽量少用。

Vue 中如何使用样式(04.Vue中的样式-class.html)

  • 使用 class 样式

    1. 数组

      <h1 :class="['red', 'thin']">这是个邪恶的h1</h1>

    2. 数组中使用三元表达式

      <h1 :class="['red', 'thin', isactive ? 'active' : '']">这是个邪恶的h1</h1>

    3. 数组中嵌套对象

      <h1 :class="['red', 'thin', {'active': isactive}]">这是个邪恶的h1</h1>

    4. 直接使用对象

      <h1 :class="{red: true, thin: true, italic: true, active: isactive}">这是个邪恶的h1</h1>

  • 使用内联样式

    1. 直接在元素上通过:style的形式,书写样式对象

      <h1 :class="{color: 'red', 'font-size': '40px'}">这是个善良的h1</h1>

    2. 经样式对象,定义到data中,并直接应用到:style
    • 在data上定义样式
      data: {
        styleObj1: { 'color': 'red', 'font-weight': 200 },
      }
    
    • 在元素中国,通过属性绑定的样式,将样式对象应用到元素中:
      <h1 :>这是个善良的h1</h1>
    
    1. 多个样式对象的使用
    • 在data上定义样式
      data: {
        styleObj1: { 'color': 'red', 'font-weight': 200 },
        styleObj2: { 'font-style': 'italic', 'letter-spacing': '0.5em' }
      }
    
    • 在元素中国,通过属性绑定的样式,将样式对象应用到元素中:
      <h1 :>这是个善良的h1</h1>
    

v-for 和 key 属性 (05.v-for.html)

  • 迭代数组:
      <ul>
        <li v-for="item in list">{{item}}</li>
      </ul>
    
      <ul>
        <li v-for="(item, index) in list">索引:{{index}}-->值:{{item}}</li>
      </ul>
    
      <ul>
        <li v-for="(item, index) in data" :key='item.id'>id:{{item.id}}-->name:{{item.name}}</li>
      </ul>
    
  • 迭代对象中的属性:
      <p v-for="(val, key, index) in user">值:{{val}} --> 键:{{key}} --> 索引:{{index}}</p>
    
  • 迭代数字:
      <!-- 注意:如果使用 v-for 迭代数字的话,前面的 count 是从1开始的 -->
      <p v-for="count in 10">这是第{{ count }}次循环</p>
    

2.2.0+ 的版本里,挡在组件中使用v-for时,key现在是必须的。

当 Vue.js 用 v-for 正在更新已渲染的元素列表时,它默认使用就地复用策略。如果数据项的顺序被改变,

Vue将不是移动DOM元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每一个元素。

为了给Vue一个提示,以便它能跟踪每一个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一的 key 属性。

v-if 和 v-show 指令(06.v-if和v-show.html)(16-组件切换.html)

  • v-if:

    • 每次都会重新删除或创建元素
    • 有较高的切换性能消耗,如果元素涉及到频繁的切换,最好不要使用 v-if,推荐使用 v-show 。
  • v-show:

    • 每次更新不会重新进行DOM的删除和创建操作,只是切换了元素的 display: none 样式
    • 有较高的初始渲染性能消耗,如果元素可能永远也不会被显示出来,给用户看到,则推荐使用 v-if 。
  • v-else (注意:必须跟在v-if或者v-if-else的后面,不然失效)

    • 如果if条件不成立显示当前的元素
  • v-else-if 要紧跟 v-if

品牌列表的案例(07.品牌列表的案例.html)

过滤器(07.品牌列表的案例.html)

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

  • 过滤器的语法: Vue.filter('过滤器的名称', function () {})
  • 过滤器中的 function,第一个参数,已经被规定死了,永远都是 过滤器 管道符前面传过来的数据。
  • 全局过滤器 Vue.filter() 要写在 new Vue() 创建Vue实例之前。
  • 私有过滤器 filters
  • 过滤器调用的时候,采用的是就近原则,如果私有过滤器和全局过滤器名称一致了,优先调用私有过滤器。
全局过滤器、私有过滤器(07.品牌列表的案例.html)
  1. HTML元素
<td>{{ item.ctime | dataFormat('yyyy-mm-dd') }}</td>
  1. 全局过滤器 Vue.filter()
  Vue.filter("dataFormat", function (ctime, pattern = "yyyy-mm-dd hh:mm:ss") {
    const dt = new Date(ctime);
    const year = dt.getFullYear();
    const month = dt.getMonth() + 1;
    const day = dt.getDate();
    const houer = dt.getHours();
    const minute = dt.getMinutes();
    const second = dt.getSeconds();
    let ds = "";
    if (pattern && pattern.toLowerCase() === "yyyy-mm-dd") {
      ds = `${year}-${month}-${day}`;
    } else {
      ds = `${year}-${month}-${day} ${houer}:${minute}:${second}`;
    };
    return ds;
  });
  1. 私有filters定义方式:
  const vm = new Vue({
    el: "#app",
    data: {...},
    methods: {...},
    filters: {
      dataFormat: function (ctime, pattern = "yyyy-mm-dd hh:mm:ss") {
        const dt = new Date(ctime);
        const year = dt.getFullYear();
        const month = dt.getMonth() + 1;
        const day = dt.getDate();
        const houer = dt.getHours();
        const minute = dt.getMinutes();
        const second = dt.getSeconds();
        let ds = "";
        if (pattern && pattern.toLowerCase() === "yyyy-mm-dd") {
          ds = `${year}-${month}-${day}`;
        } else {
          ds = `${year}-${month}-${day} ${houer}:${minute}:${second}`;
        };
        return ds;
      }
    }
  });

使用 ES6 字符串新方法 String.prototype.padStart(maxLenght, fillString="") 或者 String.prototype.padEnd(maxLenght, fillString="") 来填充字符串

例子:

"1".padStart(2, 0)  // "01"

事件修饰符(07.品牌列表的案例.html)

.stop => event.stopPropagation() // 阻止冒泡

.prevent => 调用 event.preventDefault() // 阻止默认行为

举例:

阻止 的默认跳转事件 @click.prevent="function"

html <a href="" @click.prevent="del(item)">删除</a> <!-- 也可以设置 href="javascript:;" 防止 a 标签跳转页面 --> <!-- <a href="javascript:;" @click="del(item)">删除</a> -->

按键修饰符、自定义按键修饰符(07.品牌列表的案例.html)

  1. Vue 提供的按键修饰符:
  • enter / 13
  • tab
  • delete (捕获“删除”和“退格”)
  • esc
  • space
  • up
  • dowm
  • left
  • right

    语法:

  • 监听所有案件的抬起事件:@keyup="fun"
  • 监听某个案件的抬起事件@keyup.按键修饰符="fun" 或者 @keyup.键盘码="fun"

    举例:

<input type="text" v-model="name" @keyup.enter="add" />
<input type="text" v-model="name" @keyup.13="add" />
  1. 自定义全局按键修饰符:
<input type="text" v-model="name" @keyup.f2="add" />
// 113 是 F2 的键盘码。
Vue.config.keyCodes.f2 = 113;

自定义全局指令(07.品牌列表的案例.html)

注意:Vue中的所有指令,在调用的时候,都是以 v- 开头的。

通过 Vue.directive(); 来定义全局指令。

其中 参数1:指令的名称。注意:在定义的时候,指令的名称前面,不需要加v-前缀,但是在调用的时候,必须在指令名称前加上v-前缀来进行调用

参数2:是一个对象,这个对象身上,有一些指令相关的钩子函数,这些钩子函数可以在特定的阶段,执行相关操作。

语法以及使用举例:

  // 全局过滤器,所有的实例都共享
  // 过滤器的语法: `Vue.filter('过滤器的名称', function () {})`
  // 过滤器中的 function,第一个参数,已经被规定死了,永远都是 过滤器 管道符前面传过来的数据
  // 过滤器 `Vue.filter()` 要写在 `new Vue()` 创建Vue实例之前
  Vue.filter("dataFormat", function (ctime, pattern = "yyyy-mm-dd hh:mm:ss") {
    const dt = new Date(ctime);
    const year = dt.getFullYear();
    const month = dt.getMonth() + 1;
    const day = dt.getDate();
    const houer = dt.getHours();
    const minute = dt.getMinutes();
    const second = dt.getSeconds();
    let ds = "";
    if (pattern && pattern.toLowerCase() === "yyyy-mm-dd") {
      ds = `${year}-${month}-${day}`;
    } else {
      ds = `${year}-${month}-${day} ${houer}:${minute}:${second}`;
    };
    return ds;
  });

使用:

<div>
  {{item.ctime | dataFormat()}}
</div>

注册局部指令(07.品牌列表的案例.html)

举例:input 文本框自动获取焦点

  const vm = new Vue({
    el: "#app",
    data: {
      keyword: "",
      ...
    },
    methods: { // 自定义私有方法
      ...
    },
    filters: { // 自定义一个私有的过滤器
      ...
    },
    directives: { // 注册局部指令(自定义私有指令)
      focus: {
        // 指令的定义
        inserted: function (el) {
          el.focus()
        }
      }
    }
  });
  <input type="text" v-model="keyword" v-focus></input>
钩子函数

一个指令定义对象可以提供如下几个钩子函数 (均为可选):

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
  • unbind:只调用一次,指令与元素解绑时调用。

接下来我们来看一下钩子函数的参数 (即 el、binding、vnode 和 oldVnode)。

钩子函数参数

指令钩子函数会被依次传入以下参数:

  • el:指令所绑定的元素,可以用来直接操作 DOM。
  • binding:一个对象,包含以下 property:
    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
    • oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
    • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
    • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。
    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
  • vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。

指令函数的简写形式

  directives: { // 注册局部指令
    // focus: { // 指令的定义,完整写法
    //   inserted: function (el) {
    //     el.focus()
    //   }
    // },

    'fontSize': function(el){ // 注册指令 **简写** ,会同时注册到 `bind` 和 `updata` 钩子函数中去
      const value = parseInt(binding.value) + "px";
      el.style.fontSize = value;
    }
  }