Vue01-数据绑定+数据代理+事件处理
1.入门程序
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- 引入vue.js -->
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 4 容器 -->
<!-- 使用vue需要准备好一个容器,容器中的内容成为'vue模板'。 -->
<!-- 使用vue的插值表达式'{{}}'可以取到data中的数据。 -->
<!-- 容器中的插值表达式{{}}可以写JavaScript表达式。 -->
<!--
JavaScript表达式和JavaScript代码。
表达式会有一个返回值,如demo()。表达式是一种特殊的JavaScript代码。
代码。if(){}
-->
<h2>hello,{{name}},{{1+1}},{{name.toUpperCase()}}</h2>
</div>
<script>
// 设置为 false 阻止vue在启动时生成生产提示。
Vue.config.productionTip = false;
// 1 创建Vue实例。
// 创建Vue时需要传递配置对象。配置对象的特点是,key和value数据类型不能修改,value的值可以是任意值。
// 一个Vue实例只能控制一个容器,如果页面中有多个容器,则Vue实例会控制第一个容器。
// 一个容器只能有一个Vue实例所控制,即容器和Vue是一对一的关系。
const vm = new Vue({
// 2 el用于指定当前Vue实例服务的容器对象,el值通常为CSS选择器字符串。
// el也可以写为,el: document.getElementById('app'),即el可以是JavaScript代码。
// el也可以使用CSS的类选择器作为值,即el: '.app'。
el: '#app',
// 3 data用于存储数据,数据供el所指定的容器使用。
// data的值可以是一个对象,也可以是一个函数(组件需要是函数)。
data: {
name: 'lisi'
}
});
</script>
</body>
</html>
2.模板语法
<body>
<div id="app">
<!--
vue的两种语法。
1 插值语法。插值语法用于解析标签体内容,可以写为{{xxx}},xxx为JavaScript表达式,
并且表达式可以直接读取data中的属性。
2 指令语法。指令语法用于解析标签(标签属性、标签体内容、绑定事件),如v-bind:href="xxx"可以
简写为:href="xxx",其中xxx为JavaScript表达式,可以读取到data中的数据。vue中的很多指
令语法都是以v-xxx开头。
-->
<h2>插值语法</h2>
<h3>{{name}}</h3>
<!-- this指带创建的Vue实例vm。 -->
<h3>{{this.name}}</h3>
<hr>
<h2>指令语法</h2>
<a v-bind:href="uri">点击01</a>
<!-- v-bind:xxx可以简写为:xxx -->
<a :href="uri">点击01</a>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
name: 'lisi',
uri: 'https://www.baidu.com'
}
})
</script>
</body>
3.单向数据绑定和双向数据绑定
<div id="app">
<!--
vue有两种数据绑定的方式。
1 单项数据绑定(v-bind)。数据只能从data流向页面。
2 双向数据绑定(v-model)。数据不仅可以从data流向页面,也可以从页面流向data。
1 双向数据绑定一般都应用在表单类元素上(有value属性的元素上),如input、select。
2 v-model:value可以简写为v-model,因为v-model指令默认读取value属性。
-->
单项数据绑定 <input type="text" v-bind:value="name">
双向数据绑定 <input type="text" v-model:value="name">
v-model简写 <input type="text" v-model="name">
<h2>{{name}}</h2>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
name: 'lisi',
}
})
</script>
</body>
4.el和data的第二种写法
<body>
<div id="app01">
<p>{{name}}</p>
</div>
<div id="app02">
<p>{{name}}</p>
</div>
<script>
// 1 el的两种写法。
// 1 new Vue()时配置el属性。
// 2 先创建Vue实例,随后通过vm01.$mount('#app01');指定el的值。
const vm01 = new Vue({
data: {
name: 'lisi'
}
});
vm01.$mount('#app01');
// 2 data的二种写法。
// 对象式。
// 函数式。
// 3 data中的this。当data使用函数式时,如果是普通函数this为Vue实例,如果是箭头函数this是window。
// 所以使用Vue实例管理的函数,不能使用箭头函数,如果写箭头函数,this就是window。
// 在使用组件时data必须是函数式写法,且不能是箭头函数,否则会报错。
const vm02 = new Vue({
el: '#app02',
// data: function () {
// return {
// name: 'lisi'
// }
// }
// data函数式的简写。
data() {
console.log(this);
return {
name: 'lisi'
}
}
})
</script>
5.Object.defineProperty()
let person = {
name: 'lisi'
};
// Object.keys(person);获取指定对象的属性名,返回一个包含该对象属性名的数组。
console.log(Object.keys(person)); // ['name']
// Object.defineProperty(对象实例, 属性, 配置对象)给对象添加属性,通过Object.defineProperty()添加的属性不可遍历。
Object.defineProperty(person, 'age', {
value: 10
});
console.log(Object.keys(person)); // ['name']
// 如果希望Object.defineProperty()添加的属性可遍历,需要在配置对象中将enumerable设置为true,enumerable默认值是false。
Object.defineProperty(person, 'address', {
value: 'bj',
enumerable: true
});
console.log(Object.keys(person)); // ['name', 'address']
// Object.defineProperty()第三个参数可以指定的其他配置项。
Object.defineProperty(person, 'phone', {
value: '123',
enumerable: true,
writable: true, // 控制属性是否直接可以通过person.phone修改,默认false。
configurable: true // 控制属性是否可以通过delete person.phone删除,默认false。
});
let email = 'lisi.com';
// Object.defineProperty()参数配置对象中的get和set属性。
Object.defineProperty(person, 'email', {
// 在读取person中的email属性时,会调用get。
get: function getEmail() {
console.log('get');
return email;
},
// 在修改person中的email属性时,会调用set。
// 属性为方式时的简写。
set(val) {
console.log('set', val);
email = val;
}
});
console.log(person);
console.log(person.email); // lisi.com
person.email = 'wangwu@.com';
console.log(person.email); // wangwu@.com
6.数据代理
<body>
<div id="app">
<p>{{name}}</p>
</div>
<script>
// 1 数据代理,通过一个对象代理另一个对象中的属性读写操作。
// 2 Vue的数据代理。通过vm对象代理data对象中数据的读写操作。
// 3 Vue中的数据代理,可以使得操作数据更加的方便。
// 4 创建Vue实例时,会将data属性保存到vm的_data中,即可以通过vm._data来访问;同时
// 会通过Object.defineProperty()将data中的属性都添加到vm中。
// 5 修改vm.name时会通过Object.defineProperty()的参数配置对象的set()来修改vm._data.name的值,
// 读取vm.name时会通过Object.defineProperty()的参数配置对象的get()来去读vm._data.name的值。
const vm = new Vue({
el: '#app',
data: {
name: 'lisi'
}
});
console.log(vm.name); // lisi
console.log(vm._data.name); // lisi
</script>
</body>
7.事件处理
<body>
<div id="app">
<!-- 1 vue添加事件使用v-on:xxx表示,如点击事件为v-on:click。-->
<button v-on:click="method01">method01</button>
<!-- 2 v-on:click可以简写为@click。 -->
<button @click="method01">method02</button>
<!-- 3 如果事件函数没有其他的参数,vue会默认将事件对象event作为第一个参数传递。
@click="method03"和@click="method03($event)效果是一致的。"
-->
<button @click="method03">method03</button>
<!-- 4 如果事件函数有参数,vue不会传递事件对象event。 -->
<button @click="method04(1)">method04</button>
<!-- 5 如果事件函数有参数时,需要传递事件对象,则可以使用$event来传递事件对象。 -->
<button @click="method05(1, $event)">method05</button>
<!-- 6 当事件函数为普通函数时,函数内部的this为Vue实例。 -->
<button @click="method06">method06</button>
<!-- 7 当事件函数为箭头时,函数内部的this为Window。 -->
<button @click="method07">method07</button>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
name: 'lisi'
},
// 8 data中的数据会被vue数据代理,methods中的方法不会被数据代理。
// 将methods中的方法写在data中也不会报错,但是会增加vue的负担,会对该方法进行数据代理,
// 在Vue实例中产生get和set。data中的数据会经常进行修改,而方法本身在创建之后就不用做修改了,
// 所以不需要进行数据代理。
methods: {
method01() {
alert('method01');
},
method03(event) {
alert('method02');
console.log(event.target); // <button>method03</button>
},
method04(a, event) {
alert('method04');
console.log(a, event); // 1 undefined
},
method05(a, event) {
alert('method05');
console.log(a, event.target.innerText); // 1 'method05'
},
method06() {
console.log(this); // Vue
},
method07: () => {
console.log(this); // 当methods中的属性为箭头函数时,this为Window。
}
}
})
</script>
</body>
8.事件修饰符
<body>
<div id="app">
<!-- 1 使用event.preventDefault();阻止a标签的默认跳转行为。 -->
<a href="https://www.baidu.com" @click="method01">method01</a>
<!-- 2 使用vue提供的事件修饰符来阻止a标签默认的跳转行为。 -->
<a href="https://www.baidu.com" @click.prevent="method02">method02</a>
<!--
3 vue提供的6中事件修饰符。
1 prevent,阻止默认事件。
2 stop,阻止事件冒泡。
3 once,事件只触发一次。
4 capture,使用事件的捕获模式。
5 self,只有event.target是当前元素时才触发,可以用来阻止事件冒泡。
6 passive,事件默认行为立即执行,无需等待事件的回调执行完毕。相比于pc端passive可能在移动端使用较多。
-->
<!-- 4 使用事件修饰符同时满足多个效果可以连写,如@click.prevent.stop,同时满足阻止默认事件和阻止事件冒泡。 -->
<a href="https://www.baidu.com" @click.prevent.stop="method02">method02</a>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
name: 'lisi'
},
methods: {
method01(event) {
event.preventDefault();
alert('method01');
},
method02() {
alert('method02');
}
}
})
</script>
</body>
9.键盘事件
<body>
<div id="app">
<!-- 1 vue中可以使用按键别名给按键绑定keydown和keyup事件。 -->
<!--
vue中常用的按键别名。
回车 enter
删除 delete,捕获删除和退格键。
空格 space
换行 tab,tab比较特殊,按下之后会进行光标焦点的切换,所以需要配合keydown使用。
上 up
下 down
左 left
右 right
-->
<!-- @keydown.enter按下回车键触发。 -->
<input type="text" @keydown.enter="method01">
<!-- 2 vue中未提供别名的键可以使用按键原始的key去绑定事件,但是需要注意CapsLock需要转换为caps-lock。 -->
<input type="text" @keydown.caps-lock="method01">
<!-- @keydown.k按下k键触发事件。 -->
<input type="text" @keydown.k="method01">
<!-- 3 tab键比较特殊按下之后会进行光标焦点的切换,所以需要配合keydown使用。 -->
<!-- 4 系统修饰键ctrl、alt、shift和meta(win)也比较特殊。
系统修饰键如果绑定的是keyup事件,按下系统修饰键的同时,在按下其他键,随后释放其他键,事件才能够被触发。
系统修饰键如果绑定的是keydown事件,则正常触发。
-->
<!-- 5 使用keycode来绑定事件,如回车enter键的keycode是13,但是这种方式不推荐使用,会在未来废弃,
原因是不同键盘的keycode有可能不一样。 -->
<!-- 通过keycode给回车键绑定事件。 -->
<input type="text" @keydown.13="method01">
<!-- 6 自定义键的别名,如将回车键定义为huiche,
Vue.config.keyCodes.huiche = 13;
-->
<input type="text" @keydown.huiche="method01">
<!-- 7 同时按下ctrl+y才触发事件。 -->
<input type="text" @keydown.ctrl.y="method01">
</div>
<script>
// 自定义键的别名,将keycode=13的回车键定义为huiche
Vue.config.keyCodes.huiche = 13;
const vm = new Vue({
el: '#app',
data: {
name: 'lisi'
},
methods: {
method01() {
console.log('method01');
}
}
})
</script>
</body>