• Vue基础(干货+代码)


    本文主要记录Vue2.0的干知识点 + 案例代码

    Vue官网教程: https://cn.vuejs.org/v2/guide/

    1.模板语法

    这两个部分操作的都是 data(){} 中的数据。

    1.插值语法

    插值语法: 把指定的值放到指定的位置。

    {{ js表达式 }} 读取data中的数据,可对读取到的数据进行处理。

    • 解析标签体内容

    2.指令语法

    v-bind:属性名="xxx" 单向绑定,数据只能从 data 流向页面,简写为 :

    • 一般用在标签属性中
    • xxx为js表达式

    v-model:value="xxx" 双向绑定,数据不仅能从 data 流向页面,还能从页面流向 data,简写为 v-model="xxx"

    • 只能用在表单元素上,如input、select

    v-text = "固定值"类似于innerText属性,作用与{{}}类似,但只能写一个固定的值。

    v-html="固定值" 类似于innerHTML属性,作用与{{}}类似,但只能写一个固定的值。

    v-once 具有v-once的标签中的数据只在界面上渲染一次。

    v-pre 标签具有v-pre,界面会原封不动地展示标签内的内容。

    v-cloak 标签具有v-cloak,在界面和数据还没完全渲染的时候,它不会展示,当界面和数据渲染完成,它才显示。需要和css的代码 [v-cloak]{ display: none } 一起配合使用。

    3.v-bind

    字符串写法:

    • 适用于:样式的类名不确定,需要动态指定。
    <div :class="{ active: isActive , 'text-danger': hasError}">div>
    
    • 1
    data: {
      isActive: true,
      hasError: false
    }
    
    • 1
    • 2
    • 3
    • 4

    数组写法:

    • 适用于:要绑定的样式个数不确定、名字也不确定
    <div :class="[activeClass, errorClass]">div>
    
    • 1
    data: {
      activeClass: 'active',
      errorClass: 'text-danger'
    }
    
    • 1
    • 2
    • 3
    • 4

    对象写法:

    • 适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用
    <div :class="classObject"></div>
    
    • 1
    data: {
      isActive: true,
      error: null
    },
    computed: {
      classObject: function () {
        return {
          active: this.isActive && !this.error,
          'text-danger': this.error && this.error.type === 'fatal'
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

        <!-- 绑定style样式--对象写法 -->
        <div class="basic" :style="styleObj"></div> 
    
        <!-- 绑定style样式--数组写法 -->
        <div class="basic" :style="styleArr"></div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    .basic{
            width: 400px;
            height: 100px;
            border: 1px solid black;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
                styleObj:{
                    fontSize: '40px',
                    color:'red',
                },
                styleArr:[
                    {
                        fontSize: '40px',
                        color:'blue',
                    },
                    {
                        backgroundColor:'gray'
                    }
                ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.事件绑定

    这部分操作的都是是 methods:{} 中的方法。

    注意: 普通函数中的this指代的是Vue实例,箭头函数中的this指代的是就不是Vue实例,箭头函数绑定到父上下文。

    1.触发事件的方式

    鼠标说明键盘说明表单说明
    click 鼠标单击keydown键盘按下blur失去焦点
    dblclick鼠标双击keyup键盘抬起focus获得焦点
    mousemove鼠标移动keypress按下按键change内容变化
    mouseover鼠标悬浮
    mouseout鼠标离开

    vue中常用的按键别名:

    • 回车:enter
    • 删除:delete (捕获“删除”和“退格”键)
    • 退出:esc
    • 空格:space
    • 换行:tab (特殊,必须配合keydown去使用)
    • 上:up
    • 下:down
    • 左:left
    • 右:right

    键盘事件注意事项:

    • 系统修饰键(用法特殊):ctrl、alt、shift、meta
      配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发
      配合keydown使用:正常触发事件
    • 可以使用keyCode去指定具体的按键,比如:@keydown.13=“showInfo”,但不推荐这样使用
    • Vue.config.keyCodes.自定义键名 = 键码,可以自定义按键别名

    2.基本用法

    v-on:click="方法名" 绑定一个点击触发的方法,简写为 @click

    • 不建议在methods中的方法使用箭头函数

    3.事件修饰符

    触发一个事件会经历以下两个过程:

    • 事件的捕获过程: 从最外面的祖先DOM传递到目标DOM
    • 事件的冒泡过程: 从目标DOM原路传出去

    默认情况,我们只是监测冒泡过程,只有给事件的触发条件加上了事件修饰符才会监测捕获过程。

    事件修饰符:使用格式:@click.修饰符1.修饰符2="方法名"

    修饰符说明
    prevent阻止默认事件
    stop阻止事件冒泡
    once事件只触发一次
    capture使用事件的捕获模式
    self只有目标DOM是当前操作时才触发事件
    passive事件的默认行为立即执行

    3.Computed 和 Watchers

    1.计算属性

    计算属性:根据已经存在的属性,去加工获得新的属性或属性值。对于复杂的逻辑,应该使用计算属性。

    • 要用的属性不存在,需要通过已有属性计算得来
    • 底层借助了Objcet.defineproperty()方法提供的getter和setter
      初次读取时会执行一次getter,依赖的数据发生改变时会被再次调用getter
    • 必须要有return返回,如果没有return会报错。
    • 与methods实现相比,内部有缓存机制(复用),效率更高,调试方便
    <div id="app">
      <p>Original message: "{{ message }}"p>
      <p>Computed reversed message: "{{ reversedMessage }}"p>
    div>
    
    • 1
    • 2
    • 3
    • 4
    var vm = new Vue({
      el: '#app',
      data: {
        message: 'Hello'
      },
      computed: {
        // a computed getter
        // 这里可以把function省略
        reversedMessage: function () {
          // `this` points to the vm instance
          return this.message.split('').reverse().join('')
        }
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    计算出的属性是基于它们的依赖关系进行缓存的。计算属性只会在其某些依赖项发生更改时才会重新评估。这意味着只要message没有改变,多次访问reversedMessage计算属性将立即返回先前计算的结果,而不必再次运行该函数。这就比methods效率更高。


    <div id="root">
      姓:<input type="text" v-model="firstName"><br><br>
      名:<input type="text" v-model="lastName"><br><br>
      姓名:<span>{{fullName}}span>
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
            new Vue({
                el:'#root', 
                data:{ 
                    firstName:'张',
                    lastName:'三'
                },
                computed:{
                    fullName:{
                        get(){
                            return this.firstName + '-' + this.lastName
                        },
                        set(value){
    						const arr = value.split('-')
    						this.firstName = arr[0]
    						this.lastName = arr[1]
                        }
                    }
                }
            })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2.监视属性

    监视属性:监视数据,当数据发生变化的时候,就会自动回调函数,进行相关的操作。

    • 监视的数据必须是存在的:data、props 、$route 、$emit 、computed

    监视属性简写:如果监视属性除了handler没有其他配置项的话,可以进行简写。

        const vm = new Vue({
            el:'#root',
            data:{
                isHot:true,
            },
            computed:{
                info(){
                    return this.isHot ? '炎热' : '凉爽'
                }
            },
            methods: {
                changeWeather(){
                    this.isHot = !this.isHot
                }
            },
            watch:{
                //正常写法
                isHot:{
    				handler(newValue,oldValue){
    					console.log('isHot被修改了',newValue,oldValue)
    				}
    			}, 
                //简写
                isHot(newValue,oldValue){
    				console.log('isHot被修改了',newValue,oldValue,this)
    			}
            }
        })
    
        //正常写法
        vm.$watch('isHot',{
            handler(newValue,oldValue){
                console.log('isHot被修改了',newValue,oldValue)
            }
        })
        //简写
        vm.$watch('isHot',function(newValue,oldValue){
            console.log('isHot被修改了',newValue,oldValue,this)
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    <div id="demo">{{ fullName }}div>
    
    • 1
    var vm = new Vue({
      el: '#demo',
      data: {
        firstName: 'Foo',
        lastName: 'Bar',
        fullName: 'Foo Bar'
      },
      watch: {
        firstName: function (val) {
          this.fullName = val + ' ' + this.lastName
        },
        lastName: function (val) {
          this.fullName = this.firstName + ' ' + val
        }
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    深度监视:监视对象的属性值的变化。

    • Vue中的watch默认不监测对象内部值的改变
    • 在watch中配置 deep:true 可以监测对象内部值的改变(多层)
        <div id="root">
            <h3>a的值是:{{numbers.a}}h3>
    		<button @click="numbers.a++">点我让a+1button>
    		<h3>b的值是:{{numbers.b}}h3>
    		<button @click="numbers.b++">点我让b+1button>
        div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
            new Vue({
                el:'#root', 
                data:{ 
                    isHot:true,
                    numbers:{
                        a:1,
                        b:1,
                    }
                },
                watch:{
                    //监视多级结构中所有属性的变化
                    numbers:{
                        deep:true,
    					handler(){
    						console.log('numbers改变了')
    					}
                    }
                    //监视多级结构中某个属性的变化
    				/* 'numbers.a':{
    					handler(){
    						console.log('a被改变了')
    					}
    				} */
                }
            })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    4.条件渲染

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>条件渲染title>
    		<script type="text/javascript" src="../js/vue.js">script>
    	head>
    	<body>
    		<div id="root">
    			<h2>当前的n值是:{{n}}h2>
    			<button @click="n++">点我n+1button>
    
    			<h2 v-show="true">Hello,{{name}}!h2>
    
    			<div v-if="n === 1">Angulardiv>
    			<div v-else-if="n === 2">Reactdiv>
    			<div v-else>Vuediv>
    		div>
    	body>
    
    	<script type="text/javascript">
    		Vue.config.productionTip = false
    
    		const vm = new Vue({
    			el:'#root',
    			data:{
    				name:'jojo',
    				n:0
    			}
    		})
    	script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    1.v-if

    v-if 当表达式为真时,才会显示组件内容,否则组件不可见。

    写法:

    • v-if="表达式"
    • v-else-if="表达式"
    • v-else

    适用场景:切换频率较低的场景(开发阶段需要经常刷新页面,建议使用v-show)。

    • 原因:不展示的DOM元素直接被移除

    注意:v-if 可以和 v-else-if 、 v-else 一起使用,但要求结构不能被打断

    2.v-show

    v-show 作用同 v-if 类似,表达式为真才显示组件内容,否则组件不可变。

    适用于:切换频率较高的场景。

    • 原因:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉

    注意: v-show 不能与