# 指令 Directive

<div v-text="x"></div>
<div v-html="x"></div>

以 v- 开头的东西就是指令

  • 语法

v-指令名:参数 = 值 , 如 v-on: click=add

如果值里没有特殊字符,则可以不加引号; 有些指令没有参数和值, 如 v-pre; 有些指令没有值,如v-on:click.prevent

# 自定义指令

声明一个全局指令

Vue.directive('x',directiveOptions)

声明一个局部指令

new Vue({
  ...,
  directives:{ "x" : directiveOptions }
})

directiveOptions五个函数属性:

  • bind(el,info,vnode,oldVnode) 类似created
  • inserted(el,info,vnode,oldVnode) 类似mounted
  • update(el,info,vnode,oldVnode) 类似updated
  • componentUpdated(el,info,vnode,oldVnode)
  • unbind(el,info,vnode,oldVnode) 类似destroyed
# 指令的作用:
  • 主要用于DOM操作(Vue实例/组件用于数据绑定、事件监听、DOM更新,Vue指令用于DOM操作)
  • 减少重复
new Vue({
  directives: {
    on2: {
      // bind 可以改为 inserted
      bind(el, info) {
        el.addEventListener(info.arg, info.value);
        // Vue 自带的 v-on 并不是这样实现的,它更复杂,用了事件委托
      },
      unbind(el, info) {
        el.removeEventListener(info.arg, info.value);
      }
    }
  },
  template: `
    <button v-on2:click="hi">点我</button>
  `,
  methods: {
    hi() {
      console.log("hi");
    }
  }
}).$mount("#app");

# 修饰符

@click.stop = "add" 表示阻止事件传播/冒泡
@click.prevent = "add" 表示阻止默认动作
@click.stop.prevent = "add" 同时表示两种意思

v-on支持的修饰符:

.stop .prevent
.{keycode | keyAlias}  .capture .self .once .passive .native
快捷键相关 .ctrl .alt .shift .meta .exact
鼠标相关 .left .right .middle

v-bind 支持的修饰符:

.sync .prop .camel 

v-model 支持的修饰符: .lazy .number .trim

.lazy
在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转为在 change 事件_之后_进行同步:

<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg">


.number
如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符:

<input v-model.number="age" type="number">
这通常很有用,因为即使在 type="number" 时,HTML 输入元素的值也总会返回字符串。如果这个值无法被 parseFloat() 解析,则会返回原始的值。

.trim
如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:
<input v-model.trim="msg">

# .sync 修饰符

组件不能修改 props 外部数据 $emit 可以触发事件,并传参 $event 可以获取$emit的参数

.sync功能:当一个子组件改变了一个 prop 的值时,这个变化也会同步到父组件中;使用update:myPropName 模式触发事件,实现双向绑定

代码示例

//父组件代码
<template>
  <div class="app">
    App.vue 我现在有 {{total}}
    <hr>
    <Child :money="total" v-on:update:money="total = $event"/>
  </div>
</template>

<script>
import Child from "./Child.vue";
export default {
  data() {
    return { total: 10000 };
  },
  components: { Child: Child }
};
</script>

<style>
</style>
//子组件代码
<template>
  <div class="child">
    {{money}}
    <button @click="$emit('update:money', money-100)">
      <span>花钱</span>
    </button>
  </div>
</template>

<script>
export default {
  props: ["money"]
};
</script>

<style>
</style>

在一个包含money prop 的假设的组件中,通过以下方式赋予新值:

$emit('update:money', money-100)
// this.$emit 可以触发事件,并传参

然后父组件可以监听事件并根据需要更新一个本地的数据属性

 <Child :money="total" v-on:update:money="total = $event"/>
// $event 可以获取$emit的参数
 <Child :money="total" @update:money="total = $event"/>

为了方便起见,这种模式可以缩写,即 .sync 修饰符:

 <Child :money.sync="total"/>