2 vue基础

1 适合人群

有一定的HTML/CSS/javaScript+ES6+基础开发人员


2 vue框架学习路线

html/css/js=>es6=>vue基础+组件化开发=>vue核心插件vue-router和vuex=>搜索
社区大牛的资料继续深入学习+(底层源码)


3 历史介绍

  • angular 09年,年份较早,一开始大家是拒绝star:

    image

  • react 2013年,用户体验好,直接拉到一堆粉丝star:

    image

  • vue 2014年,用户体验好作者:尤雨溪江苏无锡人 国人骄傲

    image


4 前端框架与库的区别

  • jquery 库=> DOM(操作DOM)+请求

  • 有可能学习了一些art-template库->模板引擎

  • 框架
    。全方位功能齐全
    。简易的DOM体验+发请求+模板引擎+路由功能

  • KFC的世界里,库就是一个小套餐,框架就是全家桶

  • 代码上的不同
    。一般使用库的代码,是调用某个函数,我们自己把控库的代码
    。一般使用框架,其框架在帮我们运行我们编写好的代码

框架:初始化自身的一些行为
执行你所编写的代码
施放一些资源


5 vue起步

  1. 引包

    • 安装:参考网址(https://cn.vuejs.org/v2/guide/installation.html)

      // 下载之后引包
      <script src="./vue.js"></script>
      
  2. 启动初始化

    new Vue({
        el: '#app', //目的地
        data: {
            //保存数据的地方
        },
        methods: {
            // 声明方法
        },
        template: `模板内容`
    });
    
  3. 小案例

    html:

    <div id="app">
        <h2>{{ msg }}</h2> <!--插入变量名-->
        <h3>{{ 2 }}</h3>  <!--插入数值-->
        <h3>{{ "刘大帅" }}</h3>  <!--插入字符串-->
        <h3>{{ {id:1} }}</h3>  <!--插入对象-->
        <h3>{{ 1>2 ? "真的":"假的" }}</h3>  <!--插入表达式-->
        <h3>{{ text.split("").reverse().join("") }}</h3>  <!--字符翻转-->
        <h3>{{ getContent() }}</h3>  <!--调用方法-->
    </div>
    

    js:

    <script src="./vue.js"></script>
    <script>
        const vm = new Vue({
            el: '#app', //目的地
            data: {
                // 声明数据属性
                msg: 'hello vue',
                text: 'alex',
                msg2: 'content..'
            },
            methods: {
                // 声明方法
                getContent(){
                    return this.msg + ' ' + this.msg2
                }
            }
            //template: `模板内容`
        });
    </script>
    

6 插值表达式

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

示例:

<div id="app">
    <h2>{{ msg }}</h2> <!--插入变量名-->
    <h3>{{ 2 }}</h3>  <!--插入数值-->
    <h3>{{ "刘大帅" }}</h3>  <!--插入字符串-->
    <h3>{{ {id:1} }}</h3>  <!--插入对象-->
    <h3>{{ 1>2 ? "真的":"假的" }}</h3>  <!--插入表达式-->
    <h3>{{ text.split("").reverse().join("") }}</h3>  <!--字符翻转-->
    <h3>{{ getContent() }}</h3>  <!--调用方法-->
</div>

7 什么是指令

  • vue中提供了一些对于页面 + 数据的更为方便的输出,这些操作就叫做指令,以v-xxx表示
    • 比如html页 面中的属性i <div v-xxx ></div>
  • 比如在angular中以ng- xxx开头的就叫做指令
  • vue中以v-xxx开头的就叫做指令
  • 指令中封装了-些DOM行为,结合属性作为一个暗号,暗号有对应的值,根据不同的值,框架会进行相关DOM操作的绑定

8 vue中常用的v-指令演示

  • v-text:元素的textContent属性,必须是双标签跟{{ }}效果是一样的使用较少

  • v-html:元素的innerHTML

    示例:

    <div id="app">
        <!--插入文本方式-->
        <h1>{{ msg }}</h1>
        <h2 v-text="msg"></h2>
        <!--插入标签-->
        <div v-html="htmlMsg"></div>
    </div>
    
    <script src="vue.js"></script>
    <script>
        // {{}}和v-text的作用是一样的,都是插入值直接渲染
        // v-html即能插入值又能插入标签
        new Vue({
            el: "#app",
            data: {
                msg: "插入标签",
                htmlMsg: '<h3>刘大帅</h3>'
            }
        })
    </script>
    
  • v-if :判断是否插入这个元素,相当于对元素的销毁和创建

  • v-else-if

  • v-else

  • v-show 隐藏元素如果确定要隐藏,会给元素的style加.上display:none。是基于css样式的切换

    <div id="app">
        <div v-if="isShow">
            显示
        </div>
        <div v-else>
            隐藏
        </div>
        <h3 v-show="show">正常显示</h3>
    </div>
    
    <script src="vue.js"></script>
    <script>
        // v-if v-else-if v-else v-show
        new Vue({
            el: '#app',
            data: {
                isShow:Math.random() > 0.5,
                show: true
            }
        })
    </script>
    

9 v-ifv-show的区别

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

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

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

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


10 v-bind使用

  • 给元素的属性赋值
    • 可以给已经存在的属性赋值input value
    • 也可以给自定义属性赋值mydata
  • 语法在元素上v-bind:属性名="常量||变量名"
  • 简写形式:属性名="变量名"
  • v-bind就是对属性的简单赋值,当内存中值改变,还是会触发重新渲染
<div v-bind:原属性名="变量"></div>
<div :属性名="变量"></div>

示例:

<style>
    .active{color: red;}
</style>

<div id="app">
    <a v-bind:href="res.url" v-bind:title="res.title">{{ res.name }}</a>
    <!--v-bind 可简写为 :  列如以下-->
    <img :src="imgSrc" width="200">
    <!--可动态切换-->
    <h3 class="name" :class="{active:isActive}">v-bind的用法</h3>
    <h4 :style="{color:isColor,fontSize:fontSize}">hello</h4>
</div>

<script src="vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            res: {
                name: '百度',
                url: 'https://www.baidu.com',
                title: '百度一下'
            },
            imgSrc: './images/123.jpg',
            isActive: true,
            isColor: 'green',
            fontSize: '40px',
        }
    })
</script>

11 v-on的使用

  • 处理自定义原生事件的,给按钮添加click并让使用变量的样式改变
  • 普通使用 v-on:事件名="表达式| |函数名"
  • 简写方式 @事件名="表达式"
<style>
  .box{
    width: 200px;
    height: 200px;
    background-color: red;
  }
  .active{
    background-color: gray;
  }
</style>

<div id='app'>
  <h3>{{num}}</h3>
  <button v-on:click="handleClick">+1</button>
  <div class="box" :class="{active:isActive}"></div>
  <!--v-on指令可以简写为 @ 如下示例-->
  <button @click="changeClick">切换</button>
</div>

<script src="vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      num: 0,
      isActive: false,
    },
    methods: {
      handleClick(){this.num+=1;},
      changeClick(){this.isActive = !this.isActive;}
    }
  })
</script>

11-1 事件修饰符

.once :只能执行一次

<div id='app'>
  <h3>{{num}}</h3>
  <button v-on:click.once="handleClick">+1</button>
</div>

<script src="vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      num: 0,
    },
    methods: {
      handleClick(){this.num+=1;},
    }
  })
</script>

https://cn.vuejs.org/v2/guide/events.html#事件修饰符

详细查阅官方文档!


11-2 按键修饰符

.enter:回车按键

<div id='app'>
  <input @:keyup.enter="submit">
</div>

<script src="vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {},
    methods: {
      submit(){alert('按下了回车键');}
    }
  })
</script>

11-3 为什么在 HTML 中监听事件

你可能注意到这种事件监听的方式违背了关注点分离 (separation of concern) 这个长期以来的优良传统。但不必担心,因为所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上,它不会导致任何维护上的困难。实际上,使用 v-on 有几个好处:

  1. 扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
  2. 因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
  3. 当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们。

12 v-model双向数据绑定

  • 双向数据流(绑定)
    • 页面改变影响内存(js)
    • 内存(js)改变影响页面
<div id="app">
    <p>{{msg}}</p>
    <!--默认value绑定msg-->
    <!--当输入框中的值发生变化时,p便签中的值也跟着变化-->
    <input type="text" v-model="msg">
</div>

<script src="vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            msg: '大帅逼',
        }
    })
</script>

应用:

<div id="app">
    <!--复选框单选-->
    <label for="checkbox">{{checked}}</label>
    <input type="checkbox" id="checkbox" v-model="checked">
    <!--复选框多选-->
    <div class="box">
        <label for="a">黄瓜</label>
        <input type="checkbox" id="a" value="黄瓜" v-model="checkedNames">
        <label for="b">西瓜</label>
        <input type="checkbox" id="b" value="西瓜" v-model="checkedNames">
        <br>
        <span>{{checkedNames}}</span>
    </div>
</div>

<script src="vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            checked: false,
            checkedNames: []
        }
    })
</script>

(https://cn.vuejs.org/v2/guide/forms.html#单选按钮)


13 v-bingv-model的区别

  • input v-model="name"
    • 双向数据绑定页面对于input的value改变,能影响内存中name变量
    • 内存js改变name的值,会影响页面重新渲染最新值
  • input :value="name"
    • 单向数据绑定内存改变影响页面改变
  • v-model: 其的改变影响其他v-bind:其的改变不影响其他
  • v-bind就是对属性的简单赋值,当内存中值改变,还是会触发重新渲染

14 v-for的使用

  • 基本语法v-for="item in arr"

  • 对象的操作v-for="item in obj"

  • 如果是数组没有id

    • v-for="(item, index) in arr" :class="index"
  • v-for的优先级最高

  • 维护状态

    • Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略
    • 为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key attribute:
    • 建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
    • 因为它是 Vue 识别节点的一个通用机制,key 并不仅与 v-for 特别关联。后面我们将在指南中看到,它还具有其它用途
<div id="app">
    <div>
        <ul>
            <li v-for="(item,index) in menus" :key="item.id">
            <!--能遍历数组-->
                <h3>{{index}}-id:{{item.id}}菜名:{{item.name}}</h3>
            </li>
        </ul>
        <ol>
            <!--能遍历对象-->
            <li v-for="(val,key) in obj" :key="key">{{key}}--{{val}}</li>
        </ol>
    </div>
</div>

<script src="vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            menus: [
                {id:1,name:'大腰子'},
                {id:2,name:'烤鸡翅'},
                {id:3,name:'烤韭菜'},
                {id:4,name:'红烧肉'},
            ],
            obj: {
                title: 'hello 循环',
                author: '大帅逼',
            }
        }
    })
</script>

15 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)
                }
            }

        }
    })
</script>

16 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>

16-1 setter方法

<div id="app">
    <p>{{msg}}</p>
    <input type="text" v-model="content" @input="handleInput">
    <button @click="handleClick">获取</button>
</div>

<script src="vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            msg: '',
        },
        methods: {
            handleInput: function (event) {
                const {value} = event.target;
                this.content = value;
            },
            handleClick(){
                if (this.content){
                    console.log(this.content);
                }
            }
        },
        computed: {
            content: {
                set: function (newV) {
                    this.msg = newV;
                },
                get: function () {
                    return this.msg;
                }
            }
        },
    })
</script>

17 filters过滤器

类似格式化输出

<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('');
    })

    // 为数据添油加醋
    new Vue({
        el: '#app',
        data: {
            price: 10,
            msg: 'hello过滤器'
        },
        // 局部过滤器
        filters: {
            myPrice: function (price,a) {
                return "$"+price+a;
            }
        },
    })
</script>

18 案例:音乐播发器

音乐资源,要提前下载好。放到一个static文件中。

<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>
<div id="app">
    <audio :src="getCurrentSongSrc" controls autoplay @ended="handleEnded"></audio>
    <ul>
        <li :class="{active:index===currentIndex}"
            v-for="(item,index) in musicData"
            :key="item.id"
            @click="handleClick(index)">
            <h3>{{item.id}}-歌名:{{item.name}}</h3>
            <p>作者:{{item.author}}</p>
        </li>
    </ul>
    <button @click="handleNext">下一首</button>
</div>

<script src="vue.js"></script>
<script>
    const musicData = [
        {
            id:0,
            name: 'Jean Roch - Can You Feel It (Big Ali Edit)',
            author: 'Jean Roch',
            songSrc: './static/Jean Roch - Can You Feel It (Big Ali Edit).mp3'
        },
        {
            id:1,
            name: '庞龙 - 兄弟抱一下',
            author: '庞龙',
            songSrc: './static/庞龙 - 兄弟抱一下.mp3'
        },
        {
            id:2,
            name: '田馥甄 - 魔鬼中的天使 (降调版伴奏)',
            author: '田馥甄',
            songSrc: './static/田馥甄 - 魔鬼中的天使 (降调版伴奏).mp3'
        },
        {
            id:3,
            name: '郭美美 - 上帝是个女孩',
            author: '郭美美',
            songSrc: './static/郭美美 - 上帝是个女孩.mp3'
        }
    ]

    new Vue({
        el: '#app',
        data: {
            musicData,
            currentIndex: 0,
        },
        computed: {
            getCurrentSongSrc(){
                return this.musicData[this.currentIndex].songSrc;
            }
        },
        methods: {
            handleClick(index){
                this.currentIndex = index;
            },
            handleEnded(){
                this.handleNext();
            },
            handleNext(){
                this.currentIndex++;
                if(this.currentIndex === this.musicData.length){
                    this.currentIndex = 0;
                }
            }
        }
    })
</script>
posted @ 2022-09-26 14:38  角角边  Views(32)  Comments(0)    收藏  举报