Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue简单使用 #11

Open
LyzSg opened this issue Feb 2, 2019 · 0 comments
Open

Vue简单使用 #11

LyzSg opened this issue Feb 2, 2019 · 0 comments
Labels

Comments

@LyzSg
Copy link
Owner

LyzSg commented Feb 2, 2019

1. 创建一个Vue实例

el : 指定实例挂载的DOM元素。可以是CSS选择器,也可以是HTMLElement

<div id="app"></div>

<script>
  new Vue({
    el: '#app'
  })
</script>

当没有指定el时,就不会立刻进行挂载和编译。

此时可以在获取实例vm后,使用实例方法$mount来指定要挂载的DOM元素。

<div id="app"></div>

<script>
  var vm = new Vue({})
  vm.$mount('#app')
</script>

template : html字符串模版(只能有一个顶层元素)。当此属性存在时,会代替el或者$mount方法指定的挂载元素,并作为html模版进行解析。例如下面的div#app就会被h1替换。

<div id="app"></div>

<script>
  var vm = new Vue({
    el: '#app',
    template: '<h1>{{message}}</h1>',
    data: { message: 'hello' }
  })
</script>

在没有指定template的时候,其实会把指定挂载的元素通过outerHTML隐式地转成模版再使用。

template -> AST -> render -> VNode -> 真实DOM

render: 当需要js的完全编程能力时,可以使用render函数,优先级比template要高。

render函数接收createElement方法,并返回其生成的VNode。

createElement第一个参数是根标签,第二个参数是相关属性的数据对象,第三个参数是子虚拟节点,可以由createElement生成。

new Vue({
  el: '#app',
  render (createElement) {
    return createElement('p', {
      style: {
        color: 'red',
        fontSize: '14px'
      },
      'class': {
        foo: true,
        bar: false
      },
      attrs: {
        id: 'foo'
      },
      props: {
        myProp: 'bar'
      },
      domProps: {
        innerHTML: 'baz'
      }
    }, [
      'hello world',
      createElement('h1', '一则头条')
    ])
  }
})

2. 模版语法

Mustache语法(双大括号语法), 可以在里面使用js表达式(运算、三目运算符、函数调用)

里面的变量都是挂载到vm实例上面的属性。在配置vm实例时,设置的data和methods都会混入到实例上,可以直接通过vm.xxx来访问。

methods配置的方法中this都指向该vm实例。所以不应该使用箭头函数来定义method函数。

<div id="app">{{ 'data:' +  msg + show() }}</div>
<script>
  new Vue({
    el: '#app',
    data: {
      msg: 'hello',
      hi: 'hi'
    },
    methods: {
      show() {
        return this.hi
      }
    }
  })
</script>

Mustache语法不能作用在html特性上,因为html特性或属性必须是字符串

<a href={{url}}>url</a>

这时可以使用Vue指令中的v-bind指令,可缩写为冒号:

<a v-bind:href="url">url</a>
<a :href="url">url</a>

Vue指令的格式是:v - 指令名 : 指令参数 . 修饰符 = 指令表达式

3. 事件

绑定事件用 v-on:click="func" 可缩写为 @click="func"

如果写的是函数执行的形式func(),那么必须手动注入事件对象$event

<button @click="show">点我</button>
<button @click="show($event)">点我</button>

在html中监听事件的好处:

  1. 一看html模版就能定位js里的方法
  2. 使ViewModel代码和DOM完全解耦,无需手动绑定事件
  3. 当一个ViewModel被销毁时,所有的事件处理器都会被自动删除。

事件修饰符

  • .prevent 阻止默认事件
  • .stop 阻止冒泡
  • .capture 开启捕获
  • .once 只触发一次
  • .self 只在event.target是自身的情况下才触发

可以只有修饰符没有指令表达式。修饰符可以链式调用,但要注意顺序:

<!-- 仅阻止div自身的默认事件,子元素不阻止 -->
<div @click.self.prevent>
  <a href="github.com">link</a>
</div>

<!-- 阻止div自身及其子元素的默认事件 -->
<div @click.prevent.self>
  <a href="github.com">link</a>
</div>

按键修饰符

使用keyCode。vue提供了最常用的按键别名代替keyCode。esc和方向键在IE9中有不同的key值,所以最好用内置别名。

<!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` -->
<input v-on:keyup.13="submit">
  • .enter .space .tab
  • .up .down .left .right
  • .esc
  • .delete (同时监听Delete键和退格键)

可通过全局config.keyCodes对象自定义按键修饰符别名:
配置Vue.config.keyCodes.f1 = 112后,可以使用@keyup.f1

系统修饰符

  • .ctrl
  • .shift
  • .alt
<!-- Alt + C -->
<input @keyup.alt.67="clear">

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>

鼠标按钮修饰符

  • .left
  • .right
  • .middle

.exact修饰符

可以精确到特定的修饰符组合触发事件,多按了其他按键则不触发

<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>

4. 有关渲染

v-html : Mustache语法默认只能解析为普通文本,不能解析HTML代码。当需要解析HTML代码时,使用v-html指令:

<div v-html>{{ rawHtml }}</div>

v-once : 绑定的数据对象的属性一旦发生改变,双大括号中的插值都会改变。使用v-once指令可以让数据只渲染第一次。

<span v-once>这个将不会改变: {{ msg }}</span>

v-cloak : 该属性会保持在元素上直到关联实例结束编译。配合css属性选择器[v-cloak] { display: none }可以隐藏未编译的双大括号,防止闪烁。

v-if v-else-if v-else 条件渲染 : 注意不显示的节点不会出现在结构上。

<p v-if="items > 10">{{ items }} 个 有现货</p>
<p v-else-if="items >= 1">库存不多,赶紧买啊</p>
<p v-else>没货了淦</p>

通常配合template标签来进行分组渲染

<template v-if="items > 50">
  <p>注意事项:</p>
  <p>库存好多,现在买笑嘻嘻</p>
</template>

v-show : 实际是通过修改元素的display属性来使显示/隐藏。不显示的元素还在html结构中。

<div v-show="true">show</div>
<div v-show="false">no show</div>

需要频繁切换则用v-show性能更好, 如果条件很少改变则用v-if

v-for 列表渲染

  • v-for指令的表达式需要使用 item in items 形式的语法(可以把in换成of)。
  • 必须在双大括号中才能使用item。
  • 双大括号中同样可以使用data中的变量。当item与data中的变量重名时,item有效。
  1. 当items为数组时, 第二个参数是索引值
<ul>   
  <li v-for="(title, index) in movies">{{ index + ' ' + title }}</li>
</ul>
  1. 当items为对象时,第二个参数是key,第三个参数才是index
<ul>
  <li v-for="(value, key, index) in obj">{{ prop }} : {{ name }} ({{ index }})</li>
</ul>
  1. 当items是非负整数时,例如是3,那么会先创建一个长度为3的数组,然后重1开始填充为[1,2,3]。所以如果是负数,则在new Array阶段就会报错。

    当items是字符串时,例如是'abc',则会转成['a','b','c']。
<div v-for="(n, i) in 10">{{ n }}|{{ i }}</div>
<div v-for="(s, i) in 'abcd'">{{ s }}|{{ i }}</div>
  • key
    v-for更新已渲染过的元素列表时,采用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序。

    绑定key属性并提供唯一值,即可跟踪每个节点的身份。
<div v-for="n in numbers" :key="n">
  {{ n }} <input type="text">
</div>
<button @click="reverse">reverse</button>

<script>
  new Vue({
    el: '#app',
    data: {
      numbers: [1, 2, 3]
    },
    methods: {
      reverse: function () {
        this.numbers.reverse()
      }
    }
  })
</script>
  • 有几种情况vue不能随数据变化更新视图:

    例如对于数组,直接通过数组下标的形式修改添加数据,或者修改数组长度:
    vm.items[indexOfItem] = newValue
    vm.items.length = newLength
    对于对象,通过键名添加或者删除属性:(修改已有属性是可以触发更新的)
    vm.obj.newKey = newValue
    delete vm.obj.key

    对于数组和对象相互嵌套的情况下,同上规则。例如修改数组中的对象的属性,是可以的,但是添加数组中对象的属性就不行;同样修改对象中数组的某个值也是不行的。

    但是vue对于以下数组方法(改变原数组),能够触发视图更新:
    push、pop、unshift、shift、reverse、splice、sort

    所以,当想插入值或者缩短数组长度时,可以利用数组的splice方法:
    vm.items.splice(indexOfItem, 1, newValue)
    vm.items.splice(newLength)

    或者,利用Vue的全局方法set或者实例方法$set(二者相同)来强制更新数组:
    Vue.set(vm.items, indexOfItem, newValue)
    Vue.set(vm.obj, newKey, newValue)

    或者改变原数组或对象的引用,就可以触发视图更新。

5. 计算属性

使用初衷:模版语法内放过多的逻辑运算不便于维护,且相同逻辑不便于复用:

<!-- Bad -->
<div id="example">
  {{ message.split('').reverse().join('') }}
</div>

所以,引入了计算属性:

<!-- Good -->
<div id="example">{{ reversedMessage }}</div>
<script>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})
</script>

computed是个对象,它的属性即为计算属性。计算属性有两种定义方法,一种即为上面的形式,是一个函数,这个函数将作为reversedMessage属性的getter,函数内的this同样指向vm实例。

另一种形式则是定义为对象,并手动设置setter和getter:

// ...
computed: {
  fullName: {
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}
// ...

set接收的参数是修改计算属性(vm.fullName = xxx)时的值。利用setter可以更新依赖值。

“缓存机制”:计算属性都是只有在依赖的属性(getter中出现过的响应式属性)发生改变时,才会去走getter去更新,否则在重新渲染时取的是上一次缓存的值。这就是区别于methods的好处。

*计算属性不能监听异步操作中所依赖的属性。

6.侦听器

使用初衷:当要在数据变化时要执行异步操作时。

watch是个对象,键是要侦听的属性,值有四种情况:

  1. 回调函数,两个参数分别是新值和旧值
// ...
watch: {
  a: function (val, oldVal) {
    console.log('new: %s, old: %s', val, oldVal)
  }
}
// ...
  1. 字符串,是methods中的函数名
// ...
watch: {
  b: 'someMethod'
}
// ...
  1. 数组。对于一个属性可设置多个watcher函数,按顺序执行
// ...
watch: {
  e: [
    function handle1(val, oldVal) { /* ... */ },
    function handle2(val, oldVal) { /* ... */ }
  ],
}
// ...
  1. 对象,此时handler为回调函数,另外有两个可配置属性。
//...
watch: {
  c: {
    handler: function (val, oldVal) { /* ... */ },
    deep: true,
    immediate: true
  },
}
//...

deep默认为false。当deep为false时,通过键修改或者添加对象属性时,监听不到。当deep为true时,通过键修改已有属性可以侦听到,但是添加属性同样侦听不到。
deep不影响数组的监听,数组同样是只有使用变异方法或者改变引用才能侦听到。

所以,当deep为true时,侦听器能侦听的实际上和渲染更新是一样的。为false时,改变对象属性值,虽然视图更新了,但是侦听器侦听不到。

immediate默认为false。设为true后,对于的回调将会在侦听开始之后(created触发之前)被立即调用。

7. 过滤器

filters常用于一些常见的文本格式化,把逻辑抽离以复用。

过滤器可以用在两个地方:双花括号插值v-bind表达式

<!-- 在双花括号中 -->
{{ message | capitalize }}

<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>

定义:函数的第一个参数是要过滤的值。

filters: {
  capitalize: function (value) {
    if (!value) return ''
    value = value.toString()
    return value.charAt(0).toUpperCase() + value.slice(1)
  }
}

过滤器可链式调用:
{{ message | filterA | filterB }}

因为过滤器是函数,所以还能接收多个参数,从第二个参数开始。
{{ message | filterA('arg1', arg2) }}

此外,还可以通过Vue.filter全局注册过滤器:

// 注册
Vue.filter('my-filter', function (value) {
  // 返回处理后的值
})

// getter,返回已注册的过滤器
var myFilter = Vue.filter('my-filter')

另外,如果想在methods或其他地方使用过滤器,可以利用vm实例上的$options属性,它拥有当前Vue实例的所有初始化选项(包括自定义)。所以,在methods中可以利用this.$options.filters[xxx]来使用过滤器。

8. class 与 style 绑定

vue中绑定class有两种形式:对象和数组。

如果原来有class,那么绑定的class会出现在原有class的后面。(后面覆盖前面)

当为对象时,键是要绑定的类名,且只在值有truthy时才进行绑定。注意当类名包含“-”时要加双引号。

<div :class="{ active: isActive, 'text-danger': hasError }"></div>

当为数组时,数组里每个元素就是要绑定的类,元素也可以为对象。

<div :class="[{ active: isActive }, errorClass]"></div>

当然,也可以把对象或者数组抽离出来,作为数据属性或者计算属性使用。


绑定style也有两种形式:对象和数组。

绑定的style会与原来的style合并,且当有相同的css属性时,绑定的css优先。

当为对象时,比较像CSS。但是因为是js对象,所以属性名有“-”要用小驼峰形式或者加双引号。

<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

当为数组时,可以绑定多个样式对象。

<div :style="[baseStyles, overridingStyles]"></div>

9. 表单输入绑定(双向数据绑定)

可以用v-model指令在表单元素上创建双向数据绑定。

对于普通文本元素,通过v-bind绑定的value并不能在用户输入的同时更新数据,只能通过修改数据来更新value。v-model可以做到双向数据绑定。

<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
  • 修饰符
    • v-model.lazy 相当于在触发change事件时才进行绑定
    • v-model.number 将输入的数字转为Number,如果含有parseInt无法转换的其他字符,则保持为字符串。
    • v-model.trim 过滤掉用户输入的首尾空白字符

v-model会代替掉表单元素的value、checked、selected特性。

复选框checkbox
当绑定的值初始化为布尔值时,修改选中状态得到的是true或者false

<input type="checkbox" id="checkbox" v-model="checked">
<!-- checked: true / false -->

当绑定的值初始化为数组时,修改选中状态得到的是input的自定义value值。

<input type="checkbox" value="Jack" v-model="checkedNames">
<!-- checkedNames: ["Jack"] / [] -->

单选按钮radio
绑定的值为自定义的input的value值

<input type="radio" id="one" value="One" v-model="picked">
<input type="radio" id="two" value="Two" v-model="picked">
<!-- picked: "One" / "Two" -->

选择框select:
当option没有设置value时,绑定值为option标签之间的值,反之为value值。

<select v-model="selected">
  <option disabled value="">请选择</option>
  <option value="a">A</option>
  <option>B</option>
  <option>C</option>
</select>
<!-- selected: a / B / C -->

<script>
new Vue({
  el: '...',
  data: {
    selected: ''
  }
})
</script>

当将selected初始化为空串时,如果option没有找到对应项,那么选择框将呈现出空的状态。所以比较推荐留一个不能选择的值为空的选项。

10. 组件

1. 组件注册

分为全局注册和局部注册:

全局注册:(可以在任何新创建的Vue根实例的模版及其所有子组件中使用,已注册的实例中不能使用在注册之后才全局注册的组件)

<component-a></component-a>
Vue.component('component-a', { /* ...配置... */ })

局部注册:(只能在注册其的实例中使用,不能在子组件中使用)

  • 使用局部组件相比全局组件可以节省webpack打包后不必要的大小
// 因为组件本质上就是一个Vue的配置对象,所以可以先写好再引入
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }

new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

有关组件命名:组件名最好是多个完整单词,使用驼峰或者中划线形式。如果是单个单词可能会与未来的HTML元素冲突。

2. 配置对象

template:因为组件一开始都不知道要挂载到哪里,所以要写HTML模版。只能有一个根元素。

data: 必须是一个函数,并返回数据对象。以每个实例都维护独自的数据对象。

props: 父组件传过来的数据。

Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})
<blog-post :title="My journey with Vue"></blog-post>

当需要传递一个对象的所有属性时,可以使用不带参数的v-bind指令:

<blog-post v-bind="post"></blog-post>

<!-- 相当于 -->
<blog-post :id="post.id" :title="post.title"></blog-post>

props有两种定义形式:字符串数组对象

数组仅仅列出了所有的prop:(实际操作最好使用对象的形式)
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']

对象还可以设置数据类型:
(键为prop的名称,而值又可以为prop的类型、类型数组、对象)

props: {
  likes: Number,
  title: [String, Number, Boolean, Array, Object, Function, Date, Symbol],

  propA: {
    type: Number,
    require: true,
    default: 100
  },
  propB: {
    type: Object,
    default: function () {
      return { message: 'hello' }
    }
  },
  // 自定义验证函数
  propF: {
    validator: function (value) {
      // 这个值必须匹配下列字符串中的一个
      return ['success', 'warning', 'danger'].indexOf(value) !== -1
    }
  }
}
  • 因为prop会在组件实例化之前进行验证,所以default和validator中不能使用实例的属性(data、computed等)
  • prop的命名推荐使用小驼峰形式,在HTML中使用时用kebab-case形式。

3. 通过 事件 向父组件发送消息

在子组件上通过v-on指令监听事件

<div id="app">
  <component-a @my-change="myChange"></component-a>
</div>

在子组件中,通过内置方法$emit可触发自定义事件。第一个参数为事件名称(事件名如果为多个单词应该为kebab-case的形式,驼峰形式无法在DOM元素中使用),第二个参数开始为事件的参数。

Vue.component('component-a', {
  template: `
    <button @click="$emit('my-change', 'val')">change</button>
  `
})

new Vue({
  el: '#app',
  methods: {
    // 可接收参数
    myChange(val) {
      console.log(val)
    }
  }
})

4. 监听原生事件

当想要在组件的根元素上直接监听一个原生事件时,可以使用v-on指令的.native修饰符。
例如,要监听一个原生click事件:

<my-comp @click.native="func"></my-comp>

相当于: (要自行在根元素绑定事件,并通过$emit触发时还要记得传递事件对象)

<my-comp @click="func"></my-comp>
Vue.component('myComp', {
  methods: {
    onClick (e) {
      this.$emit('click', e)
    }
  },
  template: `
    <div @click="onClick">
      <div>
        <!-- ... -->
      </div>
    </div>
  `
})

5. v-model 与 .sync修饰符

当把 v-model 用在组件上时:

<my-comp v-model="bar"></my-comp>

相当于:

<my-comp :value="bar" @input="val => bar = val"></my-comp>

为了使其正常工作,在子组件中需要用props接收value,同时,要用$emit('input', value)把新值抛出。这样就能做到"双向绑定"。

然而这样做的话,因为v-model只有一个,所以只能绑定一个值,而且子组件中prop名必须是value,触发事件必须是input,这样的限制可能也不方便。

这时就可以用 v-bind 指令配合 .sync 修饰符,这样就可以绑定多个值。

<my-comp :value.sync="bar"></my-comp>

相当于:

<my-comp :value="bar" @update:value="val => bar = val">

这样做只需要在$emit触发事件的时候把事件名命名为update:propName这种形式即可。而且通过v-bind可以绑定多个属性,prop名也可以自定义。

6. 插槽

具名插槽和插槽默认内容
组件标签之间的内容默认会替换组件中的插槽<slot></slot>

插槽可以拥有名字<slot name="xxx"></slot>,这样在要插入到插槽的标签(template也可以)添加slot属性指向要插入的插槽就可以了。没有指定插槽则默认添加到不具名插槽中。

<my-comp>
  hello world
  <h1 slot="header">Hello</h1>
  <h1 slot="footer">Bye bye</h1>
</my-comp>
Vue.component('my-comp', {
  template: `
    <div>
      <slot name="header"></slot>
      <slot></slot>
      <slot name="footer"></slot>
    </div>
  `
})

作用域插槽
普通插槽,在插入时候不能访问组件的作用域。作用域插槽可以为slot通过v-bind绑定子组件的数据。

<ul>
  <li
    v-for="todo in todos"
    v-bind:key="todo.id"
  >
    <!-- 将 `todo` 对象作为一个插槽的 prop 传入。-->
    <slot v-bind:todo="todo">
      {{ todo.text }}
    </slot>
  </li>
</ul>

在使用时,通过slot-scope就可以获取子组件的数据。传入slot-scope的是插槽作用域,是个对象,名字可以自取,也可以通过解构赋值直接取得要取的数据。

<todo-list v-bind:todos="todos">
  <!-- 将 `slotProps` 定义为插槽作用域的名字 -->
  <template slot-scope="slotProps">
    <!-- 为待办项自定义一个模板,-->
    <!-- 通过 `slotProps` 定制每个待办项。-->
    <span v-if="slotProps.todo.isComplete"></span>
    {{ slotProps.todo.text }}
  </template>
</todo-list>

解构赋值版:

<todo-list v-bind:todos="todos">
  <template slot-scope="{ todo }">
    <span v-if="todo.isComplete"></span>
    {{ todo.text }}
  </template>
</todo-list>

7. 动态组件

使用Vue内置组件<component>,并通过is特性给出需要动态渲染的已经注册的组件名或组件的选项对象

<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component :is="currentTabComponent"></component>

每次切换组件时,Vue都会创建一个新的实例。如果希望实例能被缓存下来,可以使用内置组件<keep-alive><component>包裹起来。

8. 异步组件

使用异步组件有利于按需加载。

全局注册:

Vue.component(
  'my-component',
  // 这个 `import` 函数会返回一个 `Promise` 对象。
  () => import('./my-async-component')
)

局部注册:

new Vue({
  // ...
  components: {
    'my-component': () => import('./my-async-component')
  }
})

另外,函数还能以下形式编写,来处理加载状态。

const AsyncComponent = () => ({
  // 需要加载的组件 (应该是一个 `Promise` 对象)
  component: import('./MyComponent.vue'),
  // 异步组件加载时使用的组件
  loading: LoadingComponent,
  // 加载失败时使用的组件
  error: ErrorComponent,
  // 展示加载时组件的延时时间。默认值是 200 (毫秒)
  delay: 200,
  // 如果提供了超时时间且组件加载也超时了,
  // 则使用加载失败时使用的组件。默认值是:`Infinity`
  timeout: 3000
})

9. $root、$parent、$refs

$root: 在子组件中,通过$root可以访问其根实例,从而访问根实例上的属性和方法

$refs: 在父级组件中,通过给子组件或子元素设置ref特性,进而通过$refs来访问子组件实例子元素

<base-input ref="usernameInput"></base-input>
<input ref="input">
this.$refs.usernameInput  // 获取子组件实例
this.$refs.input.focus()  // 获取子元素

$parent: 在组件中,可以访问父组件的实例。

需要向任意更深层级的组件提供上下文信息时,推荐使用依赖注入: 用到了两个新的实例选项provideinject

provide选项可以指定想要提供给后代组件的数据/方法。

provide: function () {
  return {
    getMap: this.getMap
  }
}

然后在任意后代组件中,可以使用inject选项来接收想要添加在这个实例上的属性:

inject: ["getMap"]

11. 生命周期

beforeCreate: 实例初始化之后,数据观测和event/watcher时间配置之前被调用。

created: 实例创建完成后被立即调用。实例上已完成数据观测、属性和方法的运算、watch/event事件回调。

beforeMount: 在挂载开始前被调用。

mounted: el被新创建的vm.$el替换,并挂载到实例上去后被调用。mounted不会承诺所有子元素都被一起挂载。如果希望等到整个视图都渲染完成,可以用vm.$nextTick:

mounted: function () {
  this.$nextTick(function () {
    // ...
  })
}

beforeUpdate: 在页面中被应用的数据发生改变时被调用。

  • 需要注意的是,Vue检测到数据变化,并不会立即重新渲染。Vue将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。等同步任务全部执行完后,才开始重新渲染DOM。
  • 在数据变化之后立即使用Vue.nextTick(callback),这样回调函数就会在DOM更新完成后被调用。

updated: 重新渲染完后被调用。同样不保证所有子组件也都一起被重绘,如果需要等到整个视图重绘完,可以使用vm.$nextTick替换掉updated:

updated: function () {
  this.$nextTick(function () {
    // ...
  })
}

beforeDestroy: vm.$destroy被调用时触发。

destroyed: 实例销毁后调用,所有的数据解绑,监听器移除,所有的子实例也会被销毁。

@LyzSg LyzSg added the Vue label Feb 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant