前端MVC Vue2学习总结(二)——Vue的实例、生命周期与Vue脚手架(vue-cli)

目录

一、Vue 的实例

1.1、创建一个 Vue 的实例

每个 Vue 应用都是通过 Vue 函数创建一个新的 Vue 实例开始的:

var vm = new Vue({
// 选项
})

虽然没有完全遵循 MVVM 模型,Vue 的设计无疑受到了它的启发。因此在文档中经常会使用 vm (ViewModel 的简称) 这个变量名表示 Vue 实例。

1、vue.js 就是一个构造器,通过构造器 Vue 来实例化一个对象;例如:var vm = new Vue({});
2、实例化 Vue 时,需要传入一个参数(选项对象);
3、参数:选项对象可以包含,数据 (data)、挂载元素 (el)、方法 (methods)、模版 (template)、生命周期函数等等;
4、扩展构造器 Vue,从而用预定义选项创建可复用的组件构造器,所有组件都是被扩展的 Vue 的实例,使用 Vue.extend({}) 来扩展;
注意:尽管可以命令式地创建扩展实例,不过在多数情况下建议将组件构造器注册为一个自定义元素,然后声明式地用在模板中。

当创建一个 Vue 实例时,你可以传入一个选项对象。这篇教程主要描述的就是如何使用这些选项来创建你想要的行为。作为参考,你也可以在 API 文档 中浏览完整的选项列表。
一个 Vue 应用由一个通过 new Vue 创建的根 Vue 实例,以及可选的嵌套的、可复用的组件树组成。举个例子,一个 todo 应用的组件树可以是这样的:

Root Instance
└─ TodoList
├─ TodoItem
│ ├─ DeleteTodoButton
│ └─ EditTodoButton
└─ TodoListFooter
├─ ClearTodosButton
└─ TodoListStatistics

我们会在稍后的组件系统章节具体展开。不过现在,你只需要明白所有的 Vue 组件都是 Vue 实例,并且接受相同的选项对象即可 (一些根实例特有的选项除外)。

1.2、数据与方法

当一个 Vue 实例被创建时,它向 Vue 的响应式系统中加入了其 data 对象中能找到的所有的属性。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。

// 我们的数据对象
var data = { a: 1 }

// 该对象被加入到一个 Vue 实例中
var vm = new Vue({
data: data
})

// 他们引用相同的对象!
vm.a === data.a // => true

// 设置属性也会影响到原始数据
vm.a = 2
data.a
// => 2

// ... 反之亦然
data.a = 3
vm.a
// => 3

当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时 data 中存在的属性是响应式的。也就是说如果你添加一个新的属性,像:

vm.b = 'hi'

那么对 b 的改动将不会触发任何视图的更新。

示例:

<!DOCTYPE html>
<html>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">meta </span><span style="color: rgba(255, 0, 0, 1)">charset</span><span style="color: rgba(0, 0, 255, 1)">="UTF-8"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">title</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>vue2实例<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">title</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="app1"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">input </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text"</span><span style="color: rgba(255, 0, 0, 1)"> v-model</span><span style="color: rgba(0, 0, 255, 1)">="a"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">src</span><span style="color: rgba(0, 0, 255, 1)">="../js/vue.js"</span><span style="color: rgba(255, 0, 0, 1)"> type</span><span style="color: rgba(0, 0, 255, 1)">="text/javascript"</span><span style="color: rgba(255, 0, 0, 1)"> charset</span><span style="color: rgba(0, 0, 255, 1)">="utf-8"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text/javascript"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> data</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">{a:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">1</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">}
        </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">实例</span>
        <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> vm </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">new</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> Vue({
            el: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">#app1</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">,
            data:data,
            updated:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">(){
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">实例被更新了!</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
            }
        });
    </span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

</html>

结果:

如果你知道你会在晚些时候需要一个属性,但是一开始它为空或不存在,那么你仅需要设置一些初始值。比如:

data: {
newTodoText: '',
visitCount: 0,
hideCompletedTodos: false,
todos: [],
error: null
}

除了 data 属性,Vue 实例暴露了一些有用的实例属性与方法。它们都有前缀 $,以便与用户定义的属性区分开来。例如:

var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})

vm.$data === data // => true
vm.$el === document.getElementById('example') // => true

// $watch 是一个实例方法
vm.$watch('a', function (newValue, oldValue) {
// 这个回调将在 vm.a 改变后调用
})

在未来,你可以在 API 参考查阅到完整的实例属性和方法的列表

1.3、实例属性

解释

vm._uid // 自增的 id
vm._isVue // 标示是 vue 对象,避免被 observe
vm._renderProxy // Proxy 代理对象
vm._self // 当前 vm 实例

vm.$parent // 用于自定义子组件中,指向父组件的实例
vm.$root // 指向根 vm 实例
vm.$children // 当前组件的子组件实例数组
vm.$refs 

vm._watcher = null
vm._inactive
= null
vm._directInactive
= false
vm._isMounted
= false // 标识是否已挂载
vm._isDestroyed = false // 标识是否已销毁
vm._isBeingDestroyed = false // 标识是否正在销毁

vm._events
// 当前元素上绑定的自定义事件
vm._hasHookEvent // 标示是否有 hook: 开头的事件

vm.$vnode
// 当前自定义组件在父组件中的 vnode,等同于 vm.$options._parentVnode
vm._vnode // 当前组件的 vnode
vm._staticTrees // 当前组件模板内分析出的静态内容的 render 函数数组
vm.$el // 当前组件对应的根元素

vm.$slots
// 定义在父组件中的 slots,是个对象键为 name,值为响应的数组
vm.$scopedSlots = emptyObject
// 内部 render 函数使用的创建 vnode 的方法
vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)
// 用户自定义 render 方法时,传入的参数
vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)

vm._props // 被 observe 的存储 props 数据的对象
vm._data // 被 observe 的存储 data 数据的对象
vm._computedWatchers // 保存计算属性创建的 watcher 对象

1.4、实例方法

1.5、实例参数 vm.$options

vm.$options 其实也就是我们 new Vue(options)options 这个选项对象可传入的属性

declare type ComponentOptions = {
  // data
  data: Object | Function | void;  // 传入的 data 数据
  props?: {[key: string]: PropOptions }; // props 传入的数据
  propsData?: ?Object;  // 对于自定义组件,父级通过 `props` 传过来的数据
  computed?: {  // 传入的计算属性
    [key: string]: Function | {
      get?: Function;
      set?: Function;
      cache?: boolean
    }
  };
  methods?: {[key: string]: Function }; // 传入的方法
  watch?: {[key: string]: Function | string };  // 传入的 watch

// DOM
el?: string | Element; // 传入的 el 字符串
template?: string; // 传入的模板字符串
render: (h: () => VNode) => VNode; // 传入的 render 函数
renderError?: (h: () => VNode, err: Error) => VNode;
staticRenderFns
?: Array<() => VNode>;

// 钩子函数
beforeCreate?: Function;
created
?: Function;
beforeMount
?: Function;
mounted
?: Function;
beforeUpdate
?: Function;
updated
?: Function;
activated
?: Function;
deactivated
?: Function;
beforeDestroy
?: Function;
destroyed
?: Function;

// assets
directives?: {[key: string]: Object }; // 指令
components?: {[key: string]: Class<Component> }; // 子组件的定义
transitions?: {[key: string]: Object };
filters
?: {[key: string]: Function }; // 过滤器

// context
provide?: {[key: string | Symbol]: any } | () => { [key: string | Symbol]: any };
inject
?: {[key: string]: string | Symbol } | Array<string>;

// component v-model customization
model?: {
prop
?: string;
event
?: string;
};

// misc
parent?: Component; // 父组件实例
mixins?: Array<Object>; // mixins 传入的数据
name?: string; // 当前的组件名
extends?: Class<Component> | Object; // extends 传入的数据
delimiters?: [string, string]; // 模板分隔符

// 私有属性,均为内部创建自定义组件的对象时使用
_isComponent?: true; // 是否是组件
_propKeys?: Array<string>; // props 传入对象的键数组
_parentVnode?: VNode; // 当前组件,在父组件中的 VNode 对象
_parentListeners?: ?Object; // 当前组件,在父组件上绑定的事件
_renderChildren?: ?Array<VNode>; // 父组件中定义在当前元素内的子元素的 VNode 数组(slot)
_componentTag: ?string; // 自定义标签名
_scopeId: ?string;
_base: Class
<Component>; // Vue
_parentElm: ?Node; // 当前自定义组件的父级 dom 结点
_refElm: ?Node; // 当前元素的 nextSlibing 元素,即当前 dom 要插入到 _parentElm 结点下的 _refElm 前
}

1.5.1、computed 计算属性

在模板中绑定表达式是非常便利的,但是它们实际上只用于简单的操作。在模板中放入太多的逻辑会让模板过重且难以维护。例如: 

<span>{{msg.split('').reverse().join('')}}</span>

使用计算属性定义成一个方法可以复用且模板会更加简洁:

<!DOCTYPE html>
<html>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">meta </span><span style="color: rgba(255, 0, 0, 1)">charset</span><span style="color: rgba(0, 0, 255, 1)">="UTF-8"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">title</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>vue2实例<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">title</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="app1"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">input </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text"</span><span style="color: rgba(255, 0, 0, 1)"> v-model</span><span style="color: rgba(0, 0, 255, 1)">="msg"</span> <span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>{{msg.split('').reverse().join('')}}<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">input </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text"</span><span style="color: rgba(255, 0, 0, 1)"> v-model</span><span style="color: rgba(0, 0, 255, 1)">="msg"</span> <span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>{{revMsg}}<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">src</span><span style="color: rgba(0, 0, 255, 1)">="../js/vue.js"</span><span style="color: rgba(255, 0, 0, 1)"> type</span><span style="color: rgba(0, 0, 255, 1)">="text/javascript"</span><span style="color: rgba(255, 0, 0, 1)"> charset</span><span style="color: rgba(0, 0, 255, 1)">="utf-8"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text/javascript"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> app1 </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">new</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> Vue({
            el: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">#app1</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">,
            data: {
                msg: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">hello</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
            },
            computed: {
                revMsg: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">() {
                    </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">return</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">this</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">.msg.split(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">''</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">).reverse().join(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">''</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
                }
            }
        });
    </span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

</html>

结果:

注意:

1、computed 中定义的方法只允许当着属性用,不能带参数,这限制它的复用性。

2、当方法中的属性发生变化时方法将重新调用

3、不应该使用箭头函数来定义计算属性函数 

4、 computed 计算属性可以对属性进行缓存的,计算属性只有当该属性发生变化的时候才会重新计算值

5、如果一个属性不能完成需要的功能时可以考虑转成计算

1.5.2、watch 计算属性

一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。

示例:

<!DOCTYPE html>
<html>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">meta </span><span style="color: rgba(255, 0, 0, 1)">charset</span><span style="color: rgba(0, 0, 255, 1)">="UTF-8"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">title</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>vue2实例<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">title</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="app1"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
            a:
            </span><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">input </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text"</span><span style="color: rgba(255, 0, 0, 1)"> v-model</span><span style="color: rgba(0, 0, 255, 1)">="a"</span> <span style="color: rgba(0, 0, 255, 1)">/&gt;</span>{{a}}<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">br</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span><span style="color: rgba(0, 0, 0, 1)"> b:
            </span><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">input </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text"</span><span style="color: rgba(255, 0, 0, 1)"> v-model</span><span style="color: rgba(0, 0, 255, 1)">="b"</span> <span style="color: rgba(0, 0, 255, 1)">/&gt;</span>{{b}}<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">br</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span><span style="color: rgba(0, 0, 0, 1)"> c:
            </span><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">input </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text"</span><span style="color: rgba(255, 0, 0, 1)"> v-model</span><span style="color: rgba(0, 0, 255, 1)">="c.x.y.z"</span> <span style="color: rgba(0, 0, 255, 1)">/&gt;</span>{{c.x.y.z}}<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">br</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span><span style="color: rgba(0, 0, 0, 1)"> d:
            </span><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">input </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text"</span><span style="color: rgba(255, 0, 0, 1)"> v-model</span><span style="color: rgba(0, 0, 255, 1)">="d"</span> <span style="color: rgba(0, 0, 255, 1)">/&gt;</span>{{d}}<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">br</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
            n:</span><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">input </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text"</span><span style="color: rgba(255, 0, 0, 1)"> v-model</span><span style="color: rgba(0, 0, 255, 1)">="c.x.y.n"</span> <span style="color: rgba(0, 0, 255, 1)">/&gt;</span><span style="color: rgba(0, 0, 0, 1)">{{c.x.y.n}}
        </span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">src</span><span style="color: rgba(0, 0, 255, 1)">="../js/vue.js"</span><span style="color: rgba(255, 0, 0, 1)"> type</span><span style="color: rgba(0, 0, 255, 1)">="text/javascript"</span><span style="color: rgba(255, 0, 0, 1)"> charset</span><span style="color: rgba(0, 0, 255, 1)">="utf-8"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text/javascript"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> app1 </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">new</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> Vue({
            el: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">#app1</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">,
            data: {
                a: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">1</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">,
                b: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">2</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">,
                c: {
                    x: {
                        y: {
                            z: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">3</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">,
                            n: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">3</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
                        }
                    }
                },
                d: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">4</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
            },
            watch: {
                a: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">(val, oldVal) {
                    console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">a新: %5s, 原: %5s</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">, val, oldVal);
                },
                </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)"> 方法名</span>

b: 'watchb',
//对象,深度监视
c: {
handler:
function(val, oldVal) {
console.log(
'c 新: %5s, 原: %5s', JSON.stringify(val),JSON.stringify(oldVal));
},
deep:
true
},
//立即监视
d: {
handler:
function(val, oldVal) {
console.log(
'c 新: %5s, 原: %5s', val,oldVal);
},
immediate:
true //设置初始值时也将调用
}
},
methods: {
watchb:
function(val, oldVal) {
console.log(
'b 新: %5s, 原: %5s', val, oldVal);
}
}
});

        </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> watchb </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">(val, oldVal) {
            console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">b新: %5s, 原: %5s</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">, val, oldVal);
        }
    </span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

</html>

结果:

注意:不应该使用箭头函数来定义 watcher 函数、对象类型时并非深拷贝的,只是引用。

1.5.3、方法 methods

methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的 this 自动绑定为 Vue 实例。

var vm = new Vue({
  data: { a: 1 },
  methods: {
    plus: function () {
      this.a++
    }
  }
})vm.plus()
vm.a // 2

 示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>vue2 实例</title>
    </head>
    <body>
        <div id="app1">
            <button type="button" v-on:click="add(2)">{{msg}}</button>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var app1 = new Vue({
                el: "#app1",
                data:{
                    msg:"vue"
                },
                methods:{
                    add:function(str){
                        return this.msg+=str;
                    }
                }
            });
            console.log(app1.add(3));
        </script>
    </body>

</html>

结果:

注意,不应该使用箭头函数来定义 method 函数 (例如 plus: () => this.a++)。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.a 将是 undefined。

1.5.4、小结

computed 是计算属性的,methods 是计算方法的,最主要的区别是 computed 计算属性可以对
属性进行缓存的,计算属性只有当该属性发生变化的时候才会重新计算值,只要值没有改变,它是不会重新渲染的,但是 methods 方法不同,每次调用该方法的时候,都会重新执行的。

1、每个 Vue 的实例都会代理其 data 对象里的所有属性,被代理的属性是响应的;

2、如果实例创建之后添加新的属性到实例上,不会触发视图更新;

3、不要在实例属性或者回调函数中(如 vm.$watch('a', newVal => this.myMethod()))使用箭头函数。因为箭头函数绑定父上下文,所以 this 不会像预想的一样是 Vue 实例,而是 this.myMethod 未被定义。

4、Vue 实例暴露了一些有用的实例属性和方法,带有前缀 $ 便于与代理的 data 区分

a、vm.$el:类型(HTMLElement)挂载元素,Vue 实例的 DOM 根元素;
b、vm.$data:类型(Object),Vue 实例观察的数据对象
c、vm.$props:类型(Object),属性
d、vm.$options:类型(Object),用于当前 Vue 实例的初始化选项,在选项中需要包含自定义属性的时候很有用。
e、vm.$parent:类型(Vue 实例),父实例。
f、vm.$root:类型(Vue 实例),当前组件树的根 Vue 实例,如果没有父实例,就是实例本身。
h、vm.$children:类型(Array(Vue 实例)),当前实例的直接子组件
需要注意 $children 并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用 $children 来进行数据绑定,考虑使用一个数组配合 v-for 来生成子组件,并且使用 Array 作为真正的来源。
i、vm.$slots:类型({[name: string]: ?Array<VNode> }),用来访问被 slot 分发的内容。每个具名 slot 有其相应的属性(例如:slot="foo" 中的内容将会在 vm.$slots.foo 中被找到)。default 属性包括了所有没有被包含在具名 slot 中的节点。
k、vm.$refs:类型(Object),一个对象,其中包含了所有拥有 ref 注册的子组件;
l、vm.$isServer:类型(boolean),当前 Vue 实例是否运行于服务器;

官网对应

1.5.5、箭头函数

箭头函数是 ES6 引入的一种语法糖,使得写函数更加简便,类似 Lambda 表达式,基本格式如下:

()=>{}

示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>vue2 实例</title>
    </head>
    <body>
        <div id="app1">
        </div>
        <script type="text/javascript">
            var m1=a=>a+1;
            console.log(m1(100));
            //类似
            var m2=function(a){
                return a+1;
            }
            console.log(m2(100));
        </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> m3</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">(a,b)</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=&gt;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">a</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">+</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">b;
        console.log(m3(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">100</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">,</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">200</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">));
        
        </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> m4</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">(a,b)</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=&gt;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">{a</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">++</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">; b</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">++</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">; </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">return</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> a</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">+</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">b;};  </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">如果方法体中有多个表达式,则需要大括号与return</span>

console.log(m4(100,200));
</script>
</body>

</html>

结果:

二、生命周期

2.1、实例生命周期

每个 Vue 实例在被创建之前都要经过一系列的初始化过程。例如需要设置数据监听、编译模板、挂载实例到 DOM、在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,给予用户机会在一些特定的场景下添加他们自己的代码。
比如 created 钩子可以用来在一个实例被创建之后执行代码:

new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 实例
console.log('a is:' + this.a)}})
// => "a is: 1"


也有一些其它的钩子,在实例生命周期的不同场景下调用,如 mounted、updated、destroyed。钩子的 this 指向调用它的 Vue 实例。
不要在选项属性或回调上使用箭头函数,比如 created: ()=> console.log(this.a) 或 vm.$watch('a', newValue => this.myMethod())。因为箭头函数是和父级上下文绑定在一起的,this 不会是如你所预期的 Vue 实例,经常导致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之类的错误。

2.2、生命周期图示

下图说明了实例的生命周期。你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。

中文版:

 

1. beforeCreate

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

2. created

实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。 可以在组件的这个期间请求数据,如果是 keep-alive 组件会被缓存起来,生命周期不会再次触发,如果需要更新数据可以 watch 当前 router 变化,如果 router 是当前组件所在的 router 则请求数据。

methods : {
getData : function(id){
...
this.content = 'test';
}
},
created : function(){
this.getData(this.id);}
...
watch : {
$route : function(){
if(this.$route.name == 'xxx'){
this.getData(this.id);}
}
}

3. beforeMount

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

4. mounted

vm.$el 已挂载在文档内,对已有 dom 节点的操作可以在这期间进行。

5. beforeUpdate

数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。

可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。

6.updated

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

当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。

7.activated

keep-alive 组件激活时调用。

8.deactivated

keep-alive 组件停用时调用。

9.beforeDestroy

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

10.destroyed

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

2.2.0、控制台输出技巧

console.log 支持的格式标志有:

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    var tom={name:"tom",age:10};
    console.group("开始");
    console.group("第一组");
    console.log("%c%s%o","background:red;color:yellow;",'对象是:',tom);
    console.groupEnd();
console.group(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">第二组</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">%c%s%o</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">,</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">background:red;color:yellow;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">,</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">对象是:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">,tom);
console.groupEnd();

console.group(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">第三组</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">%c%s%o</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">,</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">background:red;color:yellow;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">,</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">对象是:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">,tom);
console.groupEnd();
console.groupEnd();

</script>
</body>
</html>

结果:

2.3、生命周期示例一

示例 1:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>vue2 生命周期</title>
    </head>
    <body>
        <div id="app1">
            <input v-model="msg" /> {{msg}}
        </div>
        <button type="button" onclick="destroy()">销毁</button>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            //格式化输出
            console.log("示例:%c%s","background:red;color:#fff","vue2 生命周期","开始了");
        </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> app1 </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">new</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> Vue({
            el: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">#app1</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">,
            data:{
                msg:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">vue</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
            },
            beforeCreate:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">(){
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">创建前:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">+</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">this</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">.msg);
            },
            created:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">(){
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">创建后:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">+</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">this</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">.msg</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">+</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">,</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">+</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">this</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">.$el);
            },
            beforeMount:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">(){
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">挂载前:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">this</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">.$el);
            },
            mounted:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">(){
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">挂载后:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">this</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">.$el);
            },
            beforeUpdate:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">(){
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">实例更新前:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">this</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">.msg);
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">this</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">.$el);
            },
            updated:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">(){
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">实例更新后:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">this</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">.msg);
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">this</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">.$el);
            },
            beforeDestroy:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">(){
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">实例销毁前:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">this</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">.msg);                                        
            },
            destroyed:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">(){
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">实例销毁后:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
                console.log(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">this</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">.msg);
            }
        });
        
        </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> destroy(){
            app1.$destroy();
        }
    </span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

</html>

初始化结果 1:

修改 msg 的值为 vue2 后的结果:

执行销毁:

2.4、生命周期示例二

示例 2:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Vue2 Demo</title>
</head>
<body>
<div id="app01">
    <h2>{{name}}</h2>
    <button @click="changename">修改 name</button>
    <button @click="over">销毁实例</button>
</div>
<script src="../../js/vue/vue.min.js"></script>
<script>
    var vm = new Vue({
        data: {
            name: 'zhangguo',
            bar:"test"
        },
        el: "#app01",
        methods: {
            changename: function () {
                this.name += ',Hello';
            },
            over:function () {
                //销毁实例
                this.$destroy();}
        },
        beforeCreate: function () {
            console.group('1、beforeCreate 创建前状态 ===============》');
            console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
            console.log("%c%o", "color:red", "data   : " + this.$data); //undefined
            console.log("%c%s", "color:red", "name: " + this.name); //undefined
            console.groupEnd() },
        created: function () {
            console.group('2、created 创建后状态 ===============》');
            console.log("%c%s", "color:red", "el     : " + this.$el);
            console.log("%c%s", "color:red", "data   : " + JSON.stringify(this.$data));
            console.log("%c%s", "color:red", "name: " + this.name);
            console.groupEnd() },
        beforeMount: function () {
            console.group('3、beforeMount 挂载前 ===============》');
            console.log("%c%s", "color:red", "el     : ", this.$el);
            console.log("%c%s", "color:red", "data   : " + JSON.stringify(this.$data));
            console.log("%c%s", "color:red", "name: " + this.name);
            console.groupEnd() },
        mounted: function () {
            console.group('4、mounted 挂载后 ===============》');
            console.log("%c%s", "color:red", "el     : ", this.$el);
            console.log("%c%s", "color:red", "data   : " + JSON.stringify(this.$data));
            console.log("%c%s", "color:red", "name: " + this.name);
            console.groupEnd() },
        beforeUpdate: function () {
            console.group('5、beforeUpdate 视图更新前 ===============》');
            console.log("%c%s", "color:red", "el     : ", this.$el.innerHTML);
            console.log("%c%s", "color:red", "data   : " + JSON.stringify(this.$data));
            console.log("%c%s", "color:red", "name: " + this.name);
            console.groupEnd() },
        updated: function () {
            console.group('6、updated 视图更新后 ===============》');
            console.log("%c%s", "color:red", "el     : ", this.$el.innerHTML);
            console.log("%c%s", "color:red", "data   : " + JSON.stringify(this.$data));
            console.log("%c%s", "color:red", "name: " + this.name);
            console.groupEnd() },
        beforeDestroy: function () {
            console.group('7、beforeDestroy 实例销毁前 ===============》');
            console.log("%c%s", "color:red", "el     : ", this.$el.innerHTML);
            console.log("%c%s", "color:red", "data   : " + JSON.stringify(this.$data));
            console.log("%c%s", "color:red", "name: " + this.name);
            console.groupEnd() }
        ,
        destroyed: function () {
            console.group('8、beforeDestroy 实例销毁后 ===============》');
            console.log("%c%s", "color:red", "el     : ", this.$el.innerHTML);
            console.log("%c%s", "color:red", "data   : " + JSON.stringify(this.$data));
            console.log("%c%s", "color:red", "name: " + this.name);
            console.groupEnd()}});
</script>
</body>
</html>

 

初始化结果:

更新 name 的值:

销毁实例

2.5、手动挂载与调用事件

2.5.1、手动挂载

vm.$mount([elementOrSelector] )如果 Vue 实例在实例化时没有收到 el 选项,则它处于“未挂载”状态,没有关联的 DOM 元素。可以使用 vm.$mount() 手动地挂载一个未挂载的实例。

如果没有提供 elementOrSelector 参数,模板将被渲染为文档之外的的元素,并且你必须使用原生 DOM API 把它插入文档中。
这个方法返回实例自身,因而可以链式调用其它实例方法。

var MyComponent = Vue.extend({
template: '<div>Hello!</div>'
})

// 创建并挂载到 #app (会替换 #app)
new MyComponent().$mount('#app')

// 同上
new MyComponent({ el: '#app' })

// 或者,在文档之外渲染并且随后挂载
var component = new MyComponent().$mount()
document.getElementById(
'app').appendChild(component.$el)

示例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Vue2 Demo</title>
</head>
<body>
<div id="app01">
</div>
<button type="button" onclick="mount01()">手动挂载方法 1</button>
<button type="button" onclick="mount02()">手动挂载方法 2</button>
<button type="button" onclick="mount03()">手动挂载方法 3</button>
<script src="../../js/vue/vue.min.js"></script>
<script>
    var vm = new Vue({
        data: {
            name: 'zhangguo'
        },
        template:'<h2>{{name}}</h2>'
    });
</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> mount01() {
    </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">方法1</span>
    <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">手动挂载到指定DOM</span>

vm.$mount("#app01");
}

</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> mount02() {
    </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">方法1</span>
    <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">手动挂载,触发编译</span>

vm.$mount();
//将编译生成的内容元素添加到要挂载的 DOM 中,作为子元素
document.getElementById("app01").appendChild(vm.$el);
}

</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> mount03() {
    </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">扩展出一个新的Vue构造器</span>
    <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> Component01</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">Vue.extend({
        template:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">&lt;h2&gt;{{name}}&lt;/h2&gt;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
    });

    </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> c01</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">new</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> Component01({
        data: {
            name: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">zhangguo</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
        },
        el:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">#app01</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
    });
}

</script>
</body>
</html>

运行结果:

2.5.2、销毁实例

vm.$destroy() 完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器。

2.5.3、强制更新

vm.$forceUpdate() 迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。

三、Vue 脚手架(vue-cli)

单页 Web 应用(single page web application,SPA),就是只有一张 Web 页面的应用,是加载单个 HTML 页面并在用户与应用程序交互时动态更新该页面的 Web 应用程序。

提供一个官方命令行工具,可用于快速搭建大型单页应用(SPA)。该工具为现代化的前端开发工作流提供了开箱即用的构建配置。只需几分钟即可创建并启动一个带热重载、保存时静态检查以及可用于生产环境的构建配置的项目:

# 全局安装 vue-cli
$ npm install --global vue-cli
# 创建一个基于 webpack 模板的新项目
$ vue init webpack my-project
# 安装依赖,走你
$ cd my-project
$ npm install
$ npm run dev

注意:CLI 工具假定用户对 Node.js 和相关构建工具有一定程度的了解。如果你是新手,我们强烈建议先在不用构建工具的情况下通读指南,在熟悉 Vue 本身之后再使用 CLI。

3.1、环境搭建

3.1.1、安装 node.js

从 node.js 官网下载并安装 node,安装过程很简单,一路“下一步”就可以了。安装完成之后,打开命令行工具 (win+r,然后输入 cmd),输入 node -v,如下图,如果出现相应的版本号,则说明安装成功。

如果安装不成功,可以直接把安装包修改成压缩包,解压后配置环境变量也可以,就成了绿色版。

 

这里需要说明下,因为在官网下载安装 node.js 后,就已经自带 npm(包管理工具)了,另需要注意的是 npm 的版本最好是 3.x.x 以上,以免对后续产生影响。

注意版本不能太低,如果您已经安装了低版本的 node 可以使用 npm 直接更新。

3.1.2、修改 npm 为淘宝镜像

因为 npm 的仓库有许多在国外,访问的速度较慢,建议修改成 cnpm,换成 taobao 的镜像。

打开命令行工具,复制如下配置:

npm install -g cnpm --registry=https://registry.npm.taobao.org

安装这里是因为我们用的 npm 的服务器是外国,有的时候我们安装“依赖”的时候很很慢很慢超级慢,所以就用这个 cnpm 来安装我们说需要的“依赖”。安装完成之后输入 cnpm -v,如下图,如果出现相应的版本号,则说明安装成功。

版本号:

3.1.3、安装 webpack

安装 webpack,打开命令行工具输入:

npm install webpack -g

安装完成之后输入

webpack -v

如下图,如果出现相应的版本号,则说明安装成功。

3.1.4、安装 vue-cli 脚手架构建工具

打开命令行工具输入:

cnpm install vue-cli -g

安装完成之后输入 vue -V(注意这里是大写的“V”),如下图,如果出现相应的版本号,则说明安装成功。

3.2、构建项目

1)、在硬盘上找一个文件夹放工程用的。这里有两种方式指定到相关目录:

①cd 目录路径

②如果以安装 git 的,在相关目录右键选择 Git Bash Here

2)、安装 vue 脚手架输入:vue init webpack projectName,注意这里的“projectName” 是项目的名称可以说是随便的起名,但是“不能用中文”。

提示选择项:

$ vue init webpack exprice --------------------- 这个是那个安装 vue 脚手架的命令
This will install Vue 2.x version of the template. --------------------- 这里说明将要创建一个 vue 2.x 版本的项目
For Vue 1.x use: vue init webpack#1.0 exprice
? Project name (exprice) ---------------------项目名称
? Project name exprice
? Project description (A Vue.js project) ---------------------项目描述
? Project description A Vue.js project
? Author Datura --------------------- 项目创建者
? Author Datura
? Vue build (Use arrow keys)
? Vue build standalone
? Install vue-router? (Y/n) --------------------- 是否安装 Vue 路由,也就是以后是 spa(但页面应用需要的模块)
? Install vue-router? Yes
? Use ESLint to lint your code? (Y/n) n ---------------------是否启用 eslint 检测规则,这里个人建议选 no
? Use ESLint to lint your code? No
? Setup unit tests with Karma + Mocha? (Y/n)
? Setup unit tests with Karma + Mocha? Yes
? Setup e2e tests with Nightwatch? (Y/n)
? Setup e2e tests with Nightwatch? Yes
vue-cli · Generated "exprice".
To get started: --------------------- 这里说明如何启动这个服务
cd exprice
npm install
npm run dev
View Code

3)、cd 命令进入创建的工程目录,首先 cd projectName;

4)、安装项目依赖:npm install,因为自动构建过程中已存在 package.json 文件,所以这里直接安装依赖就行。不要从国内镜像 cnpm 安装 (会导致后面缺了很多依赖库),但是但是如果真的安装“个把”小时也没成功那就用:cnpm install 吧

5)、安装 vue 路由模块 vue-router 和网络请求模块 vue-resource,输入:cnpm install vue-router vue-resource --save。

目录:

|-- build                            // 项目构建 (webpack) 相关代码
|   |-- build.js                     // 生产环境构建代码
|   |-- check-version.js             // 检查 node、npm 等版本
|   |-- dev-client.js                // 热重载相关
|   |-- dev-server.js                // 构建本地服务器
|   |-- utils.js                     // 构建工具相关
|   |-- webpack.base.conf.js         // webpack 基础配置
|   |-- webpack.dev.conf.js          // webpack 开发环境配置
|   |-- webpack.prod.conf.js         // webpack 生产环境配置
|-- config                           // 项目开发环境配置
|   |-- dev.env.js                   // 开发环境变量
|   |-- index.js                     // 项目一些配置变量
|   |-- prod.env.js                  // 生产环境变量
|   |-- test.env.js                  // 测试环境变量
|-- src                              // 源码目录
|   |-- components                     // vue 公共组件
|   |-- store                          // vuex 的状态管理
|   |-- App.vue                        // 页面入口文件
|   |-- main.js                        // 程序入口文件,加载各种公共组件
|-- static                           // 静态文件,比如一些图片,json 数据等
|   |-- data                           // 群聊分析得到的数据用于数据可视化
|-- .babelrc                         // ES6 语法编译配置
|-- .editorconfig                    // 定义代码格式
|-- .gitignore                       // git 上传需要忽略的文件格式
|-- README.md                        // 项目说明
|-- favicon.ico 
|-- index.html                       // 入口页面
|-- package.json                     // 项目基本信息

3.3、运行项目

6)、启动项目,输入:npm run dev。服务启动成功后浏览器会默认打开一个“欢迎页面”,如下图:

编译成功后可以直接在浏览器中查看项目:

3.4、使用 WebStorm IDE 创建 Vue-cli 项目

在 webstorm 中新建项目,选择 vue-cli:

输出项目名称:

项目描述:

作者:

构建模式:

是否使用路由:

是否使用 ESLint 作语法检查:

是否单元测试:

是否安装 e2e(测试):

是否使用 npm 作为包管理器:

选择安装包:

如果网速比较慢, 在上面这个界面中不要选择用 npm,手动在控制台 cnmp install

所有的包下载完成后就可以构建 并运行了:

运行结果:

 

3.5、Vue-cli HelloWorld

了解了默认的模板内容,我们可以开始定义自己的 vue 程序了,这里写一个简单的 HelloWorld,在 src 目录下创建一个 Hi.vue 文件,内容如下:

<template>
    <div id="app1">
        <input v-model="msg" v-on:click="sayhi"/>
        <p>
            <h2>{{msg}}</h2>
        </p>
    </div>
</template>

<script>
export
default {
name:
'Hi',
data() {
return {
msg:
'My First vue-cli app!'
}
},
methods:{
sayhi:
function(){
alert(
this.msg);
}
}
}
</script>

<style>
#app1
{
font-family
: "microsoft yahei";
color
: dodgerblue;
font-size
: 20px;
}
</style>

修改 main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './Hi'

Vue.config.productionTip = false

/ eslint-disable no-new /
new Vue({
el:
'#app',
template:
'<App/>',
components: {App}
})

运行结果:

3.6、Vue-cli 路由与单页

3.6.1、创建一个带路由的项目

创建好的项目如下

3.6.2、定义组件

在 src/compontents 目录下创建 3 个 vue 组件

CompontentA:

<template>
  <div>
    <h2>{{msg}}</h2>
  </div>
</template>

<script>
export
default {
name:
"ComponentA",
data(){
return {
msg:
"ComponentA,这是组件 A!",
}
}
}
</script>

<style scoped>
h2
{
color
: crimson;
}
</style>

ComponentB:

<template>
  <div>
    <h2>{{msg}}</h2>
  </div>
</template>

<script>
export
default {
name:
"ComponentB",
data(){
return {
msg:
"ComponentB,这是组件 B!",
}
}
}
</script>

<style scoped>
h2
{
color
:limegreen;
}
</style>

ComponentC:

<template>
  <div>
    <h2>{{msg}}</h2>
  </div>
</template>

<script>
export
default {
name:
"ComponentC",
data(){
return {
msg:
"ComponentC,这是组件 C!",
}
}
}
</script>

<style scoped>
h2
{
color
:dodgerblue;
}
</style>

结果:

3.6.3、修改路由

修改 src/router 目录下的 index.js 文件

增加路由,一个组件对应一个访问地址:

import Vue from 'vue'
import Router from 'vue-router'
import App from '@/App'
import A from '@/components/ComponentA'
import B from '@/components/ComponentB'
import C from '@/components/ComponentC'

Vue.use(Router);

export default new Router({
routes: [
{
path:
'/',
name:
'App',
component: App
}, {
path:
'/a',
name:
'ComponentA',
component: A
}, {
path:
'/b',
name:
'ComponentB',
component: B
}, {
path:
'/c',
name:
'ComponentC',
component: C
}
]
})
 

3.6.4、引用链接地址

修改 index.html 文件:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vuecli06</title>
  </head>
  <body>
    <div id="app">
      <ul>
        <li><a href="/">首页</a> </li>
        <li><a href="#/a">组件 A</a> </li>
        <li><a href="#/b">组件 B</a> </li>
        <li><a href="#/c">组件 C</a> </li>
      </ul>
      <!--router-view 主要是构建 SPA (单页应用) 时,方便渲染你指定路由对应的组件。你可以 router-view 当做是一个容器,它渲染的组件是你使用 vue-router 指定的。-->
      <router-view></router-view>
    </div>
    <!-- built files will be auto injected -->
  </body>
</html>

 

router-view 主要是构建 SPA (单页应用) 时,方便渲染你指定路由对应的组件。你可以 router-view 当做是一个容器,它渲染的组件是你使用 vue-router 指定的。

打包后运行结果:

点击 a

点击 b

点击 c

3.7、Vue-cli 中依赖 jQuery 与 BootStrap

3.7.1、添加依赖包

项目根目录下找到 package.json 添加

"bootstrap": "^3.3.6",
"jquery": "^2.1.4",

版本可以根据自己的需要修改

cnpm install

在控制台下安装。

3.7.2、导入 jQuery 与 Bootstrap

在 main.js 导入 (注意导入是 node_modules 下的路径可以点进去查看具体位置)min 是压缩后文件建议导入这个

import 'jquery/dist/jquery.min.js'
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.min.js' 

3.7.3、使用内置插件 ProvidePlugin 自动加载模块

此时 jQuery 并未依赖成功,将提示错误:

插件 ProvidePlugin(点击查看)自动加载模块,而不必到处 import 或 require。

需在 build/webpack.base.conf.js 中增加插件配置

const webpack = require('webpack')

配置中添加

plugins: [
  new webpack.ProvidePlugin({
    $: "jquery",
    jQuery: "jquery",
    "windows.jQuery": "jquery"
  })
],

完整结果:

'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
const webpack = require('webpack')

function resolve (dir) {
return path.join(__dirname, '..', dir)
}

const webpack = require('webpack')

module.exports = {
context: path.resolve(__dirname,
'../'),
entry: {
app:
'./src/main.js'
},
output: {
path: config.build.assetsRoot,
filename:
'[name].js',
publicPath: process.env.NODE_ENV
=== 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: [
'.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
module: {
rules: [
{
test:
/.vue$/,
loader:
'vue-loader',
options: vueLoaderConfig
},
{
test:
/.js$/,
loader:
'babel-loader',
include: [resolve(
'src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
{
test:
/.(png|jpe?g|gif|svg)(?.)?$/,
loader:
'url-loader',
options: {
limit:
10000,
name: utils.assetsPath(
'img/[name].[hash:7].[ext]')
}
},
{
test:
/.(mp4|webm|ogg|mp3|wav|flac|aac)(?.
)?$/,
loader:
'url-loader',
options: {
limit:
10000,
name: utils.assetsPath(
'media/[name].[hash:7].[ext]')
}
},
{
test:
/.(woff2?|eot|ttf|otf)(?.*)?$/,
loader:
'url-loader',
options: {
limit:
10000,
name: utils.assetsPath(
'fonts/[name].[hash:7].[ext]')
}
}
]
},
plugins: [
new webpack.ProvidePlugin({
$:
"jquery",
jQuery:
"jquery",
"windows.jQuery": "jquery"
})
],
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs:
'empty',
net:
'empty',
tls:
'empty',
child_process:
'empty'
}
}

View Code

3.7.4、使用 jQuery 与 Bootstrap

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vuecli06</title>
  </head>
  <body>
    <div id="app">
      <ul class="nav nav-tabs">
        <li role="presentation" class="active"><a href="/">首页</a></li>
        <li role="presentation"><a href="#/a">组件 A</a></li>
        <li role="presentation"><a href="#/b">组件 B</a></li>
        <li role="presentation"><a href="#/c">组件 C</a></li>
      </ul>
      <!--router-view 主要是构建 SPA (单页应用) 时,方便渲染你指定路由对应的组件。你可以 router-view 当做是一个容器,它渲染的组件是你使用 vue-router 指定的。-->
      <router-view></router-view>
    </div>
    <!-- built files will be auto injected -->
  </body>
</html>

运行结果:

四、示例下载

https://git.coding.net/zhangguo5/vue2.git

五、视频

https://www.bilibili.com/video/av17503637/

六、作业

1、请定义任意一个 Vue 实例,触发 Vue 实例中的 8 个事件,将结果输出到控制台,要求可以观察到数据初始化与挂载情况。

2、请使用 vuecli+vue2+bootstrap 完成如下功能:

要求如下:

a)、实现添加功能

b)、实现删除功能

c)、实现编辑功能,增加按钮

d)、实现隔行换色

e)、实现按年龄排序

参考