vue 朝花夕拾系列(1)- vue内置指令和修饰符基础

vue 朝花夕拾系列(1)主要收录的就是vue使用中的基础知识,包括:vue的特点,模板技术, key实现组件高效复用,双向数据绑定及其语法糖,vue的内置指令和vue的事件修饰符等内容…

vue 特点介绍

  • 提供了virtual dom的虚拟dom
  • 提供了响应式呵呵组件化的视图组件
  • 渐进式框架,将注意力集中保持在核心库上,而将其他功能如理由vue-router和全局的状态管理vuex交给相关的库进行管理。
  • 由于vue的响应式是基于Object.defineProperty的getter和setter,而这个是仅仅支持es5的,所以vue不支持ie8以及更低版本的浏览器。

vue使用了Mustache的html模板技术:

  • 即双大括号,来声明式地将dom绑定至vue实例的数据,双大括号中支持javascript表达式,但是不支持逻辑代码块或者代码片段。
1
2
3
4
5
6
7
1){{}}类似angularjs,在dom中使用双括号进行变量插值,经常适用于非html属性
<div id="app">
{{ message }}
</div>
2) html的属性需要使用v-bind的方式进行绑定
<div id="app" :title="title"></div> // title是data对象中的动态值
<div id="app" title="我是静态属性"></div> // 静态属性直接字符串写入属性,不需要bind

使用key复用

1
2
3
4
5
6
7
8
9
10
11
12
// vue会高效复用组件元素,所以需要根据场景使用key标识是否复用
<div>
<input v-if="true" placeholder="uncle"/>
<input v-if="false" placeholder="pis"/>
</div>

// 以上在条件渲染的时候只有placehodler不一样,所以会复用,如果需要重新渲染,需要加入key

<div>
<input v-if="true" placeholder="uncle" key="firstName"/>
<input v-if="false" placeholder="pis" key="lastName"/>
</div>

数据双向绑定v-model(语法糖)

  • v-model实际上是v-on:input和v-bind:value的语法糖。
  • v-bind可以缩写成:bind,而v-on:eventName可以缩写成@eventName
    1
    2
    3
    4
    5
    它能轻松实现表单输入和应用状态之间的双向绑定。
    <input v-model="userName"/> // 等价于下面的写法
    <input v-bind:value="userName" v-on:input="userName=$event.target.value"/>
    <input :value="userName" @on:input="userName=$event.target.value"/>
    <p>{{userName}}</p>

指令系统:带有v-前缀的特殊属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1.v-if: 控制节点的渲染和移除(惰性的,初始渲染的时候为真才渲染)
2.v-show:控制节点的隐藏和消失(一直会渲染,只是切换css进行隐藏和消失)
3.v-for:循环渲染,必须指定唯一的key(string或者number类型)
1) v-for循环数组:`v-for="(item,index) in items"`
2) v-for循环对象:`v-for="(value,key,index) in items"` ,遍历对象的时候多一个第三个参数的index
3) v-for循环数字:v-for="n in 10" ,注意遍历数字的时候n从1开始
4.v-bind:attrName 属性绑定(可以简写成:attrName)
5.v-on:eventName(argument1,$event) 事件监听
1)监听事件触发一些js的代码:
<button v-on:click="counter += 1">Add 1</button>

2)逻辑太复杂的时候调用一个函数:
<button v-on:click="greet">Greet</button> // $event默认可以省略
greet(event){
// event就是原生 DOM 事件
}

3)有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:
<button v-on:click="greet('hello',$event)">Greet</button> // 显示的话必须使用特殊的$event指代原生的event对象
greet: function (message, event) {
// 现在我们可以访问原生事件对象
if (event) event.preventDefault()
alert(message)
}

修饰符

  • 修饰符可以同时使用多个,但是可能会因为顺序而有所不同。
    用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
    也就是从左往右判断~

表单修饰符

  • .lazy
1
2
3
4
5
<!--输入完所有东西,光标离开才更新视图,相当于在onchange事件触发更新 -->
<div>
<input type="text" v-model.lazy="value">
<p>{{value}}</p>
</div>
  • .trim
1
2
3
<!--  过滤首尾的空格!首尾,中间的是不会过滤的 -->
<input type="text" v-model.trim="value">
// " 123 4 " ==> "123 4"
  • .number
1
2
3
//如果你先输入数字,那它就会限制你输入的只能是数字。
//如果你先输入字符串,那它就相当于没有加.number
<input type="text" v-model.number="value">

事件修饰符

  • stop
1
2
3
4
<!-- 阻止事件冒泡,event.stopPropagation(),popUp(2)不会执行 -->
<div @click="popUp(2)">
<button @click.stop="popUp(1)">ok</button>
</div>
  • prevent
1
2
<!-- 阻止事件冒泡,event.preventDefault() -->
<form v-on:submit.prevent="onSubmit"></form>
  • self

    1
    2
    3
    4
    <!-- 只当事件是从事件绑定的元素本身触发时才触发回调 -->
    <div class="blue" @click.self="popUp(2)">
    <button @click="popUp(1)">ok</button>
    </div>
  • once

1
2
<!-- 绑定了事件以后只能触发一次,第二次就不会触发 -->
<button @click.once="popUp(1)">ok</button>
  • .native

我们经常会写很多的小组件,有些小组件可能会绑定一些事件,但是,像下面这样绑定事件是不会触发的

1
<My-component @click="popUp(3)"></My-component>

必须使用.native来修饰这个click事件(即<My-component @click.native="popUp(3)"></My-component>),可以理解为该修饰符的作用就是把一个vue组件转化为一个普通的HTML标签,
注意:使用.native修饰符来操作普通HTML标签是会令事件失效的

  • capture
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    <!-- 其实完整的事件机制是:捕获阶段--目标阶段--冒泡阶段。
默认的呢,是事件触发是从目标开始往上冒泡,加上capture就是从事件捕获阶段触发 -->
<div @click.capture="popUp(1)"> <!--捕获阶段触发-->
太爷爷层
<div @click.capture="popUp(2)"> <!--捕获阶段触发-->
爷爷层
<div @click="popUp(3)"> <!--冒泡阶段触发-->
爸爸层
<div @click="popUp(4)"> <!--目标阶段触发-->
自己层
</div>
</div>
</div>
</div>
<!-- 太爷爷=>爷爷层=>自己层=>爸爸层-->
  • passive

v-on:event.passive:这个修饰符会执行默认方法。你们可能会问,明明默认执行为什么会设置这样一个修饰符。这就要说一下这个修饰符的本意了
通俗点说就是每次事件产生,浏览器都会去查询一下是否有preventDefault阻止该次事件的默认动作。我们加上passive就是为了告诉浏览器,不用查询了,我们没用preventDefault阻止默认动作。

.passiv修饰符尤其能够提升移动端的性能```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
- 这里一般用在滚动监听,@scoll,@touchmove 。
因为滚动监听过程中,移动每个像素都会产生一次事件,每次都使用内核线程查询prevent会使滑动卡顿。
- 我们通过passive将内核线程查询跳过,可以大大提升滑动的度。
- passive和prevent冲突,不能同时绑定在一个监听器上。
不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。
- 请记住,.passive 会告诉浏览器你不想阻止的默认行为。
- `passive和prevent的关系`
```html
<!-- 不加 prevent 修饰符 -->
<a @click="clickFunc" href="javascript:alert('default active')">点击</a>
<!-- 点击后 执行 clickFunc 事件函数,并提示default active -->
<!-- prevent 修饰符 -->
<a @click.prevent="clickFunc" href="javascript:alert('default active')">点击</a>
<!-- 点击后 执行 clickFunc 事件函数,并没有提示default active -->

鼠标按键修饰符

  • left 左键点击
  • right 右键点击
  • middle 中键点击
1
2
<!-- 刚刚我们讲到这个click事件,我们一般是会用左键触发,有时候我们需要更改右键菜单啥的,就需要用到右键点击或者中间键点击,这个时候就要用到鼠标按钮修饰符 -->
<button @click.right="popUp(1)">ok</button>

键值修饰符

  • .keyCode
1
2
<!-- 指定按下某一个键才触发这个popUp的时候,这个修饰符就有用了 -->
<input type="text" @keyup.keyCode="popUp(4)">
  • 为了方便我们使用,vue给一些常用的键提供了别名

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    //普通键
    .enter
    .tab
    .delete //(捕获“删除”和“退格”键)
    .space
    .esc
    .up
    .down
    .left
    .right

    //系统修饰键(需要将系统修饰键和其他键码链接起来使用)
    .ctrl
    .alt
    .meta
    .shift
    <input type="text" @keyup.ctrl.87="popUp(4)">

    // 可以通过全局 config.keyCodes 对象自定义按键修饰符别名:
    // 可以使用 `v-on:keyup.open`
    Vue.config.keyCodes.open = 123
  • 如果是鼠标事件,那就可以单独使用系统修饰符

    1
    <button @mouseover.ctrl="popUp(1)">ok</button>
  • 单手指使用系统修饰键的修饰符(最少两个手指,可以多个)。你可以一个手指按住系统修饰键一个手指按住另外一个键来实现键盘事件。也可以用一个手指按住系统修饰键,另一只手按住鼠标来实现鼠标事件

v-bind修饰符

  • .sync(2.3.0+ 新增)
1
2
3
4
5
6
7
8
9
10
11
12
//父亲组件
<comp :myMessage="message" @update:myMessage="func"></comp>
//js
func(msg){
this.message = msg;
}


//子组件js发送事件更新父组件的message
invokerFunction(){
this.$emit('update:myMessage',params);
}

可以简化成

1
2
3
4
5
<!-- 父组件使用sync修饰符简化上面的写法 -->
<comp :myMessage.sync="message"></comp>

//子组件invoker的函数触发事件
this.$emit('update:myMessage',params);

sync需要注意的地方

1)使用sync的时候,子组件传递的事件名必须为update:value,其中value必须与子组件中props中声明的名称完全一致(如上例中的myMessage,不能使用my-message
2)注意带有 .sync 修饰符的 v-bind 不能和表达式一起使用 (例如 v-bind:title.sync=”doc.title + ‘!’” 是无效的)。取而代之的是,你只能提供你想要绑定的属性名,类似 v-model
3)将 v-bind.sync 用在一个字面量的对象上,例如 v-bind.sync=”{ title: doc.title }”,是无法正常工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑

参考链接

vue修饰符–可能是东半球最详细的文档(滑稽)

初到贵宝地,有钱的给个钱场,没钱的挤一挤给个钱场