2020年末了,快来看Vue全家桶系列之Vue基础 (后面含Vue3.0)

2,899 阅读5分钟

Vue3.0会在后续更新~~~~

喜欢本文章的同学,记得关注-点赞-转发

看本文章的时候,带着几个问题回过头来思考

  1. Vue性能优化从代码级别要多注意什么?
  2. computed和watch的区别?
  3. 双向数据绑定的原理?
  4. 观察者模式和订阅发布模式的区别?
  5. Vue2.0中对数组是如何实现响应式的?说一下过程
  6. Vue3.0如何解决对数组和对象的数据的响应式的?为什么要这样解决?优点是什么,缺点是什么?

知道答案的同学,欢迎大家勇于评论以上六个问题。勇敢的说出来,你就能很好的跟面试官进行沟通

vue基础


历史介绍

  • angular 09年,年份较早,一开始大家是拒绝 star:
  • react 2013年, 用户体验好,直接拉到一堆粉丝 star:
  • vue 2014年, 用户体验好 作者:尤雨溪 江苏无锡人 国人骄傲

前端框架与库的区别?

  • jquery 库 => DOM(操作DOM) + 请求
  • 有可能学习了一些art-template 库 -> 模板引擎=>简化DOM操作
  • 框架
    • 全方位功能齐全
    • 简易的DOM体验 + 发请求 + 模板引擎 + 路由功能
  • KFC的世界里,库就是一个小套餐, 框架就是全家桶
  • 代码上的不同
    • 一般使用库的代码,是调用某个函数,我们自己把控库的代码
    • 一般使用框架,其框架在帮我们运行我们编写好的代码
      • 框架: 初始化自身的一些行为
        • 执行你所编写的代码
        • 施放一些资源

vue起步

  • 1:引包

  • 2:启动

    new Vue({
        el:'#app',//目的地
        data:{
          //保存数据的地方  
        },
        template:`模板内容`
    });
    

插值表达式

  • {{ 表达式 }}
    • 对象 (不要连续3个{{ {name:'jack'} }})
    • 字符串 {{ 'xxx' }}
    • 判断后的布尔值 {{ true }}
    • 三元表达式 {{ true?'是正确':'错误' }}
  • 可以用于页面中简单粗暴的调试
  • 要用插值表达式 必须要data中声明该属性

什么是指令

  • 在vue中提供了一些对于页面 + 数据的更为方便的输出,这些操作就叫做指令, 以v-xxx表示

    • 比如html页面中的属性 ```
      ``
  • 比如在angular中 以ng-xxx开头的就叫做指令

  • 在vue中 以v-xxx开头的就叫做指令

  • 指令中封装了一些DOM行为, 结合属性作为一个暗号, 暗号有对应的值,根据不同的值,框架会进行相关DOM操作的绑定

vue中常用的v-指令演示

  • v-text:元素的textContent属性,必须是双标签 跟{{ }}效果是一样的 使用较少
  • v-html: 元素的innerHTML
  • v-if : 判断是否插入这个元素,相当于对元素的销毁和创建
  • v-else-if
  • v-else
  • v-show 隐藏元素 如果确定要隐藏, 会给元素的style加上display:none。是基于css样式的切换

v-if和v-show的区别 (官网解释)

v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。

v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

v-bind使用

  • 给元素的属性赋值

    • 可以给已经存在的属性赋值 input value
    • 也可以给自定义属性赋值 mydata
  • 语法 在元素上 v-bind:属性名="常量||变量名"

  • 简写形式 :属性名="变量名"

  • <div v-bind:原属性名="变量"></div>
    <div :属性名="变量">
    </div>
    

v-on的使用

  • 处理自定义原生事件的,给按钮添加click并让使用变量的样式改变
  • 普通使用 v-on:事件名="表达式||函数名"
  • 简写方式 @事件名="表达式"

v-model 双向的数据绑定

  • 双向数据流(绑定)
    • 页面改变影响内存(js)
    • 内存(js)改变影响页面

v-bind 和 v-model 的区别

  • input v-model="name"

    • 双向数据绑定 页面对于input的value改变,能影响内存中name变量
    • 内存js改变name的值,会影响页面重新渲染最新值
  • input :value="name"

    • 单向数据绑定 内存改变影响页面改变
  • v-model: 其的改变影响其他 v-bind: 其的改变不影响其他

  • v-bind就是对属性的简单赋值,当内存中值改变,还是会触发重新渲染

v-for的使用

  • 基本语法 v-for="item in arr"
  • 对象的操作 v-for="item in obj"
  • 如果是数组没有id
    • v-for="(item,index) in arr" :class="index" :key='index'
  • v-for的优先级最高

侦听器watch

基本的数据类型可以使用watch直接监听,复杂数据类型Object Array 要深度监视

<div id='app'>
    <input type="text" v-model='msg'>
    <h3>{{msg}}</h3>
    <h3>{{stus[0].name}}</h3>
    <button @click='stus[0].name = "Tom"'>改变</button>
</div>
<script src="./vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            msg:'',
            stus:[{name:'jack'}]
        },
        watch: {
            // key是属于data对象的属性名 value:监视后的行为 newV :新值 oldV:旧值
            'msg':function(newV,oldV){
                // console.log(newV,oldV);
                if(newV === '100'){
                    console.log('hello');
                }

            },
            // 深度监视: Object |Array
            "stus":{
                deep:'true',
                handler:function(newV,oldV){
                    console.log(newV[0].name);

                }
            }
        },
    })

计算属性之computed

<div id='app'>
    {{reverseMsg}}
    <h3>{{fullName}}</h3>
    <button @click='handleClick'>改变</button>
</div>
<script src="./vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            msg: 'hello world',
            firstName: '小马',
            lastName: '哥'
        },
        methods: {
            handleClick(){
                this.msg = '计算属性computed';
                this.lastName = '妹';
            }
        },
        computed: {
            // computed默认只有getter方法
            // 计算属性最大的优点:产生缓存 如果数据没有发生变化 直接从缓存中取
            reverseMsg: function () {
                return this.msg.split('').reverse().join('')
            },
            fullName: function () {
                return this.firstName + this.lastName;
            }
        },

    })
</script>

过滤器

<div id="app">
    <h3>{{price | myPrice('¥')}}</h3>
    <h3>{{msg|myReverse}}</h3>
</div>
<script src="./vue.js"></script>
<script>
    // 创建全局过滤器
    Vue.filter('myReverse', (val) => {
        return val.split('').reverse().join('');
    })
    // 为数据添油加醋
    // ¥  $20
    new Vue({
        el: '#app',
        data: {
            price: 10,
            msg:'hello 过滤器'
        },
        // 局部过滤器
        filters: {
            myPrice: function (price, a) {
                return a + price;

            }
        }

    })
</script>

案例:音乐播放器

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>案例:音乐播放器</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        ul {
            list-style: none;
        }

        ul li {
            margin: 20px 20px;
            padding: 10px 5px;
            border-radius: 3px;
        }

        ul li.active {
            background-color: #D2E2F3;
        }
    </style>
</head>

<body>
    <div id='app'>
        <audio :src="currentSrc" controls autoplay @ended='handleEnded'></audio>
        <ul>
            <li :class='{active:index===currentIndex}' v-for='(item,index) in musicData' :key='item.id'
                @click='handleClick(item.songSrc,index)'>
                <h2>{{item.id}}-歌名:{{item.name}}</h2>
                <p>{{item.author}}</p>
            </li>
        </ul>
        <button @click='handleNext'>下一首</button>
    </div>

    <script src="./vue.js"></script>
    <script>
        const musicData = [{
                id: 1,
                name: '于荣光 - 少林英雄',
                author: '于荣光',
                songSrc: './static/于荣光 - 少林英雄.mp3'
            },
            {
                id: 2,
                name: 'Joel Adams - Please Dont Go',
                author: 'Joel Adams',
                songSrc: './static/Joel Adams - Please Dont Go.mp3'
            },
            {
                id: 3,
                name: 'MKJ - Time',
                author: 'MKJ',
                songSrc: './static/MKJ - Time.mp3'
            },
            {
                id: 4,
                name: 'Russ - Psycho (Pt. 2)',
                author: 'Russ',
                songSrc: './static/Russ - Psycho (Pt. 2).mp3'
            }
        ];

        new Vue({
            el: '#app',
            data: {
                musicData,
                currentSrc: './static/于荣光 - 少林英雄.mp3',
                currentIndex: 0
            },
            methods: {
                handleClick(src, index) {
                    this.currentSrc = src;
                    this.currentIndex = index;
                },
                handleEnded() {
                    // // 下一首的播放
                    // this.currentIndex++;
                    // this.currentSrc = this.musicData[this.currentIndex].songSrc;
                    this.handleNext();
                },
                handleNext() {
                    this.currentIndex++;
                    if (this.currentIndex === this.musicData.length) {
                        this.currentIndex = 0;
                    }
                    this.currentSrc = this.musicData[this.currentIndex].songSrc
                }
            }
        })
    </script>

</body>

</html>