8

前言

接触vue也有一年多的时间了,一直没有做记录。作为一个前端开发者,对我而言,vue是一个正确的选择。vue的易用性,渲染能力,开发文档等等,都比较友好。最近的一段时间也在做react。

个人看法:对于框架,自己觉得顺手就行,使用框架就要尽可能发挥出框架的全部能量,html、JavaScript、css基本功要做好,这样任何js框架对你来说上手都很快。

写这篇文章主要是巩固一些知识和记录开发中的一些经验,对于初学者也有一些帮助。

本篇为基础篇,如果这些内容掌握了,那基本的开发就没有问题了。但这还不够,如果你对组件、路由、还有状态管理有深入的理解,那你会是一个优秀的前端开发者。稍后我也会把我的理解记录下来,给大家分享。

本篇内容有两部分

  1. 指令的基本用法和注意事项
  2. 周期钩子的解释和注意事项

一.引入

第一部当然是引入了,两种方式

标签引入方式
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

配合npm 模块化引入
import Vue from 'vue'

二.实例化

 var app = new Vue({
      el: '#app',//.app||document.getElementById('app')
      data: {
        message: 'Hello Vue!'
      }
    })

表示提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。

el:参数可以是css选择器,也可以是HTMLElement,但最好是id选择器,用class选择器vue会自动把class转化为id

你可能也见过这种写法,效果一样

new Vue({
  data: {
    message: 'Hello Vue!'
  }
}).$mount('#app')

三.指令

v-text与v-html

v-text被编译成不同文本,v-html不被编译,直接输出标签

<span v-text="msg"></span>
<!-- 和下面的一样 -->
<span>{{msg}}</span>

testHtml:<i>testHtml</i>
<span v-html="testHtml"></span>

输出:testHtml

<span v-text="testHtml"></span>

输出 <i>testHtml</i>

v-show与v-if

都可以说是条件判断

<span v-if="true"></span>
<span v-show="false"></span>

v-show dom元素存在,根据表达式之真假值,切换元素的 display CSS 属性。

v-if true元素存在,false元素不存在,根据表达式的值的真假条件渲染元素。

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>

v-for

列表渲染

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

建议尽可能在使用 v-for 时提供 key,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。

开发中你会遇到的事情:绑定事件,获取索引

<div v-for="(item,index) in items" :key="item.id" @click="toggle(index)">
  {{ item.text }}
</div>
new Vue({
  el: '#app',
  data: function() {
    return {
      items: [{
        id:1,
        content: '1 item',
      }, {
        id:2,
        content: '2 item',
      }, {
        id:3,
        content: '3 item',
      }]
    }
  },
  methods: {
    toggle: function(index) {
        alert(this.items[index].content)
    }
  }
})

一个对象的 v-for

new Vue({
  el: '#v-for-object',
  data: {
    object: {
      firstName: 'John',
      lastName: 'Doe',
      age: 30
    }
  }
})

<div v-for="(value, key, index) in object">
  {{ index }}. {{ key }}: {{ value }}
</div>

0. firstName: John
1. lastName: Doe
2. age: 30

v-on

事件指令
缩写 @
部分修饰符,开发中这两个基本就够了

.stop - 调用 event.stopPropagation()。
.prevent - 调用 event.preventDefault()。

<!-- 方法处理器 -->
<button v-on:click="doThis"></button>

<!-- 内联语句 -->
<button v-on:click="doThat('hello', $event)"></button>

<!-- 缩写 -->
<button @click="doThis"></button>

<!-- 停止冒泡 -->
<button @click.stop="doThis"></button>

<!-- 阻止默认行为 -->
<button @click.prevent="doThis"></button>

v-bind

属性绑定
缩写 :

<!-- 绑定一个属性 -->
<img v-bind:src="imageSrc">

<!-- 缩写 -->
<img :src="imageSrc">

<!-- class 绑定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">

<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>

<!-- 绑定一个有属性的对象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

<!-- 通过 prop 修饰符绑定 DOM 属性 -->
<div v-bind:text-content.prop="text"></div>

<!-- prop 绑定。“prop”必须在 my-component 中声明。-->
<my-component :prop="someThing"></my-component>

<!-- 通过 $props 将父组件的 props 一起传给子组件 -->
<child-component v-bind="$props"></child-component>

v-model

表单控件双向绑定
限制

  • <input>
  • <select>
  • <textarea>

修饰符

  • .lazy - 取代 input 监听 change 事件
  • .number - 输入字符串转为数字
  • .trim - 输入首尾空格过滤

四.周期钩子

注意:非常重要!非常重要!非常重要!

理解了生命周期函数,能帮助你在合适的时机做合适的事情。

vue官方api最新版本给出了11个周期函数

生命周期图示我就不贴了,官网都有

上代码,要仔细看哦~

<template>
  <div id="app1">
    <h1>{{a}}</h1>
    <h1>{{aDouble}}</h1>
    <button @click="plus">plus</button>
  </div>
</template>

<script>
export default {
  name: 'test',
  data () {
    return {
      a: 1
    }
  },
  computed: {
    aDouble () {
      return this.a * 2
    }
  },
  methods: {
    plus: function () {
      this.a++
    }
  },
  watch: {
    a: (val, oldVal) => {
      console.log(val, oldVal)
    },
    deep: true
  },
  beforeCreate () {
    console.log(this.$el) // undefined
    console.log(this.$data) // undefined
    console.log('beforeCreate 钩子执行...')
  },
  created () {
    console.log(this.$el) // undefined
    console.log(this.$data) // {__ob__: Observer} 绑定了data
    this.a++ // a:2
    this.plus() // a:3
    // 连续两次改变a的值,这里watch只执行了一次,为什么呢?这里是个异步,如果同一个 watcher 被多次触发,只会被推入到队列中一次。
    console.log('created 钩子执行...')
  },
  beforeMount () {
    console.log(this.$el) // undefined
    console.log('beforeMount 钩子执行...')
  },
  mounted () {
    console.log(this.$el) // <div id="app1">...</div>
    console.log('mounted 钩子执行...')
  },
  beforeUpdate: function () {
    // this.plus() 会触发beforeUpdate
    console.log('beforeUpdate 钩子执行...')
  },
  updated: function () {
    // this.plus() 会触发beforeUpdate
    console.log('updated 钩子执行...')
  },
  beforeDestroy: function () {
    // this.$destroy()或者是该组件被切换、路由跳转等会引发实例被销毁 会触发beforeDestroy
    console.log('beforeDestroy 钩子执行...')
  },
  destroyed: function () {
    // this.$destroy()或者是该组件被切换、路由跳转等会引发实例被销毁 会触发beforeDestroy
    console.log('destroyed 钩子执行...')
  }
}
</script>

beforeCreate

官方说明:在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。

意思就是,实例要初始化了,我准备干大事了,给你们提个醒!(你可以理解为:这个时候vue还啥都没干)

created

官方说明:在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。

意思就是:实力已经创建完成了,你写的data老子已经拿到了,你写的methods老子也拿到了,你写的watch老子也看到了(你敢动试试,我看着呢),总之呢,这个时候除了没有生成dom,其他事情都干完了。你可以选择在这里面请求一些数据。

beforeMount

官方说明:在挂载开始之前被调用:相关的 render 函数首次被调用。
意思就是:老子要生成dom,往html里面挂了,前方高能,老子要挂了!!就是告诉你要挂载到dom了,有什么事情在挂载之前做的就赶快做。

mounted

官方说明:el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。
意思就是:该做的事情都做完了,dom也有了,这个时候你可以操作dom了。

beforeUpdate

官方说明:数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
意思就是:当你的数据改变了,实例监测到了变化,就会引发beforeUpdate然后updated两个钩子,很好理解

updated

官方说明:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
意思就是:当你的数据改变了,实例监测到了变化,就会引发beforeUpdate然后updated两个钩子,很好理解

activated

keep-alive 组件激活时调用。
牵扯到路由缓存(keep-alive),讲路由的时候再详细说明

deactivated

keep-alive 组件停用时调用。
牵扯到路由缓存(keep-alive),讲路由的时候再详细说明

beforeDestroy

官方说明:实例销毁之前调用。在这一步,实例仍然完全可用。
意思就是:当实例被销毁的时候会被触发,什么时候会被销毁呢?就是当组件(从页面上消失的时候),通常是组件的切换,路由的切换等,或者主动调用this.$destroy(),先beforeDestroy然后destroyed,在开发的时候也很少用到

destroyed

官方说明:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
意思就是:当实例被销毁的时候会被触发,什么时候会被销毁呢?就是当组件(从页面上消失的时候),通常是组件的切换,路由的切换等,或者主动调用this.$destroy(),先beforeDestroy然后destroyed,在开发的时候也很少用到

errorCaptured

2.5.0+ 新增
当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
这个本人没用到过,一般不会让子组件出错。

小结:周期钩子能帮助我们理解实例被创建的过程和运行过程发生的事情,我们可以在合适的时机做合适的事情,就像约会的时候根据不同的相处时间或者感觉做出那个时候该做的事情一样,关于基础篇就先说这么多。


强子
345 声望11 粉丝

尽人事,安天命!