Vue 干货

2018/08/18 Vue

Vue.js 是什么

  • Vue是一套用于构建用户界面的渐进式框架

  • Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合

  • 当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动

  • Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性。但它支持所有兼容 ECMAScript 5 的浏览器。

    Vue 特点

  • 响应式编程

  • 组件化

  • 模块化

  • 动画

  • 路由

  • 稳定性

    开始学习 Vue

  • Hello World
<script src="https://unpkg.com/vue"></script>
<div id="app">
  <p></p>
</div>
<script>
    new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue.js!'
      }
    })
</script>

Vue 生命周期

beforeCreate

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

created

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

beforeMount

在挂载开始之前被调用:相关的 render 函数首次被调用。

mounted

el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。

beforeUpdate

数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。 你可以在这个钩子中进一步地更改状态, 这不会触发附加的重渲染过程。

updated

由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。

当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,

你应该避免在此期间更改状态,因为这可能会导致更新无限循环。

该钩子在服务器端渲染期间不被调用。

beforeDestroy

实例销毁之前调用。在这一步,实例仍然完全可用。

destroyed

Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

			生命周期图

基础模板语法

文本

//数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值
<span>Message: </span>

特性

//Mustache 语法不能作用在 HTML 特性上,遇到这种情况应该使用 v-bind 指令:
<div v-bind:id="dynamicId"></div>
// v-on 指令,它用于监听 DOM 事件
<a v-on:click="doSomething">...</a>

缩写

//因此v-bind 和 v-on 是两个最常用的指令,所以Vue.js提供了特定简写:
    <!-- 完整语法 -->
    <a v-bind:href="url">...</a>
    <!-- 缩写 -->
    <a :href="url">...</a>

    <!-- 完整语法 -->
    <a v-on:click="doSomething">...</a>
    <!-- 缩写 -->
    <a @click="doSomething">...</a>

计算属性

  • 计算属性缓存 vs 方法

计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。

调用方法将总会再次执行函数

		代码示例 html
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <p>Original message: ""</p>
  <p>Computed reversed message: ""</p>
  <!--   <p>Methods reversed message: ""</p> -->
</div>

javascript

var vm = new Vue({
  el: '#app',
  data: {
    message: 'Hello'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function() {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  },
  methods: {
    reversedMessageMethods: function() {
      return this.message.split('').reverse().join('')
    }
  }
})

  • 计算属性 vs 侦听属性

任何复杂逻辑,你都应当使用计算属性

只有当需要在数据变化时执行异步或开销较大的操作时,侦听属性才是最有用的。

html

<script src="https://unpkg.com/vue"></script>

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

javascript

//侦听属性
var vm = new Vue({
  el: '#app',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function(val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function(val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})
//计算属性(任何复杂逻辑应该使用计算属性)
/* var vm = new Vue({
  el: '#app',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
}) */

条件渲染

html

<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>

javascript

var vm = new Vue({
  el: '#app',
  data: {
    type: 'A'
  }
})

setTimeout(function() {
  vm.type = 'C'
}, 3000)

列表渲染

//key的作用主要是为了高效的更新虚拟DOM。

<div v-for=”item in items” :key=”item.id”> </div>

html

<script src="https://unpkg.com/vue"></script>

<div id="app">
  <ul>
    <li v-for="(item, index) in items" :key="item.id">
        - 
    </li>
  </ul>
</div>

javascript

var vm = new Vue({
  el: '#app',
  data: {
    items: [{
        message: 'Foo',
        id: 1
      },
      {
        message: 'Bar',
        id: 2
      }
    ]
  }
})

虚拟DOM

虚拟DOM包含的信息会告诉 Vue 页面上需要渲染什么样的节点,及其子节点。

我们把这样的节点描述为“虚拟节点 (Virtual Node)”,也常简写它为“VNode”。

“虚拟 DOM”是我们对由 Vue 组件树建立起来的整个 VNode 树的称呼。

事件

可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码,或者接收一个需要调用的方法名称

html

<script src="https://unpkg.com/vue"></script>
<div id="app">
  <button v-on:click="counter += 1">Add 1</button>
  <!-- `greet` 是在下面定义的方法名 -->
  <button v-on:click="greet">Methods Add 1</button>
  <p>The button above has been clicked  times.</p>
</div>

Vue

var vm = new Vue({
  el: '#app',
  data: {
    counter: 0
  },
  methods: {
    greet: function (event) {
      this.counter++
    }
  }
})

表单输入绑定

你可以用 v-model 指令在表单<input><textarea> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新

元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特

殊处理。

html

<script src="https://unpkg.com/vue"></script>

<div id="app">
  <input v-model="message" placeholder="edit me">
  <p>Message is: </p>
</div>

javascript

var vm = new Vue({
  el: '#app',
  data: {
    message: ''
  }
})

组件

html

<script src="https://unpkg.com/vue"></script>

<div id="components-dem">
  <button-counter></button-counter>
</div>

javascript

// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
  data: function() {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me 8 times.</button>'
})
var vm = new Vue({
  el: '#components-dem'
})

组件进阶

  • 通过 Prop 向子组件传递数据

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,

但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。 html

<script src="https://unpkg.com/vue"></script>

<div id="app">
  <blog-post title="My journey with Vue"></blog-post>
  <blog-post title="Blogging with Vue"></blog-post>
  <blog-post title="Why Vue is so fun"></blog-post>
  <!-- <blog-post
  v-for="post in posts"
  v-bind:key="post.id"
  v-bind:title="post.title"
  ></blog-post> -->
</div>

javascript

Vue.component('blog-post', {
  props: ['title'],
  //每个 prop 都有指定的值类型
  /* props: {
    title: String
  }, */
  template: '<h3></h3>'
})
var vm = new Vue({
  el: '#app',
  /* data: {
    posts: [{
        id: 1,
        title: 'My journey with Vue'
      },
      {
        id: 2,
        title: 'Blogging with Vue'
      },
      {
        id: 3,
        title: 'Why Vue is so fun'
      }
    ]
  } */
})

  • 每个组件必须只有一个根元素否则Vue 会显示一个错误

  • 通过事件向父级组件发送消息

调用内建的 $emit 方法并传入事件的名字,来向父级组件触发一个事件

html

<script src="https://unpkg.com/vue"></script>

<div id="app">
  <div :style="{ fontSize: postFontSize + 'em' }">
    <blog-post v-for="post in posts" v-bind:key="post.id" v-bind:post="post" v-on:enlarge-text="postFontSize += 0.1"></blog-post>
  </div>
</div>

javascript

Vue.component('blog-post', {
  props: ['post'],
  template: `
    <div class="blog-post">
      <h3></h3>
      <button v-on:click="$emit('enlarge-text')">
        Enlarge text
      </button>
      <div v-html="post.content"></div>
    </div>
  `
})
var vm = new Vue({
  el: '#app',
  data: {
    postFontSize: 1,
    posts: [{
      id: 1,
      title: 'title',
      content: 'My journey with Vue'
    }]
  }
})

过度

codepen.io/sdras/pen/LLvdQL codepen.io/itslit/pen/gvKrMY

## Vue进阶

  • Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,

并以相应的规则保证状态以一种可预测的方式发生变化

Vuex

  • Vue Router

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌

Vue Router

Vue资源列表

论坛

风格指南

vue-devtools

聊天室

官方仓库

Vue 优选

Vue 资源

Search

    Post Directory