Vue简介
Vue
1.通过脚手架安装
npm install -g @vue/cli // 全局安装vue/cli脚手架
vue --version // 查看vue版本
vue create hello-world // 创建项目
vue ui // 以图形化界面管理项目
2.目录结构
/public
目录下存放的index.html
为基础html,vue生成的html页面文件均是以此文件为模板基础产生的。/src
目录下为项目源文件,分为assets
资源文件夹、components
组件文件夹、views
页面文件夹、store
状态管理文件夹、modules
多入口文件夹,单入口时不需要。/dist
目录为发布目录。
3.简介
单页面单入口时,main.js
为入口文件,会将vue
实例挂载到#app
节点上。.vue
文件包含<template></template>
、<script></script>
、<style lang="less"></style>
。注意style
样式要注明样式文件语言,template
内首层节点为单节点。
4.vue.config.js文件配置简介
module.exports = {
publicPath: '/wxapp/', // 一般为public根路径
outputDir: 'dist/wxapp', // build的项目存放路径
assetsDir: '', // 放置生成的静态资源(js、css、img、fonts)的(相对于 outputDir 的)目录
indexPath: 'index.html', // 指定生成的 index.html 的输出路径 (相对于 outputDir),也可以是一个绝对路径
pages: { // 多页面入口配置
page1: {
entry: 'src/modules/page1/page1.js', // 应用入口配置,相当于单页面应用的main.js,必需项
template: 'public/index.html', // 应用的模版,相当于单页面应用的public/index.html,可选项,省略时默认与模块名一致
filename: 'page1.html', // 编译后在dist目录的输出文件名,可选项,省略时默认与模块名一致
title: 'page1标题', // 标题,可选项,一般情况不使用,通常是在路由切换时设置title;需要注意的是使用title属性template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
},
page2: {}
},
// 其余项目配置详见
}
5.多入口页面
多页面入口时,不仅需要配置vue.config.js
文件中的pages
字段,还要将多页面文件的入口文件脚本、入口vue文件分别处理,若有router路由配置的话,还应分别配置路由router文件。入口JS文件:
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
import store from '@/store/store.js'
import MainLoan from './MainLoan.vue'
import '@/assets/css/cssreset-mobile.css'
import 'we-vue/lib/style.css'
import WeVue from 'we-vue'
import '@/assets/css/main-mobile.css'
import router from './router'
import Fastclick from 'fastclick'
Vue.config.productionTip = false
Vue.use(WeVue)
Vue.use(VueAxios, axios)
Fastclick.attach(document.body)
new Vue({
router, // 挂载路由
store, // 挂载全局状态
render: h => h(MainLoan) // 初始模板选择
}).$mount('#app')
6.vue实例
<script></script>
脚本标签内,基本类型如下:
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app', // 页面或者组件名称
components: { // 本组件需要使用的下级组件声明
HelloWorld
},
props: {
prop1: String/Object/Number // 上级组件传递的参数
},
data() { // data数据,需要使用函数返回
return {
index: 1,
temp: 'nali',
title: 'ttx',
watchIndex: 1,
}
},
computed: { // 计算属性,监听值无变化时,会有计算缓存,不会重复求值
getIndex() {
return this.index + 1
}
},
methods: { // 内部方法定义
test() {
console.log('test')
}
},
watch: { // 监听实例数据变动,可用于异步或开销较大的处理,一般无返回值
index(value) {
this.watchIndex = this.index
}
},
filters: { // 过滤器,对传入的值进行包装处理
capitalize(value) {
return value.toString()
},
},
// 以下为生命周期回调
beforeCreate() {}, // 实例创建之前调用
created() {}, // 实例创建成功,此时 data 中的数据显示出来了
beforeMount() {}, // 数据中的 data 在模版中先占一个位置
mounted() {}, // 模版中的 data 数据直接显示出来了
beforeUpdate() {}, // 当 data 数据发生变化调用,发生在虚拟 DOM 重新渲染和打补丁之前
updated() {}, // 数据更改导致的虚拟 DOM 重新渲染和打补丁
beforeDestroy() {}, // 在 vue 实例销毁之前调用,此时实例任然可用
destroyed() {}, // 在vue实例销毁之后调用,实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁
}
7.数据展示绑定
模板展示内容内,通过进行绑定,如
<div></div>
;若要进行一次性插值,节点上加入v-once
指令即可,次节点内数据绑定一次后将不会随data数据变化而更新。这个称为 Mustache 语法。Mustache语法不能用于HTML节点上,节点上应该使用vue指令。
Mustache语法内可以使用JS表达式,且只能为单个表达式。
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
8.vue指令
指令是带有v-
前缀的特殊特性。指令后数据绑定直接使用data属性即可,不用Mustache语法。
v-bind:
指令可以用于响应式地更新HTML特性:<a v-bind:href="url">...</a>
,v-bind:
可简写为:
;v-on:
用于监听 DOM 事件:<a v-on:click="doSomething">...</a>
,v-on:
可简写为@
;v-if:
用于条件性地渲染一块内容,<h1 v-if="awesome">Vue is awesome!</h1><h1 v-else>Oh no</h1>
;v-show:
用于节点的显示与隐藏;v-for:
用于循环渲染;v-model:
用于数据双向绑定;
9.指令修饰符
.
修饰符半角句号.
指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。修饰符可以级联使用。
<form v-on:submit.prevent="onSubmit">...</form>
常用修饰符:
事件修饰:
`.stop`: event.stopPropagation(),防止事件冒泡;
`.prevent`: event.preventDefault(),防止执行预设的行为;
`.capture`: 与事件冒泡的方向相反,事件捕获由外到内;
`.self`: 只会触发自己范围内的事件,不包含子元素;
`.once`: 只会触发一次;
`.passive`: 不会等待事件回调执行完毕才继续执行下一次事件,等于事件回调时异步的。有助于提升连续触发事件的性能。
键盘修饰符:
`.enter`:回车键;
`.tab`:制表键;
`.delete`:含delete和backspace键;
`.esc`:返回键;
`.space`: 空格键;
`.up`:向上键;
`.down`:向下键;
`.left`:向左键;
`.right`:向右键;
类似于`@keyup.esc`。
鼠标修饰符:
`.left`:鼠标左键;
`.middle`:鼠标中间滚轮;
`.right`:鼠标右键;
自定义按键修饰符别名:
<div id="app">
<input type="text" v-on:keydown.f5="prompt()">
</div>
Vue.config.keyCodes.f5 = 116
10.class与style绑定
通过v-bind:class=
指令动态地切换节点class属性。这个元素上已经存在的类不会被覆盖。
对象语法:
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
// vue实例中
data() {
return {
isActive: true,
hasError: 1
}
}
也可以直接使用class的对象:
<div v-bind:class="classObject"></div>
data: {
classObject: { // 此对象放于计算属性最好,可以动态结算更新
active: true,
'text-danger': false
}
}
数组语法,类似于直接将class名列出给节点:
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
// <div class="active text-danger"></div>
内联样式绑定:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
activeColor: 'red',
fontSize: 30
}
// 或者
<div v-bind:style="styleObject"></div>
data: { // 同样,计算属性更加灵活方便
styleObject: {
color: 'red',
fontSize: '13px'
}
}
// 数组语法可以将多个样式对象应用到同一个元素上
<div v-bind:style="[baseStyles, overridingStyles]"></div>
11.条件渲染
v-if
预计传值得真假判断去确定是否需要渲染html结构;
<h1 v-if="awesome">Vue is awesome!</h1>
当需要批量显示与隐藏多节点时,可以使用<template>
加v-if
指令进行包裹,最终渲染不会包含<template>
节点。
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
v-if
对应的v-else
与v-else-if
指令:
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
另外,vue在切换渲染时,会服用已有的元素,若要表明两元素不可服用,需要在元素节点上定义不同key
值:
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
v-show
用于节点的显示与隐藏,仅仅变换了display
值;v-show
不支持<template>
元素。
12.循环渲染
v-for:
循环渲染。v-for
节点渲染时,节点会被不断复用,当数据顺序变更或减少时,节点不会全部重新渲染,但会就近更新节点简单数据,因此只适用于不依赖子组件状态的情况。
当节点需要跟踪每个节点身份时,请使用v-bind:key
为节点添加唯一标示。
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
// index为渲染索引
<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
var example2 = new Vue({
el: '#example-2',
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
也可以用of
替代in
作为分隔符,当使用in
时,可以遍历对象属性。
<ul id="v-for-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
})
// name为属性名
<div v-for="(value, name) in object">
{{ name }}: {{ value }}
</div>
// index为索引
<div v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
</div>
为循环节点添加唯一标示,不要使用对象或数组之类的非基本类型值作为 v-for 的 key。请用字符串或数值类型的值:
<div v-for="item in items" v-bind:key="item.id"><!-- 内容 --></div>
v-for
也可以接受整数。在这种情况下,它会把模板重复对应次数。
<div>
<span v-for="n in 10">{{ n }} </span>
</div>
v-for
指令与v-if
指令同时使用时,v-for
指令优先级高于v-if
指令。
13.数组数据的更新检测
vue数据长度隐式更新或数组被替换时,vue会触发数据更新与视图更新;如push();pop();shift();unshift();splice();sort();reverse()
或数组替换方法均会触发数据更新。
但当用索引更新某一个数组项或者显示地定义数组长度时,数据更新不会检测到。如arr[1] = 2; arr.length = 5;
当需要使用上述方式时,可以使用以下方式变更触发视图更新:
Vue.set(vm.items, indexOfItem, newValue)
vm.items.splice(indexOfItem, 1, newValue)
vm.$set(vm.items, indexOfItem, newValue)
vm.items.splice(newLength)
同理,对象数据变更时,vue也不能检测对象属性的添加与删除。对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性,但可以通过Vue.set
向对象中添加响应属性。
var vm = new Vue({
data: {
userProfile: {
name: 'Anika'
}
}
})
Vue.set(vm.userProfile, 'age', 27)
vm.$set(vm.userProfile, 'age', 27) // 或直接调用通用方法
若有多个属性要一次性添加,不应该将多个属性直接添加到原对象上,而是应该创建一个新对象去替换原对象:
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
14.事件处理
v-on
指令监听DOM事件;若需要在内联语句处理器中访问原始的DOM事件。可以用特殊变量$event
把它传入方法;
<button @click="test($event)"></button>
// ...
methods: {
test(e) {
e.stopPropagation()
}
}
15.表单输入绑定
用v-model
指令在表单<input>
、<textarea>
及<select>
元素上创建双向数据绑定。v-model
会忽略表单元素的value
、checked
、selected
的初始值。input
和textarea
输入时,中文、日文和韩文等输入法,没有输入完毕不会更新数据。
修饰符:.lazy
:v-model
在每次input
事件触发后将输入框的值与数据进行同步(除了上述输入法组合文字时)。你可以添加.lazy
修饰符,从而转变为使用change
事件进行同步;
<input v-model.lazy="msg" >
.trim
: 自动过滤用户输入的首尾空白字符;
16.组件基础
对于重复性的结构,组件的使用将大大简化节点结构的书写。组件和页面类似,均有自己独立的实例与作用域。组件使用时,需要先注册才能被使用。注册分全局注册和局部注册。组件使用时,需要使用短横线分隔命名。
<HelloWorld msg="Welcome to Your Vue.js App"/> // 使用
import HelloWorld from '@/components/HelloWorld.vue' // 引入
export default {
name: 'home',
inheritAttrs: false, // 组件不继承使用父组件传入的prop为定义的属性
components: { // 注册
HelloWorld
}
}
向子组件传递数据props
// HelloWorld组件中
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
每一个组件必须只有一个根节点,多个时会报错。父组件的数据变化可以引起子组件的数据变化,但子组件内数据变化不会传递到父组件,但子组件需要通知父组件时,可以使用$emit()
向父组件派发事件,当父组件由对该事件进行监听时,就会触发父组件事件,达到子组件通知父组件的效果。
// 父组件
<blog-post v-on:enlarge-text="enlargeText"></blog-post>
data() {
postFontSize: 16
},
methods: {
enlargeText(addition) { // 也可以用$event进行访问
this.postFontSize += addition
}
}
// 子组件
<button v-on:click="$emit('enlarge-text', 0.1)">
Enlarge text
</button>
当在组件上使用v-model
进行值绑定时,等价于:
<input v-model="searchText">
<input v-bind:value="searchText" v-on:input="searchText = $event.target.value"> // value和input必须绑定才有效果
<custom-input v-bind:value="searchText" v-on:input="searchText = $event"></custom-input>
Vue.component('custom-input', {
props: ['value'], // 组件的props必须包含value
template: '<input v-bind:value="value" v-on:input="$emit('input', $event.target.value)"> // 事件需通过input传出
})
组件的prop
可以是数组,可以是对象集。当使用对象集时,可以指定各个属性的接受值类型。任何类型的值都可以传递给prop
。
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}
Vue.component('my-component', {
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number, Date, Symbol],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})
若需要向prop
传入一个对象的所有属性,可使用不带参数的v-bind
:
post: { id: 1, title: 'My Journey with Vue' }
<blog-post v-bind="post"></blog-post>
// 等价于
<blog-post v-bind:id="post.id" v-bind:title="post.title"></blog-post>
注意组件的数据传递请遵守单项数据原则,由父组件去改变传递的数据值,子组件不应该改变传递的值,若有需要,请使用子组件事件派发通知父组件改变。
组件的prop
接收到未定义的属性时,未定义的属性会直接添加到组件的根节点上。另外,父节点传入的属性一般会覆盖子组件的同名属性,但class
与style
会并存叠加。
17.自定义事件
自定义事件的事件名不会用作一个JS变量名或者属性名,所有没有必要使用驼峰结构,且v-on
事件监听时,会自动转换为小写,故推荐使用-
分隔的命名方式。
18.插槽
自定义的组件中,可以使用模板代码或html结构对组件进行合成,可以理解为prop
接收的是JS数据,而插槽接收的是html结构。如果组件内没有包含<slot>
元素,则组件标签内所有内容均会被舍弃。
<navigation-link url="/profile">Your Profile</navigation-link>
// 模板
<a v-bind:href="url" class="nav-link"><slot></slot></a>
// 渲染为
<a v-bind:href="/profile" class="nav-link">Your Profile</a>
卡槽的作用域与组件的作用域一致,父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
预置内容:当一个组件中有<slot>
结构但是父组件使用该组件时,没有传递slot
值,则会展示出默认的预置内容。
<button type="submit"><slot>Submit</slot></button>
// 使用
<submit-button></submit-button>
// 渲染
<button type="submit">Submit</button>
// 使用
<submit-button>save</submit-button>
// 渲染
<button type="submit">save</button>
具名插槽:<slot>
插槽带有name
属性值,可以让父组件在使用时,传递特定的内容到指定的位置。<slot>
属性在不设置name
属性时,默认name
属性值为default
。父组件中任何没有被包裹在带有v-slot
的<template>
中的内容均会被视为默认<slot>
的内容。注意v-slot
指令只能用于<template>
节点上,除非组件只有默认插槽,不过这时候有无v-slot
已经不重要了。
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
// 使用
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
// 渲染
<div class="container">
<header>
<h1>Here might be a page title</h1>
</header>
<main>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</main>
<footer>
<p>Here's some contact info</p>
</footer>
</div>
作用域插槽:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译;若需要向卡槽中传递数据,则可以使用插槽prop
。在<slot>
上绑定具名属性值,在父组件中给v-slot
带一个值来定义我们提供的插槽prop
的名字。
<span><slot v-bind:user="user">{{ user.lastName }}</slot></span>
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
19.动态组件
当组件通过is
属性进行动态切换时,不能组件之间会进行不断的销毁与创建。若需要将组件销毁前的状态保存下来,可以使用<keep-alive>
元素进行包裹。当使用<keep-alive>
时,内部组件必须要有唯一名字,否则无效。
<component v-bind:is="currentTabComponent"></component>
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
20.边界情况
访问根实例:在每个new Vue
实例的子组件中,其根实例可以通过$root
属性进行访问。
new Vue({
data: { foo: 1 },
computed: {
bar: function () { /* ... */ }
},
methods: {
baz: function () { /* ... */ }
}
})
// 子组件中,可以把根vue实例作为一个简单的全局store来使用:如下
this.$root.foo
this.$root.foo = 2
this.$root.bar
this.$root.baz()
访问父组件实例:$parent
属性可以用来从一个子组件访问父组件的实例。与$root
类似,但不建议使用。
访问子组件实例或者子元素:可以在子组件或者节点上添加ref
属性赋予一个标记ID,然后通过$refs
访问这个组件或者元素。注意$refs
属性只在定义ref
的组件实例内有效。同样地,ref
也应尽量减少使用。
// base-input组件
<input ref="input">
// 使用base-input组件
<base-input ref="usernameInput"></base-input>
methods: {
// 用来从父级组件聚焦输入框
focus: function () {
this.$refs.input.focus()
}
}
21.进入离开过渡动画
单元素/组件的过渡:使用<transition name="actionName"></transition>
包裹。若过渡没有检测到CSS动画定义,也没有检测到钩子函数,则节点的显示与隐藏将会在下一帧(显示动画帧update)执行
<div id="demo">
<button v-on:click="show = !show">
Toggle
</button>
<transition name="fade">
<p v-if="show">hello</p>
</transition>
</div>
new Vue({
el: '#demo',
data: {
show: true
}
})
.fade-enter-active, .fade-leave-active { // 动画执行时样式
transition: opacity .5s;
}
.fade-enter, .fade-leave-to { // 渐入状态和渐出状态
opacity: 0;
}
过渡类名:v-enter
: 元素被插入之前状态,插入之后下一帧移除;v-enter-active
: 元素被插入的前一帧生效,进入动画执行时间内有效,动画完成后移除;v-enter-to
: 元素被插入后的下一帧生效,动画完成后移除;有点类似于enter-active
,但生效时间晚3帧;v-leave
: 元素离开动画触发那一帧生效,下一帧移除;v-leave-active
: 元素离开动画触发那一帧生效,离开动画执行时间内有效,动画完成后移除;v-leave-to
: 元素离开动画触发下一帧生效,离开动画执行时间内有效,动画完成后移除;
自定义过渡类名:
用enter-class
、enter-active-class
、enter-to-class
、leave-class
、leave-active-class
、leave-to-class
自定义动画类名,他们的优先级高于普通类名。用于vue过渡动画和第三方库结合较好。
<transition
name="custom-classes-transition"
enter-active-class="animated tada"
leave-active-class="animated bounceOutRight"
>
<p v-if="show">hello</p>
</transition>
多元素多节点动画:<transition-group></transition-group>
22.混入
类似于对象继承的一个东西,组件在实例化之前将预先设定或者公共的属性添加到实例化对象上。当有许多组件有公共的部分的时候使用起来就比较方便。
data对象会如下方式合并:
// 混入对象
var mixin = {
data: function () {
return {
message: 'hello',
foo: 'abc'
}
}
}
// 组件使用
new Vue({
mixins: [mixin],
data: function () {
return {
message: 'goodbye',
bar: 'def'
}
},
created: function () {
console.log(this.$data)
// => { message: "goodbye", foo: "abc", bar: "def" }
}
})
混入对象会依次优先被复制到组件上,组件定义的内容会最后复制到组件上,产生自定义修改效果。另外:同名的钩子函数将会被合并为一个数组,同名钩子函数会依次执行。其实可以将钩子函数看做一个订阅事件,当此事件被多次订阅后,肯定也会多次执行。
var mixin = {
created: function () {
console.log('混入对象的钩子被调用')
}
}
new Vue({
mixins: [mixin],
created: function () {
console.log('组件钩子被调用')
}
})
// => "混入对象的钩子被调用"
// => "组件钩子被调用"
值为对象的选项,例如methods
、components
和directives
,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。与data
合并方式类似。Vue.extend()
也是如此。
var mixin = {
methods: {
foo: function () {
console.log('foo')
},
conflicting: function () {
console.log('from mixin')
}
}
}
var vm = new Vue({
mixins: [mixin],
methods: {
bar: function () {
console.log('bar')
},
conflicting: function () {
console.log('from self')
}
}
})
vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"
全局混入:我们可以使用Vue.mixin({})
进行全局混入,当使用全局混入时,以后使用的每一个vue实例都会受到此影响(包括第三方组件),所有不建议使用。
23.自定义指令
全局定义时,可以使用Vue.directive('directive-name', {})
进行定义;当然也可以在组件内使用局部定义directives
属性。
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
// 局部定义
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
定义时,需要定义指令的触发时间,也就是指令的钩子函数:bind
: 只调用一次,指令第一次绑定到元素时调用。insert
: 被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)。update
: 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。componentUpdated
: 指令所在组件的 VNode 及其子 VNode 全部更新后调用。unbind
: 只调用一次,指令与元素解绑时调用。
钩子函数的参数请参考vue文档。