前端MVC Vue2学习总结(二)

您所在的位置:网站首页 vuecli安装babel 前端MVC Vue2学习总结(二)

前端MVC Vue2学习总结(二)

#前端MVC Vue2学习总结(二)| 来源: 网络整理| 查看: 265

1、Vue的实例 1.一、建立一个 Vue 的实例

每一个 Vue 应用都是经过 Vue 函数建立一个新的 Vue 实例开始的:javascript

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

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

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

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

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

咱们会在稍后的组件系统章节具体展开。不过如今,你只须要明白全部的 Vue 组件都是 Vue 实例,而且接受相同的选项对象便可 (一些根实例特有的选项除外)。vue

1.二、数据与方法

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

// 咱们的数据对象 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 中存在的属性是响应式的。也就是说若是你添加一个新的属性,像:node

vm.b = 'hi'

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

示例:webpack

DOCTYPE html> vue2实例 var data={a:1} //实例 var vm = new Vue({ el: "#app1", data:data, updated:function(){ console.log("实例被更新了!"); } });

结果:git

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

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.三、实例属性

解释

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.四、实例方法 1.五、实例参数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 }; // 子组件的定义 transitions?: { [key: string]: Object }; filters?: { [key: string]: Function }; // 过滤器 // context provide?: { [key: string | Symbol]: any } | () => { [key: string | Symbol]: any }; inject?: { [key: string]: string | Symbol } | Array; // component v-model customization model?: { prop?: string; event?: string; }; // misc parent?: Component; // 父组件实例 mixins?: Array; // mixins传入的数据 name?: string; // 当前的组件名 extends?: Class | Object; // extends传入的数据 delimiters?: [string, string]; // 模板分隔符 // 私有属性,均为内部建立自定义组件的对象时使用 _isComponent?: true; // 是不是组件 _propKeys?: Array; // props传入对象的键数组 _parentVnode?: VNode; // 当前组件,在父组件中的VNode对象 _parentListeners?: ?Object; // 当前组件,在父组件上绑定的事件 _renderChildren?: ?Array; // 父组件中定义在当前元素内的子元素的VNode数组(slot) _componentTag: ?string; // 自定义标签名 _scopeId: ?string; _base: Class; // Vue _parentElm: ?Node; // 当前自定义组件的父级dom结点 _refElm: ?Node; // 当前元素的nextSlibing元素,即当前dom要插入到_parentElm结点下的_refElm前 } 1.5.一、computed计算属性

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

{{msg.split('').reverse().join('')}}

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

DOCTYPE html> vue2实例 {{msg.split('').reverse().join('')}} {{revMsg}} var app1 = new Vue({ el: "#app1", data: { msg: "hello" }, computed: { revMsg: function() { return this.msg.split('').reverse().join(''); } } });

结果:

注意:

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

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

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

四、 computed计算属性能够对属性进行缓存的,计算属性只有当该属性发生变化的时候才会从新计算值

五、若是一个属性不能完成须要的功能时能够考虑转成计算

1.5.二、watch计算属性

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

示例:

DOCTYPE html> vue2实例 a: {{a}} b: {{b}} c: {{c.x.y.z}} d: {{d}} n:{{c.x.y.n}} 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); }

结果:

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

1.5.三、方法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> vue2实例 {{msg}} var app1 = new Vue({ el: "#app1", data:{ msg:"vue" }, methods:{ add:function(str){ return this.msg+=str; } } }); console.log(app1.add(3));

结果:

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

1.5.四、小结

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

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

二、若是实例建立以后添加新的属性到实例上,不会触发视图更新;

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

四、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 }),用来访问被 slot 分发的内容。每一个具名 slot 有其相应的属性(例如:slot="foo" 中的内容将会在 vm.$slots.foo 中被找到)。default 属性包括了全部没有被包含在具名 slot 中的节点。k、vm.$refs:类型(Object),一个对象,其中包含了全部拥有 ref 注册的子组件;l、vm.$isServer:类型(boolean),当前Vue实例是否运行于服务器;

官网对应

1.5.五、箭头函数

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

()=>{}

示例:

DOCTYPE html> vue2实例 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));

结果:

2、生命周期 2.一、实例生命周期

每一个 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.二、生命周期图示

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

中文版:

 

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> Title var tom={name:"tom",age:10}; console.group("开始"); console.group("第一组"); console.log("%c%s%o","background:red;color:yellow;",'对象是:',tom); console.groupEnd(); console.group("第二组"); console.log("%c%s%o","background:red;color:yellow;",'对象是:',tom); console.groupEnd(); console.group("第三组"); console.log("%c%s%o","background:red;color:yellow;",'对象是:',tom); console.groupEnd(); console.groupEnd();

结果:

2.三、生命周期示例一

示例1:

DOCTYPE html> vue2生命周期 {{msg}} 销毁 //格式化输出 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); } });


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3