Vue(一) 插值与指令语法、数据代理、MVVM模式、事件处理

文章目录

  • 1. 初始Vue
  • 2. 模板语法
    • 2.1 插值语法
    • 2.2 指令语法
  • 3. el与data的两种写法
    • 3.1 el的两种写法
    • 3.2 data的两种写法
  • 4. MVVM模式
  • 5. 数据代理
    • 5.1 Object.defineProperty()
    • 5.2 何为数据代理
    • 5.4 vue中的数据代理
  • 6. 事件处理
    • 6.1 v-on
    • 6.2 事件修饰符
    • 6.3 键盘按键事件

1. 初始Vue

  
<script type="text/javascript" src="./js/vue.js">script>
  
<div id="root">
    hello {{name}}
div>

<script>
    // 创建Vue实例
    new Vue({
        el: '#root',  //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
        data: {       //data中用于存储数据,数据供el所指定的容器去使用,data暂时先写成一个对象。
            name: 'tom'
        }
    })
script>

总结:
1、想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象;
​2、root容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法;
3、root容器里的代码被称为【Vue模板】;
4、Vue实例和容器是一一对应的;一个容器只能由一个Vue实例接管,
5、真实开发中只有一个Vue实例,并且会配合着组件一起使用;

2. 模板语法

2.1 插值语法

  • 功能:用于解析标签体内容。
  • 写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。

2.2 指令语法

  • 功能:用于解析标签(包括:标签属性、标签体内容、绑定事件…)。
  • 写法:v-xxx
  • 比如:v-bind语法,v-bind:href=“xxx” xxx同样要写js表达式,且可以直接读取到data中的所有属性。(注:Vue中有很多的指令,且形式都是:v-???,只是拿v-bind举个例子。)
<div id="root">
    hello, {{stu.name.toUpperCase()}}
    <br>
    <a v-bind:href="url">百度a>
    <a v-bind:href="url.toUpperCase()">百度a>
div>
<script>
    new Vue({
        el: '#root',
        data: {
            stu: {
                name: 'tom',
                age: 18
            },
            url: 'https://www.baidu.com/',
        }
    })
script>

最终页面被解析为:
Vue(一) 插值与指令语法、数据代理、MVVM模式、事件处理_第1张图片
注意区分:js表达式 和 js代码(语句)

  1. 表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方:
    (1). a
    (2). a+b
    (3). demo(1)
    (4). x === y ? ‘a’ : ‘b’
  2. js代码(语句)
    (1). if(){}
    (2). for(){}

3. el与data的两种写法

3.1 el的两种写法

写法一:new Vue的时候配置el属性。

<script>
    const v = new Vue({
        el: '#root',   //第一种写法
        data: {
            name: 'tom',
        }
    })
script>

写法二:先创建Vue实例,随后再通过 Vue实例.$mount(‘#root’)指定el的值

<script>
    const v = new Vue({
        data: {
            name: 'tom',
        }
    })
    // 第二种写法
    v.$mount('#root')
script>

3.2 data的两种写法

写法一:对象式

<script>
    // data的两种写法
    new Vue({
        el: '#root',
        // 对象式
        data: {
            name: 'tom',
        }
    })
script>

写法二:函数式

<script>
    new Vue({
        el: '#root',
        // 函数式
        data: function () {
            console.log(this);  
            return {
                name: '山西'
            }
        }
    })
// 或者简写为:
    new Vue({
        el: '#root',
        // 函数式
       data () { //不可写为箭头函数,否则this返回的不是Vue实例
            console.log(this);  // this返回的是vue实例
            return {
                name: '山西'
            }
        }
    })
script>

data的2种写法:对象式、函数式。
如何选择:目前哪种写法都可以,以后学习到组件时,data必须使用函数式,否则会报错。
一个重要的原则:由Vue管理的函数 (data函数就是一个Vue管理的函数),一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了

4. MVVM模式

  1. M—模型(Model) :data中的数据
  2. V—视图(View) :模板代码,页面
  3. VM—视图模型(ViewModel):Vue实例
    Vue(一) 插值与指令语法、数据代理、MVVM模式、事件处理_第2张图片
    Data Bindings: model的数据挂在ViewModel上,然后数据绑定到页面中
    DOM Listeners: 监听View页面里数据的变化,修改Model里对应的数据(有点儿像双向数据绑定)
    View Model则在页面和数据之间起连接作用,所以一般命名Vue实例为vm

拓展
(1) data中所有的属性,最后都出现在了vm身上。
(2) vm身上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。

   <div id="root">
        姓名:{{name}}
        <br>
        地址:{{address}
        <br>
        
        vm属性$options{{$options}}
        <br>
        Vue原型{{$emit}}
    div>
    <script>
        const vm = new Vue({
            el: '#root',
            data: {
                name: '小白',
                address: '北京'
            }
        })
        console.log(vm);
    script>

Vue(一) 插值与指令语法、数据代理、MVVM模式、事件处理_第3张图片
Vue(一) 插值与指令语法、数据代理、MVVM模式、事件处理_第4张图片

5. 数据代理

5.1 Object.defineProperty()

语法:Object.defineProperty(对象,属性名,配置项) :给对象添加属性

需求1: 给person添加age属性

let obj = {
    name: 'jerry',
    gender: '男',
    age: 10
}
let person ={
    name: 'jerry',
    gender: '男',
}
Object.defineProperty(person, 'age', {
    value: 10,
    enumerable: true, // 控制属性是否可以被枚举,默认false Object.keys(对象)
     writable: true,   // 控制属性是否可以被修改,默认false
     configurable: true, // 控制属性是否可以被删除,默认false
});

Vue(一) 插值与指令语法、数据代理、MVVM模式、事件处理_第5张图片
相较于objperson这种添加属性的方式可以对属性进行设置,obj则不能设置


需求2:现有一个number数据,如何使age的值始终为number的值

let number = 10;
const person = {
    name: 'tom',
    gender: '男',
}
Object.defineProperty(person, 'age', {
    // 当有人读取person的age属性时,get函数(一般说getter方法)就会被调用,且返回值就是age的值
    get () {
        console.log('读取age值');
        return number
    },
    // 当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
    set (value) {
        console.log('修改age值');
        number = value
    }
})

Vue(一) 插值与指令语法、数据代理、MVVM模式、事件处理_第6张图片
此外,打印person也可以发现
Vue(一) 插值与指令语法、数据代理、MVVM模式、事件处理_第7张图片
点击(…)时,也会调用getter方法

5.2 何为数据代理

数据代理:通过一个对象来对另一个对象的属性进行读或写的操作。

// obj有个x,希望通过obj2对obj的x进行读取和修改
let obj = { x: 100 }
let obj2 = { y: 200 }
Object.defineProperties(obj2, 'x', {
    get () {
        return obj.x
    },
    set (value) {
        obj.x = value
    }
})

Vue(一) 插值与指令语法、数据代理、MVVM模式、事件处理_第8张图片

5.4 vue中的数据代理

<div class="root">
	<h2>学校名称:{{name}}h2>
	<h2>学校地址:{{address}}h2>
div>
<script>
	const vm = new Vue({
		el: 'root',
		data: {
			name: '尚硅谷',
			address: '北京'
		}
	})
script>

打印vm得知,vm身上的nameaddress都是Object.definePropterty()加上去的
Vue(一) 插值与指令语法、数据代理、MVVM模式、事件处理_第9张图片
vm将data数据存在了自身的_data中,当读取vm.address时,通过getter方法获取Vm._data.address的值
Vue(一) 插值与指令语法、数据代理、MVVM模式、事件处理_第10张图片
Vue(一) 插值与指令语法、数据代理、MVVM模式、事件处理_第11张图片
总结:
1、Vue中的数据代理:通过vm对象来代理data对象中属性的操作(读、写)
2、Vue中数据代理的好处:更方便操作data中的数据,不用写_data.name,直接写name就行。
3、基本原理:通过Object.defineProperty()把data对象中的所有属性加到vm上,为每一个添加到vm上的属性指定getter/setter。在getter/setter内部操作(读、写)data中对应的属性

6. 事件处理

6.1 v-on

语法:v-on:xxx 或简写方式 @xxx绑定事件,xxx是事件名

<div id="root">
    <button v-on:click="showInfo1">(v-on)不传参函数button>
    <button @click="showInfo2($event,66)">(@)不传参函数button>
div>

不传参的函数默认接收事件对象event

const vm = new Vue({
    el: '#root',
    data: {
        name: 'tom'
    },
    methods: {
        showInfo1 (event) {
            console.log('showInfo1');
            console.log(event);
        },
        showInfo2 (event, number) {
            console.log(event);
            console.log(number);
        },
        // showInfo1: (event) => {
        // 	console.log(this); // window;指向的不是vue实例了
        // }
    }
})
  • 事件的回调需配置在methods对象中,最终会挂在vm上
  • methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象;如果是箭头函数,则指向的不是vm了
  • @click=“demo” 和 @click=“demo($event)” 效果一致,但后者可以传参;

6.2 事件修饰符

  • prevent:阻止默认事件(常用);
  • stop:阻止事件冒泡(常用)
  • once:事件只触发一次(常用)
  • capture:使用事件的捕获模式;
  • self:只有event.target是当前操作的元素时才触发事件;
  • passive:事件的默认行为立即执行,无需等待事件回调执行完毕;

1、阻止默认事件
Vue: prevent ----> 对应原生jsevent.preventDefault()

<div id="root">
    <a href="https://www.baidu.cn" @click.prevent="moveToBaidu">点击链接跳转百度a>div>
<script>
    const vm = new Vue({
        ...
        methods: {
            moveToBaidu (event) {
                // event.preventDefault()
                console.log('点击链接');
            }
        }
    })
script>

2、阻止事件冒泡
Vue: stop ----> 对应原生js event.stopPropagation()

<div @click="stopBubble('div')" class="bubbleBox">
    <button @click="stopBubble('btn')">点击冒泡button>
div>
<script>
    const vm = new Vue({
        ...
        methods: {
            stopBubble (str) {
                // event.stopPropagation();
                console.log(str + '冒泡');
            }
        }
        ...
    })
script>

未添加stop修饰符时,点击button,分别打印:btn冒泡 div冒泡。
添加stop修饰符后,点击button,打印:btn冒泡

<button @click.stop="stopBubble('btn')">点击冒泡button>

注:修饰符可以连写

<div @click="stopBubble('div')" class="bubbleBox">
    
    <a href="https://www.baidu.cn" @click.stop.prevent="stopBubble('a链接')">点击链接跳转百度button>
div>

3、事件只发生一次
点击button,打印once;再点击,则不会再触发事件

<button @click.once="showOnce">点击事件只触发一次button>
<script>
    const vm = new Vue({
        ...
        methods: {
            showOnce () {
                console.log('once');
            }
        }
        ...
    })
script>

4、事件捕获
事件流是先捕获,后冒泡。而在上述冒泡事件点击中,点击button,依次打印:btn冒泡 div冒泡。这是因为默认对冒泡事件进行响应。
若给div添加捕获模式,则依次打印:div冒泡,btn冒泡

<div @click.capture="stopBubble('div')" class="bubbleBox">
    <button @click="stopBubble('btn')">点击冒泡button>
div>

6.3 键盘按键事件

keyup和keydown都是键盘按键事件。
键盘每个键都有键名和值,通过key和keycode可以获取

key <input type="text" @keydown="showKey">
<script>
    const vm = new Vue({
        ...
        methods: {
            showKey (e) {
                console.log(e.key,e.keycode);  //打印按键
            }
        }
    })
script>

Vue(一) 插值与指令语法、数据代理、MVVM模式、事件处理_第12张图片每按一个键,都会触发一次事件。若想在按某个键(比如回车)之后再触发事件,可以在keydown/keyup后指定按键。
Vue里常用的按键别名:

  • 回车 => enter ; 删除 => delete ; 退出 => esc ; 空格 => space
  • 换行 => tab ; 上 => up ; 下 => down ; 左 => left ; 右 => right
enter<input type="text" @keydown.enter="showInfo"><br>

Tab<input type="text" @keydown.Tab="showInfo"><br>
<script>
    const vm = new Vue({
        ...
        methods: {
           	showInfo (e) {
				console.log(e.target.value);
			}
        }
    })
script>

若两个键配合使用,则:

Ctrl+y <input type="text" @keydown.ctrl.y="showInfo">

系统修饰键:ctrl、alt、shift、meta

  • 配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发
  • 配合keydown使用:正常触发事件

总结: 系统修饰键配合keyup触发事件很麻烦,tab键配合keyup不起作用,因此键盘按键事件一般都用keydown,不用keyup

你可能感兴趣的:(Vue,vue.js,前端,javascript)