首页 > 编程 > JavaScript > 正文

Vue的实例、生命周期与Vue脚手架(vue-cli)实例详解

2019-11-19 14:38:12
字体:
来源:转载
供稿:网友

一、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 = 2data.a // => 2// ... 反之亦然data.a = 3vm.a // => 3

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

vm.b = 'hi'

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

示例:

<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>vue2实例</title> </head> <body> <div id="app1">  <input type="text" v-model="a"/> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript">  var data={a:1}  //实例  var vm = new Vue({  el: "#app1",  data:data,  updated:function(){   console.log("实例被更新了!");  }  }); </script> </body></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 // => truevm.$el === document.getElementById('example') // => true// $watch 是一个实例方法vm.$watch('a', function (newValue, oldValue) {// 这个回调将在 `vm.a` 改变后调用})

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

1.3、实例属性

解释

vm._uid // 自增的idvm._isVue // 标示是vue对象,避免被observevm._renderProxy // Proxy代理对象vm._self // 当前vm实例vm.$parent // 用于自定义子组件中,指向父组件的实例vm.$root // 指向根vm实例vm.$children // 当前组件的子组件实例数组vm.$refs vm._watcher = nullvm._inactive = nullvm._directInactive = falsevm._isMounted = false // 标识是否已挂载vm._isDestroyed = false // 标识是否已销毁vm._isBeingDestroyed = false // 标识是否正在销毁vm._events // 当前元素上绑定的自定义事件vm._hasHookEvent // 标示是否有hook:开头的事件vm.$vnode // 当前自定义组件在父组件中的vnode,等同于vm.$options._parentVnodevm._vnode // 当前组件的vnodevm._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> <head> <meta charset="UTF-8"> <title>vue2实例</title> </head> <body> <div id="app1">  <p>  <input type="text" v-model="msg" />  <span>{{msg.split('').reverse().join('')}}</span>  </p>  <p>  <input type="text" v-model="msg" />  <span>{{revMsg}}</span>  </p> </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: "hello"  },  computed: {   revMsg: function() {   return this.msg.split('').reverse().join('');   }  }  }); </script> </body></html>

结果:

注意:

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

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

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

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

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

1.5.2、watch计算属性

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

示例:

<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>vue2实例</title> </head> <body> <div id="app1">  <p>  a:  <input type="text" v-model="a" />{{a}}<br/> b:  <input type="text" v-model="b" />{{b}}<br/> c:  <input type="text" v-model="c.x.y.z" />{{c.x.y.z}}<br/> d:  <input type="text" v-model="d" />{{d}}<br/>  </p>  <p>  n:<input type="text" v-model="c.x.y.n" />{{c.x.y.n}}  </p> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript">  var app1 = new Vue({  el: "#app1",  data: {   a: 1,   b: 2,   c: {   x: {    y: {    z: 3,    n: 3    }   }   },   d: 4  },  watch: {   a: function(val, oldVal) {   console.log('a新: %5s, 原: %5s', val, oldVal);   },   // 方法名   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);   }  }  });  var watchb = function(val, oldVal) {  console.log('b新: %5s, 原: %5s', val, oldVal);  } </script> </body></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));    var m3=(a,b)=>a+b;  console.log(m3(100,200));    var m4=(a,b)=>{a++; b++; return a+b;}; //如果方法体中有多个表达式,则需要大括号与return  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.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生命周期","开始了");    var app1 = new Vue({  el: "#app1",  data:{   msg:"vue"  },  beforeCreate:function(){   console.log("创建前:"+this.msg);  },  created:function(){   console.log("创建后:"+this.msg+","+this.$el);  },  beforeMount:function(){   console.log("挂载前:");   console.log(this.$el);  },  mounted:function(){   console.log("挂载后:");   console.log(this.$el);  },  beforeUpdate:function(){   console.log("实例更新前:");   console.log(this.msg);   console.log(this.$el);  },  updated:function(){   console.log("实例更新后:");   console.log(this.msg);   console.log(this.$el);  },  beforeDestroy:function(){   console.log("实例销毁前:");   console.log(this.msg);       },  destroyed:function(){   console.log("实例销毁后:");   console.log(this.msg);  }  });    function destroy(){  app1.$destroy();  } </script> </body></html>

初始化结果1:

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

执行销毁:

2.4、生命周期示例二

示例2:

<!DOCTYPE html><html> <head> <title>Vue2生命周期</title> </head> <body> <div id="app">{{ message }}</div> <script type="text/javascript" src="https://cdn.jsdelivr.net/vue/2.1.3/vue.js"></script> <script type="text/javascript">  var app = new Vue({  el: '#app',  data: {   message: "South IT College!"  },  beforeCreate: function() {   console.group('beforeCreate 创建前状态===============》');   console.log("%c%s", "color:red", "el : " + this.$el); //undefined   console.log("%c%s", "color:red", "data : " + this.$data); //undefined    console.log("%c%s", "color:red", "message: " + this.message)  },  created: function() {   console.group('created 创建完毕状态===============》');   console.log("%c%s", "color:red", "el : " + this.$el); //undefined   console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化  },  beforeMount: function() {   console.group('beforeMount 挂载前状态===============》');   console.log("%c%s", "color:red", "el : " + (this.$el)); //已被初始化   console.log(this.$el);   console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化    console.log("%c%s", "color:red", "message: " + this.message); //已被初始化   },  mounted: function() {   console.group('mounted 挂载结束状态===============》');   console.log("%c%s", "color:red", "el : " + this.$el); //已被初始化   console.log(this.$el);   console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化   console.log("%c%s", "color:red", "message: " + this.message); //已被初始化   },  beforeUpdate: function() {   console.group('beforeUpdate 更新前状态===============》');   console.log("%c%s", "color:red", "el : " + this.$el);   console.log(this.$el);   console.log("%c%s", "color:red", "data : " + this.$data);   console.log("%c%s", "color:red", "message: " + this.message);  },  updated: function() {   console.group('updated 更新完成状态===============》');   console.log("%c%s", "color:red", "el : " + this.$el);   console.log(this.$el);   console.log("%c%s", "color:red", "data : " + this.$data);   console.log("%c%s", "color:red", "message: " + this.message);  },  beforeDestroy: function() {   console.group('beforeDestroy 销毁前状态===============》');   console.log("%c%s", "color:red", "el : " + this.$el);   console.log(this.$el);   console.log("%c%s", "color:red", "data : " + this.$data);   console.log("%c%s", "color:red", "message: " + this.message);  },  destroyed: function() {   console.group('destroyed 销毁完成状态===============》');   console.log("%c%s", "color:red", "el : " + this.$el);   console.log(this.$el);   console.log("%c%s", "color:red", "data : " + this.$data);   console.log("%c%s", "color:red", "message: " + this.message)  }  }) </script> </body></html>

初始化结果:

更新message的值:

手动销毁实例:

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生命周期</title> <style>  #app1 {  color: red;  }  #app2 {  color: blue;  } </style> </head> <body> <div id="app1"> </div> <div id="app2"> </div> <button type="button" onclick="loaddata1()">手动挂载1</button> <button type="button" onclick="loaddata2()">手动挂载2</button> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript">  var app1 = new Vue({  template: "<h2>{{msg}}</h2>",  data: {   msg: "Hello Vue2!"  }  });  function loaddata1() {  app1.$mount("#app1");  document.getElementById("app1").appendChild(app1.$el);  }  function loaddata2() {  app1.$mount();  document.getElementById("app2").appendChild(app1.$el);  } </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

从n ode.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? Yesvue-cli ・ Generated "exprice".To get started: --------------------- 这里说明如何启动这个服务cd expricenpm installnpm run dev

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、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 }})

运行结果:

四、示例下载

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

五、视频

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

六、作业

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

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

要求如下:

a)、实现添加功能

b)、实现删除功能

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

d)、实现隔行换色

e)、实现按年龄排序

参考 :

总结

以上所述是小编给大家介绍的Vue的实例、生命周期与Vue脚手架(vue-cli)实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表