• Vue学习笔记


    最重要:

    1、data:

      1)不渲染视图、不双向绑定的数据不放进data,在created中this.XXX = 定义即可;

      2)data中的对象和数组的改变:

        a、改变对象:

    data() {
        return {
            kk: {
                a: 1
            }
        }
    },
    methods: {
        change() {
            this.kk.b = 2;    //通过直接赋值改变对象,不是响应式
            this.$set(this.kk, 'b', 2);    //用$set方法改变,是响应式
        }
    }

         b、改变数组:

    data() {
        return {
            ooo: [0, 1]
        }
    },
    methods: {
        change() {
            this.ooo[2] = 2;    //通过数组下标改变数组,不是响应式
            this.ooo.push(2);    //用push、splice等方法改变,是响应式(vue重写了这几种方法)
        }
    }

    2、.vue文件中this指向的内容:

      1)$attrs:是props的合集,只有自定义的属性才能取到 (透传,由上往下传递)

        index.vue:

    <hello :tt="1234" msg="123"></hello>

        hello.vue:

    <template>
        <div>111</div>
    </template>
    
    <script>
        export default {
            mounted() {
                console.log(this.$attrs);    //{ ttt: '1234', msg: '123' }
            }
        }
    </script>

      2)$createElement:相当于render函数的h函数

      3)$el:当前div的DOM

      4)$refs:ref绑原生标签---->DOM,ref绑组件---->组件实例

        index.vue:

    <hello v-for="v in 10" :key="v" ref="ddd"></hello>
    
    
    
    this.$refs.ddd --->[10]    //10个hello组件,循环时可直接批量修改
    
    
    this.$refs.ddd.forEach(x => {
        x.msg = 'hello';
    });

        hello.vue:

    <template>
        <div>{{ msg }}</div>     //循环10个hello
    </template>
    
    
    data() {
        return {
            msg: '111'
        }
    }

       5)$parent:父级元素的实例(一般不用,也不要用)

      6)$listeners:与$attrs相对应,都是透传,是从下往上传递。eg:

    index.vue:
    
    <div>
        {{ abc }}  //默认显示1,点击hel.vue的button,改为888
        <hello :abc="abc" @click="_change"></hello>
    </div>
    
    data() {
        return {
            abc: 1
        }
    },
    methods: {
        _change(val) {
          this.abc = val;  
        }
    }
    
    
    hello.vue:
    
    <hel v-bind="$attrs" v-on="$listeners">
    </hel>
    
    
    hel.vue: 
    
    <div>
        <span>{{ $attrs.abc }}</span>       //默认显示1,点击button后变为888
        <button @click="_click"></button>
    </div>
    
    
    created() {
        console.log(this.$attrs);    //{ abc: '1'}
        console.log(this.$listeners);    //{ click: f }  index.vue的click事件
    },
    methods: {
        _click() {
            this.$emit('click', 888);    //点击调用index.vue的click事件
        }
    }

    3、$nextTick:解决mounted时,DOM没有完全渲染完的时间差(16ms)

    mounted() {
        this.$nextTick().then(() => {
            ...//代码片段
        });
    }

     4、计算属性、方法、watch比较:

      1)计算属性(computed):对数据的计算和过滤等一些简单的操作,有缓存(依赖没变、结果没变),可按照使用场景优先使用

        使用场景:多个params绑定,修改单个用computed

    coputed: {
        params: {
            page: this.page,
            pageSize: this.pageSize
        }
    }    //一个改,整个计算

      2)methods:不缓存,每次都运行

      3)watch:数据改变后,要调接口和进一步的操作

        使用场景:a、可以监听路由跳转的参数

    watch: {
        $route(val) {
            ...//代码片段
        }
    }

          b、监听嵌套对象深层的某个值:

    data() {
        return {
            kk: {
                a: {
                    b: {
                        c: 1
                    }
                }
            }
        }
    },
    
    watch: {
        'kk.a.b.c': funtion(val) {
            ...//代码片段
        }
    }

     5、key:为了更高效的复用

      vDOM:用js对象表达DOM,配合diff算法生成DOM

      1)包在中间的子节点复用,值会改变。eg:<span>3</span> ------> 5

      2)包在属性中的子节点复用,不会改变。eg:<img src="1.jpg" /> ------>不会改变,因为已经渲染了。

    6、注册组件:

       (1)动态注册组件:

    (1)
    import hello from './hello';
    
    components: { hello }
    
    
    (2)
    this.components('hello');
    
    
    (3) table.config.js: 
    import hello from 'hello';
    
    render(h) {
        return h('hello', { ... })
    }

      (2)全局注册:

    Vue.component('hello');

    7、props:父组件传递给子组件的数值

      (1)传递变量时前面需要加":",否则一律按字符串处理

    <hello msg="true"></hello>    ----->msg为字符串"true"
    
    
    <hello :msg="true"></hello>    ----->msg为布尔型数值true

      (2)布尔型的数值传递true值,可直接省略写:

    <hello msg></hello>    ----->msg为布尔型数值true

      (3)props的值不允许直接修改,在子组件中需要修改,则需要重新定义一个变量去修改。

      (4)对一个 prop 进行“双向绑定”:加.sync修饰符。即在子组件也可以修改父组件prop传递的值

    index.vue:
    
    <hello :msg.sync="123"></hello>
    
    
    
    hello.vue:
    
    this.$emit('update:msg', '222');  

    较重要:

    1、模块化:精简、复用(按需调用)、防止变量污染

    2、AMD、CMD、commonJS、esModule(es6):

      1)AMD:define(modules, callback):依赖前置、异步定义

      2)CMD:define():依赖就近,即用即返

      3)commonJS:require()引入(图片src引入或判断引入),exports导出、运行时加载。例:

        index.js:

    var bar = require('./bar.js');
    
    function foo() {
        return bar.bar();
    }

        bar.js:

    exports.bar = function() {
        console.log('1111');
    }

      4)ES Module:在script头部用import引入,export导出、编译时加载。例:

        index.js:

    'use strict'
    import bar, {foo} from './bar.js';
    
    bar();    // 11
    
    foo();    // 112 

        bar.js:

    'use strict';
    export default function bar () {
        console.log('11');
    };
    export function foo () {
        console.log('112');
    }

    3、vue.js包括编译和运行两部分:

      1)编译:将template代码片段转成AST(抽象语法树)---->优化AST(标记静态部分不再渲染)---->AST生成render函数。

      2)运行:render函数 ----> vDOM ----> DOM

      mark:由于webpack的vue-loader做了预编译,因此不需要vue.js做编译,因此用vue.runtime.js(仅运行版本的vue.js)。需要做的几处改变:

        1)main.js中new Vue({});中的template: '<App />', components: {App}需要改变成render: h => (App) 。

        2)this.$Message没法调用,将iview源码中注册组件的components改成render函数即可。

    4、data、props、methods都可代理到实例上,通过this.XXX直接调用,不通过this.$data.XXX等。this.$data---->拿到所有data中定义的数据

    5、_uid是每个组件唯一的标识

    6、@hook:监听子组件生命周期加载完成:

    <hello @hook:mounted="kk" @hook:created="qq"></hello>
    
    kk() {    //监听子组件hello的生命周期mounted完成
      console.log('hello mounted done');  
    }
    
    qq() {    //监听子组件hello的生命周期created完成
      console.log('hello created done');  
    }

    7、{{}}等同于v-text,用于存放DOM中的变量值,一般用{{}},有可能会出现不解析的情况,用指令v-cloak(等编译完才显示)解决即可

      2)v-html可以解析html语句,可转义,但是可能会遭到XSS攻击,因此要慎用

    8、动态值的优先级更高:

    <input value="22" :value="77" />
    
    ----->  value: 77

     9、$event:需要添加自己的参数时的占位符

      1)正常情况下的子组件调用父组件的方法以及传参:

    index.vue:
    <hello @click="kii"></hello>
    
    
    kii(data) {
      console.log(data);   //22
    }
    
    
    
    
    hello.vue:
    <div @click="aaa">emit click</div>
    
    
    click() {
      this.$emit('click', 22);  
    }

      2)父组件需要在该组件中传递自己的参数时,需要$event来占位保留子组件传递的值:

    index.vue:
    <hello @click="kii($event, 33)"></hello>
    
    
    kii(data, val) {    //$event只能识别第一位参数,因此子组件需要传递多个参数时,用对象包起来传递整个对象即可
      console.log(data, val);   //22  33
    }
    
    
    
    
    hello.vue:
    <div @click="aaa">emit click</div>
    
    
    click() {
      this.$emit('click', 22);  
    }

     10、插槽:

      (1)插槽的用法:

        1)父组件插槽占位,引入不同的子组件:

    index.vue:
    
    <hello>
        <slot></slot>    
    </hello>
    
    
    hello.vue:
    
    <div>
        <span>{{msg}}</span>
    </div>
    
    
    data() {
        return {
            msg: '111'
        }
    }

        2)具名插槽:

    index.vue:
    
    <hello>
        <template v-slot:header>
            <p>This is header slot!!</p>
        </template>
        <template>
            <p>This is main slot!!</p>
        </template>
        <template v-slot:footer>
            <p>This is footer slot!!</p>
        </template>
    </hello>
    
    
    hello.vue:
    
    <div>
        <header>
            <slot name="header"></slot>
        </header>
        <main>
            <slot></slot>
        </main>
        <footer>
            <slot name="footer"></slot>
        </footer>
    </div>  

      (2)用子组件的数据:

    index.vue:
    
    <hello v-slot="uu">
        <span>{{uu.aa}}</span>
        <span>{{uu.bb}}</span>
    </hello>
    
    
    hello.vue:
    
    <div>
        <slot :aa="msg" :bb="msg2"></slot>
    </div>
    
    
    data() {
        return {
            msg: '111',
            msg2: '222'
        }
    }

     11、动态组件:

      (1)keep-alive:缓存。使用场景:1)不要求实时性;2)步骤条(保存当前操作)。

        1)include、exclude根据name值去匹配包括还是去掉该路由的缓存;max则表示最大缓存的组件实例数:

    <!-- 逗号分隔字符串 -->
    <keep-alive include="a,b">
      <component :is="view"></component>
    </keep-alive>
    
    
    
    <!-- 最大缓存组件实例数,超过则最久没访问的组件实例会被销毁 -->
    <keep-alive :max="10">
      <component :is="view"></component>
    </keep-alive>

        2)当组件在 <keep-alive> 内被切换,它的 activated (进)和 deactivated (出)这两个生命周期钩子函数将会被对应执行。使用场景:

          (A)、页面不刷新;

          (B)、同一个组件,不同的调用,导致不渲染,解决方法:

           a)监听路由变化:

    watch: {
        $route(val) {
            //代码片段
        }
    }

          b)beforeUpdateRoute

      (2)动态组件:使用场景:1)判断条件加载两个不同组件;2)加载动态表单

    <!-- 自定义属性可任意加 -->
    <component :is="data.length > 300 ? 'hello' : 'div'" :size="30">
    </component>

      (3)异步组件:(性能优化)

        1)代码覆盖率:加载的文件都只为展示当前的页面,覆盖率越高,性能越好;

        2)跟首屏无关;    

        3)按需加载.

    <!-- 需要加载hello组件时,会加载hello.js -->
    const Hello = () => import (/* webChunkName: 'hello' */ '@/views/hello');   

      (4)混入(mixin):全局/局部注册,解决复用问题(很多页面都需要有这些)

        1)mixin中生命周期和组件的合并,其他的则会覆盖组件的;

        2)坏处:看不见定义及处理,因此要少用。

      (5)inject和provide:解决跨级暴露并接收

    12、函数式组件:简单用于展示类的组件,无响应式,性能更好:

    <template functional>
        <!-- 组件内容 -->
    </template>

    13、插件:在new Vue()之前通过全局方法 Vue.use() 使用插件。

    14、过滤器:对数据的过滤。适用于v-bind和{{}}。主要场景是多个地方都用到的情况下,用过滤器,也可以全局注册:

    <!-- 在双花括号中 -->
    {{ message | capitalize }}
    
    <!-- 在 `v-bind` 中 -->
    <div v-bind:id="rawId | formatId"></div>
    //在实例中定义过滤器
    filters: {
        capitalize: function (value) {
            if (!value) return '';
            value = value.toString();
            return value.charAt(0).toUpperCase() + value.slice(1);
        }
    }
    
    
    
    //全局注册过滤器
    Vue.filter('capitalize', function (value) {
        if (!value) return '';
        value = value.toString();
        return value.charAt(0).toUpperCase() + value.slice(1);
    })
    
    new Vue({
      // ...
    })

    15、自定义组件的v-model:

    index.vue:
    
    <div>
        {{abc}}    //点击hello组件的按钮后,该变量变为233333
        <hello v-model="abc"></hello>
    </div>
    
    data() {
        return {
            abc: 1
        }
    }
    
    
    hello.vue:
    <button @click="changeA">Click!</button>
    
    props: ['abc'],
    model: {
        event: 'change',
        prop: 'abc'
    },
    methods: {
        chngeA() {
            this.$emit('change', 233333);
        }
    }

    16、生命周期钩子(常用):

      1)created:调接口,加载loading状态,定义不渲染视图不双向绑定的数据等;

      2)mounted:之后才能渲染DOM,注意DOM渲染时间差,用nextTick解决;

      3)destroyed:组件销毁时的操作;

      4)activated:在keep-alive时才有该生命周期,组件激活时调用,在服务器端渲染期间不被调用;

      5)deactivated:在keep-alive时才有该生命周期,组件停用时调用,在服务器端渲染期间不被调用。

    17、API:

      1)Vue.extend(options):创建构造器,并创建实例,挂载在页面元素上

    // 创建构造器
    var Profile = Vue.extend({
      template: '<p>{{firstName}}</p>',
      data: function () {
        return {
          firstName: 'Walter',
        }
      }
    })
    // 创建 Profile 实例,并挂载到body元素上。
    new Profile().$mount('body')

      2)Vue.compile:在 render 函数中编译模板字符串。只在独立构建时有效。

      3)<pre>:不编译,直接显示写入的代码片段。

     18、vm.$watch:添加动态监听,需要手动销毁:

    <div>
        <button @click="change">Click!!</div>
        <hello :abc="abc"></hello>
    </div>
    
    
    data() {
        return {
            abc: 1
        }
    },
    methods: {
        change() {
            this.abc++;
        }
    }
    
    
    hello.vue:
    
    <span>{{ abc }}</span>
    
    props: ['abc'],
    mounted() {
        //添加动态监听
        this.$watch('abc', function(val)) {
            console.log('val', val);   //每次点击都会走监听 
        });
    
        //添加回调内销毁的监听
        let unwatch = this.$watch('abc', function(val)) {
            console.log('val', val);   //只有第一次改变会走监听 
            unwatch();
        });
    }
  • 相关阅读:
    常用模板
    pascal 的字符串操作
    war2 洛谷模拟赛day2 t3 状压
    状压搜索 洛谷T47092 作业
    Milking Order
    洛谷九月月赛T1 思考
    C数列下标 牛客OI赛制测试赛2
    钓鱼 洛谷p1717
    机房人民大团结(DP)
    Spark的Straggler深入学习(2):思考Block和Partition的划分问题——以论文为参考
  • 原文地址:https://www.cnblogs.com/minozMin/p/11176353.html
Copyright © 2020-2023  润新知