Vue 学习笔记

当需要在数据变化时执行异步或开销较大的操作时,使用watch自定义侦听器

小点:
  1. array.splice(index, step) 从index开始 删除包括自己在内的后step位, 返回删除的内容,会改变原有数组
    array.splice(index, step, val) 从index, 以val替换index后step位元素
    array.slice(from, to) 截取字符串 to为空表示截取到最后
    a.contact(b) 连接数组
    obj.charAt(index) 返回index所在字符串
    obj.charCodeAt(index) 返回index所在字符串的unicode编码

  2. config.silent : 不会打印错误日志
    /* istanbul ignore next */ 代码覆盖率检测的时候忽略该段代码

  3. arrayObject.shift() 删除数组第一个元素并返回值
    arrayObject.unshift(newelement1,newelement2,....,newelementX) 向数组开头添加一个或多个元素, 返回新数组长度

  4. Object.isFrozen() 判断是一个对象是否是可拓展的, (一个对象的冻结是指它不可拓展,所有属性都是不可配置的, 且所有数据属性都是不可写的, 即没有getter/setter组件的访问器))

  5. {} 和 Object.create(null); 的区别 {} 等同于 new Object()
    Object.create(null) 创建一个没有继承任何原型的对象, 没有任何属性方法, 不用考虑会和原型链上的属性重名问题,可以重写所有属性和方法, 是一种函数式编程

    function create(o){
        function F(){
            F.prototype = o;
            return new F();
        }
    }

数组索引:

    ["s", "b", "e"].indexOf("e") !== -1
call()和apply()
参考:https://blog.csdn.net/ganyingxie123456/article/details/70855586
1,每个函数都包含两个非继承而来的方法:call()方法和apply()方法。
2,作用一样, 改变this的指向
3, 接收参数方式不同
    apply([thisObj [,argArray..]]); 参数2必须是有小数组或者arguments对象
    call([thisObj [,arg1 [,arg2 ..]]]);  传递给函数的参数必须列举出来

        ```js
            function add(c,d){
                return this.a + this.b + c + d;
            }

            var s = {a:1, b:2};
            console.log(add.call(s,3,4)); // 1+2+3+4 = 10
            console.log(add.apply(s,[5,6])); // 1+2+5+6 = 14 
        ```
property属性

参考:https://blog.csdn.net/yh1061632045/article/details/81518138
js 中的可枚举属性(enumerable) propertylsEnumerable()

obj.propertyIsEnumerable(prop) 判断属性是否可枚举 > 返回 true or false

不可枚举属性不会被遍历
for ... in

可枚举属性对以下操作的影响
Object.keys(), JSON.stringify() 不会列举出不可枚举属性, 也不会列举出原型链上的所有属性

    Object.defineProperty(obj, prop, descriptor); 
    //直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象
    //configurable,wriable,enumerable默认为false, value,get,set 默认为undefined
    var obj = new Object();
    Object.defineProperty(obj, 'name', {
        configurable: false,    // configurable属性为false, 如果writable为false 修改所有内部属性值会抛出错误, 如果writable为true 则只有writable和value的值可修改,修改其他则会报错
        writable: true,
        enumerable: true,
        value: '张三'
    });

    Object.defineProperties(obj, props);

    var obj = new Object();
    Object.defineProperties(obj, {
        name: {
            value: '张三',
            configurable: false,
            writable: true,
            enumerable: true
        },
        age: {
            value: 18,
            configurable: true
        }
    });


    Object.getOwnPropertyDescriptor(obj, prop);  //返回指定对象上一个自有属性对应的属性描述符
    var person = {
        name: '张三',
        age: 18
    }

    var desc = Object.getOwnPropertyDescriptor(person, 'name'); 
    console.log(desc)  结果如下
    // {
    //     configurable: true,
    //     enumerable: true,
    //     writable: true,
    //     value: "张三"
    // }
问题1--正则:

[^\w.$] 相当于 \W.*

\B 非单词边界字符左右两边没有空白字符
\b 单词边界左右两边有空白

(?=) 作为匹配校验,但不会出现在匹配结果字符串里
(?😃 作为匹配校验,会出现在匹配结构字符串中,但不作为子匹配, 可以提高正则性能
eg:

```js
    var data = 'windows 98 is ok';
    data.match(/windows (?=\d+)/);  // ["windows "]
    data.match(/windows (?:\d+)/);  // ["windows 98"]
    data.match(/windows (\d+)/);    // ["windows 98", "98"]
    /(?:^|[-_])(\w)/g   //匹配开头或者-_ 后的一个字符, 所以 $1就是(\w)
```
检测对象类型
typeof 无法准确判断
Object.prototype.toString.call(obj)  可以区分各种类型  

    ```js
        "jerry".toString()  >> jerry
        Object.prototype.toString.call("jerry")   >> [object String]
    ```
instanceof  自定义类型使用instanceof
问题2:

参考:https://blog.csdn.net/fakerac/article/details/52819009
(函数名) :
var generateComponentTrace = (noop);//命名函数表达式 一般用在递归上, var res = function a(){}() 必须有一个变量接收返回值, (function a(){})() 立即执行函数, 不必须使用变量接收

var hasSymbol =
typeof Symbol !== 'undefined' && isNative(Symbol) &&
typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys);

参考:http://www.w3school.com.cn/jsref/jsref_replace.asp
str.replace(regexp/substr, replacement/func);
参数1: 子字符串, 或者替换的正则对象
如果replacement是$字符则具有特定含义:
$1 ---- $99 与regexp 中第几个子表达式相匹配的文本
$& : 与regexp相匹配的字串
$` : 位于匹配子串左侧的文本
$' : 位于匹配子串右侧的文本
$$ : 直接量符号
参数2:替换后的字符串 / 一个函数(每个匹配都调用该函数,返回字符串作为替换文本使用)

注意事项

Vue 不能检测以下变动的数组:
1.使用索引直接设置值的时候 vm.items[indexOfItem] = newValue
2.当修改数组的长度时,vm.items.length = newLength

    var vm = new Vue({
        data:{
            items:[1,2,3,4]
        }
    });
    vm.items[1] = 'x';//不是响应性的
    vm.items.length = 2;//不是响应性的

解决方法

- 对于1:可以用vm.$set(vm.items, indexOfItem, newValue);
        vm.items.splice(indexOfItem, 1, newValue)  
- 对于2:vm.items.splice(newLength)

注意事项:

  1. 在组件中使用v-for时,key是必须的

  2. 使用事件修饰符时,顺序很重要
    eg: v-on:click.prevent.self 阻止所有点击事件
    v-on:clcik.self.prevent 只阻止对元素自身的点击

  3. 在选择框中使用v-model, 如果v-model表达式的初始值不能匹配任何选项, select 元素将被渲染为 "未选中"状态。在IOS中, 会使用户无法选择第一个选项 推荐提供一个值为空的禁用选项

  4.     <!-- #选项框的选项 -->
        <select v-model="selected">
            <!-- 内联对象字面量 -->
            <option v-bind:value="{number: 123}">123</option>
        </select>
    
          
        typeof vm.selected // > object
        vm.selected.number => 123
    
  5. 组件的data必须是一个函数, 因为组件是可服用的, 每个组件实例都维护一份被返回对象的独立拷贝。才不会造成数据安全问题。

  6. 每个组件必须只有一个根元素, 即每个组件只能有一个最大的标签,在最外层没有兄弟元素。

  7.     <input v-model="searchText">
    
        <!-- 等价于 -->
    
        <input v-bind:value="searchText" v-on:input="searchText = $event.target.value">
    
  8. 解析 DOM 模板时的注意事项:is用法

  9. 实现效果与 一样 但是可以避免浏览器解析错误,以及特定内部元素限制问题。如table中只能由tr,tb 等, 出现自定义组件会导致渲染结果出错。

  10. 单向数据流

  11. 跟组件和 prop 不同,事件名不存在任何自动化的大小写转换, 事件名需要完全匹配监听这个事件所用的名称,自定义事件最好使用小写命名或者始终使用kebab-case命名 因为HTML是大小写不敏感的,所有大写会转成小写, 导致事件不能被监听到。

  12. 插槽 slot 元素作为承载分发内容的出口, 相当于jinjia2模板引擎的 占位模板

    • 普通slot
    • 具名slot
  13. 父组件模板的所有内容都会在父级作用域内编译; 子组件模板的所有内容都会在子组件作用于内编译

实现数据mvvm双向绑定
  1. 实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,有变动可拿到最新值并通知订阅者
  2. 实现一个指定解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定响应的更新函数
  3. 实现一个Watcher, 作为Obsever和Compile的桥梁,能够订阅并受到每个属性变动的通知,执行指令绑定的响应回调函数,从而更新视图
  4. mvvm入口函数, 整合以上三者

Vue整个生命周期中, 有4类地方会实例化Watcher

  1. Vue实例化的过程中有watch选项
  2. Vue实例化的过程中有computed计算属性选项
  3. Vue原型上有挂载\(watch方法: Vue.prototype.\)watch,可以直接通过实例调用this.$watch方法
  4. Vue生成了render函数,更新视图时

vm._render 调用vm.$options.render 返回生成的虚拟节点(vnode)
vm._update 将虚拟节点渲染称真实的DOM

渲染观函数的观察者并不是同步更新变化的,而是将变化放到一个异步更新队列中

update () {
    if (this.computed) {
        //
    } else if (this.sync) {
        this.run();
    } else {
        queueWatcher(this);  //这个队列会在调用栈被清空之后按照一定的顺序执行,将观察者放到一个队列中等待所有突变完成之后统一执行更新
    }
}
posted @ 2018-09-29 20:51  JonPan  阅读(153)  评论(0)    收藏  举报