vue 学习笔记(一)

vue学习及应用也有一年多了,但一直没能系统的总结过。多少有些遗憾。正好赶上找工作,就趁此巩固、总结下吧。

一、vue生命周期函数

beforeCreate ,  created             // 创建前, 创建完成
beforeMount  ,  mounted            //  挂载前, 挂载完成
beforeUpdate  , updated           //   更新前, 更新完成
beforeDestory , destroyed        //  销毁前, 销毁完成

二、vue 生命周期钩子的 this

生命周期钩子的this上下文指向调用它的vue实例
//  说明:不要在选项属性或回调上使用箭头函数,因为箭头函数是和父级上下文绑定在一起的
//  this不会是如你所预期的vue实例,经常导致 "Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function "之类的错误。

三、响应式属性

1、当一个vue实例被创建时,它向vue的响应式系统中加入了其data对象中能找到的所有的属性。当这些属性的值发生改变时,视图将会产生"响应",即匹配更新为新的值。
但是只有当实例被创建时data对象中已经存在的属性才是响应式的。所以在一开始不会使用后面却要使用的属性,最好一开始就声明到data中,初始化为空值即可。
2、使用Object.freeze(),会阻止修改现有属性,意味着响应系统无法在追踪属性变化。

四、模板语法

1、在模板数据绑定时可以用单个javascript表达式,
2、模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如 MathDate,你不应该在模板表达式中试图访问用户定义的全局变量。

五、计算属性和侦听器

1、计算属性:
将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的计算属性是基于它们的依赖进行缓存的。
计算属性只有在它的相关依赖发生改变时才会重新求值,多次访问计算属性会立即返回之前的计算结果,而不必再次执行函数。
而对于方法,每当触发重新渲染时,调用方法将总会再次执行函数。

 2、侦听器:watch
 当需要在数据变化时执行异步或开销较大的操作时使用。

六、条件渲染

1.v-if: 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
2.v-if也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
3.v-show: v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。
4.v-show: 不管初始条件是什么,元素总是会被渲染,并且只是简单地基于CSS 进行切换。
5.v-if与v-show对比:v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
6.v-if与v-for:当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。
7.v-if可以与计算属性和方法一起使用:但方法和计算属性名后不能有(),会报错。

七、列表渲染

/** 1、v-for迭代数组 **/
<div v-for="(item,index) in items">{{item}}</div>
/**说明:item是迭代的元素,index是索引。可用 of 代替 in 。 **/

/** 2、v-for循环对象 **/
<div v-for="(value, key, index) in object">
  {{ index }}. {{ key }}: {{ value }}
</div>
/**value 是属性值,key 是属性名,index 是索引。 **/

/** 3、key: 为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的且唯一的 id。
注: 建议尽可能在使用 v-for 时提供 key,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。 *

/** 4、数组更新检测:以下方法将会触发视图更新 **/

//变异方法:会改变原始数组
    push()
    pop()
    shift()
    unshift()
    splice()
    sort()
    reverse()
//非变异方法:不会改变原始数组,返回新数组
    filter)
    concat()
    slice()

注:由于 JavaScript 的限制,Vue 不能检测以下变动的数组:当你利用索引直接设置一个项时,例如:
vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:
vm.items.length = newLength
解决以上问题,使用Vue.set和splice方法。

/** 5、对象更改检测注意事项:**/
由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除,对于已经创建的实例,Vue不能动态添加根级别的响应属性。最好一开始就声明在data中。但可以使用 Vue.set(object, key, value) 方法向嵌套对象添加响应式属性。即object只能是data对象下的的属性对象。或者使用
vm.$set(object, key, value)

为已有对象赋予多个新属性使用一下方法:
vm.userProfile = Object.assign({}, vm.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})

/** 6、显示过滤/排序结果:**/

想要显示一个数组的过滤或排序副本,而不实际改变或重置原始数据。在这种情况下,可以创建返回过滤或排序数组的计算属性。

<li v-for="n in evenNumbers">{{ n }}</li>
data: {
  numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
  evenNumbers: function () {
    return this.numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}
在计算属性不适用的情况下 (例如,在嵌套 v-for 循环中) 可以使用一个method 方法:
<li v-for="n in even(numbers)">{{ n }}</li>
data: {
  numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
  even: function (numbers) {
    return numbers.filter(function (number) {
      return number % 2 == 0
    })
  }
}


/** 7、v-for 与 v-if:**/
当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。
如果目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或template)上。如:

  <ul v-if="todos.length">
  <li v-for="todo in todos">
    {{ todo }}
  </li>
</ul>
<p v-else>No todos left!</p>

八、过滤器

Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示:
<!-- 在双花括号中 -->
{{ message | capitalize }}
<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>

1.在一个组件中自定义本地过滤器
<div id='example'>
            {{message | capitalize}}
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
    new Vue({
        el: '#example',
        data: {
            message: 'hello world'
        },
        filters: {
            capitalize: function (value){
                return value.toUpperCase();
            }
        }
    });
</script>

2.定义全局过滤器
<div id='example'>
    {{name | capitalize}}
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
    Vue.filter('capitalize', function (value) {

        return value[0].toUpperCase() + value.slice(1);
    });
    new Vue({
        el: '#example',
        data: {
            name: 'john'
        }
    });
</script>
3.过滤器函数总接受表达式的值作为第一个参数,上述例子中, capitalize 过滤器函数将 message 的值作为第一个参数。
4.过滤器可以串联:
<div id='example'>
            {{name | filterA | filterB}}
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
new Vue({
        el: '#example',
        data: {
            name: 'john'
        },
        filters: {
            filterA: function (value) {
                return value[0].toUpperCase() + value.slice(1);
            },
            filterB: function (value) {
                return value.slice(0,value.length-1) + value[value.length-1].toUpperCase();
            }
        }
});
</script>

5.过滤器可以接受参数
{{ message | filterA('arg1', arg2) }}

九、响应式原理

Vue的特性之一是其非侵入性的响应式系统。数据模型是普通的 JavaScript 对象,修改数据时,视图会进行更新
1、如何追踪变化
当把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项时,Vue将遍历此对象的所有属性,并使用 Object.defineProperty 把这些属性全部转化为 getter/setter。 这些 getter/setter 对用户来说是不可见的,但在内部使用它们让 Vue 来追踪依赖,在属性被访问和修改时通知变化。
每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。

2、 检测变化的注意事项
Vue 会在初始化实例时对 data 选项上的属性执行 getter/setter 的转化,但 Vue 不能检测到对象属性的添加或删除,所以想要属性是响应式的,必须在初始化实例前声明根级响应式属性,如果属性初始无值,可以赋一个空值。
var vm = new Vue({
    data:{
        a: 1
    }
});
// vm.a 是响应的
vm.b = 2;
// vm.b 不是响应的

Vue 不允许在已经创建的实例上动态添加新的根级响应式属性。但允许使用 Vue.set(obj,key,value) 将响应式属性添加到嵌套的对象上:
var vm = new Vue({
    data:{
        someObj: {
            a: 1
        }
    }
});

Vue.set(vm.someObj,'b',2);//还可以使用 vm.$set 实例方法,这是全局 Vue.set 方法的别名


3、异步更新队列
vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变,去除重复数据,避免不必要的计算和 DOM 操作。如果同一个 watcher 被多次触发,只会被推入到队列中一次。然后,在下一个的事件循环‘tick’ 中,Vue 刷新并执行实际(已去重的)工作。Vue 在内部尝试对异步队列使用原生的 Promise.then 和 MessageChannel,如果执行环境不支持,会采用 setTimeout(fn,0)代替。
例如,当设置 vm.someData = 'new value',该组件不会立即重新渲染。当刷新队列时,组件会在事件循环队列清空时的下一个 'tick' 更新。


增加内容:
a.使用 script 标签引入 vue.js 时,将 vue.js 放到 head 里面,可以防止页面出现插值双 {{}} 的闪屏问题。
b. v-text vs v-html
v-text:遇到 html 的字符串值时会转义成字符串显示
v-html:遇到 html 的字符串值时会解析成 dom 节点

猜你喜欢

转载自blog.csdn.net/cxz792116/article/details/80747511