一、模板语法
1.插值
(1)文本 —> {{}} 文本绑定
(2)attribute(属性) —> v-bind(绑定,vue的指令) 缩写 : —> v-bind:id="“或v-bind:class=”"
(3)以上两种方式都可使用js表达式
视图 、 逻辑
mvvm思想:通过数据驱动视图,view -> model,
m -> model模型,v -> view视图,vm ->vue
vue的指令,或者后期我们自定义一个指令
vue很多语法和写法只为了让用户使用起来方便,很多api,与react不同
<body>
<div id="app" :id="testId + 123">{{msg + 123}}</div>
<script>
window.app = new Vue({
el: "#app",
data: {
msg: "hello world",
testId: "123",
},
});
</script>
</body>
二、事件处理
1.事件绑定 v-on 缩写 @ (v-on:click=“” —> @click=“”)
——直接调用函数
——内联处理器中的方法 $event
2.修饰符 (@click.once=“count++”)查API
.stop - 调用 event.stopPropagation()。阻止(单击/双击)事件继续传播
.prevent - 调用 event.preventDefault()。阻止表单提交(事件不再重载页面)
.capture - 添加事件侦听器时使用 capture 模式。
.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
.native - 监听组件根元素的原生事件。
.once - 只触发一次回调。只生效一次
.left - (2.2.0) 只当点击鼠标左键时触发。
.right - (2.2.0) 只当点击鼠标右键时触发。
.middle - (2.2.0) 只当点击鼠标中键时触发。
.passive - (2.3.0) 以 { passive: true } 模式添加侦听器
所有的函数都需要放到 methods
<body>
<div id="app">
{{ msg }} {{count}}
<!-- 写对应的函数 -->
<button v-on:click="handleClick">click</button>
<!-- 写对应的表达式 -->
<button v-on:click="count++">click</button>
<!-- 写对应的函数,带参数 -->
<button v-on:click="handleClick(0,$event)">click</button>
<!-- 只生效一次 -->
<button @click.once="count++">click</button>
</div>
<script>
window.app = new Vue({
el: "#app",
data: {
msg: "hello world",
count: 0,
},
methods: { //所有的函数都需要放到 methods
handleClick(type, e) {
console.log(e);//获取对应的event
// console.log(event)
console.log(type);//接收对应的0
console.log("click");
},
},
});
</script>
</body>
三、计算属性computed —> (是需要依赖别的属性的话,依赖别的属性的属性 ,涉及到如何写好代码)
1.可读性 (表达出代码的意图,把一些复杂的表达式放到计算属性内 不要堆积到 template 里面)
2.缓存 (只有计算属性有缓存)(将数据先缓存起来,调用时不再重复计算)
3.多对一 (多 —> 计算属性依赖的响应式数据【data内的数据】) (1 —> 响应式计算属性本身【返回一个数据】)
【只要是依赖到data内的属性就可以用计算属性computed去完成】
split()切割字符 后 转换成数组存放
reverse() 将数组内数据倒序
join() 转换成字符串
<body>
//实现倒序显示
<!-- <div id="app">{{ msg.split("").reverse().join("") }}</div> 实现倒序显示 -->
<!-- <div id="app">{{ reverseMsg }} --- {{reverseMessage()}}</div> -->
<div id="app">{{ reverseMsg }} }}</div>
<script>
window.app = new Vue({
el: "#app",
data: { // 响应式数据
msg: "hello world",
count:0
},
methods: { // 方法
reverseMessage() {//调用时每次都去计算/无缓存概念
console.log("reverseMessage");
return this.msg.split("").reverse().join("");
},
},
computed: { // 计算属性:有缓存
reverseMsg() {
console.log("reverseMsg");
return this.msg.split("").reverse().join("") + this.count;//依赖两个数据msg和count(多),结果返回一个值(一)
// 2秒 -> 浪费时间
},
},
});
</script>
</body>
四、watch —> 观察,观察一个响应式数据(data内数据)的变更,
1.【使用场景】当需要在数据变化时执行异步或开销较大的操作时使用
//执行异步fetch
//xxxxxxx对应API,绑定上newValue新值,通过异步回调拿到对应的值,
// 一般放“翻页”上处理,通过页码数获取当前页面的数据
fetch(“xxxxxxx”+newValue).then(() => {
} )
2.立马调用
——immediate: true
3.为了发现对象内部值的变化
——deep: true
4.watch和 computed 有什么区别
——watch —> 1 对 多的关系(1 —> 代表的是一个观察的响应式对象)(多 —> 可以改变多个响应式对象)【观察一个值返回多个数据】
——computed —> 多对一的关系 (多 —> 计算属性依赖的响应式数据【data内的数据】) (1 —> 响应式计算属性本身【返回一个数据】)
需求》问题(如何一开始就调用观察)》怎么去解决呢?》api》object》 immediate true
查找观看API
vm.$watch( expOrFn, callback, [options] )
参数:
{string | Function} expOrFn 观察字符串、函数
{Function | Object} callback 观察函数、对象
{Object} [options] 观察对象
{boolean} deep
{boolean} immediate
函数形式—> 需要操作/引用后才能调用
对象形式—> 一进来就直接调用就使用对象形式入参,并且将immediate设置为true
返回值:{Function} unwatch
用法:
观察 Vue 实例上的一个表达式或者一个函数计算结果的变化。回调函数得到的参数为新值和旧值。表达式只接受简单的键路径。对于更复杂的表达式,用一个函数取代。
注意:
在变更 (不是替换) 对象或数组时,旧值将与新值相同,因为它们的引用指向同一个对象/数组。Vue 不会保留变更之前值的副本。
<body>
<div id="app">
{{ msg }} {{count}}
<button @click="handleClick">click</button>
{{hello1}} {{hello2}} 1 对 多的关系
</div>
<script>
window.app = new Vue({
el: "#app",
data: {//响应式数据
count: 0,
msg: "hello world",
hello1: "hello1",
hello2: "hello2",
user: {
name: "xiaohong",
age: 123,
},
list: [[1], [2]],
},
methods: {//方法
handleClick() {
console.log("click");
this.count++;
},
},
watch: {//观察响应式数据变更
// 观察内接收数组list
list: {
handler(newVal) {
console.log(newVal);
},
},
// 观察内接收对象内的key值 user.age
"user.age": {
handler(newValue, oldValue) {
console.log("user.age");
console.log(newValue);
},
},
// 观察内接收对象user
user: {
handler(newValue, oldValue) {
console.log(newValue);//改对象的话,无触发,为了性能考虑,若想改变,需要加deep: true,vue就开启了对当前对象的深度观察,不管对象user内部有多少层,就能触发内部监听
},
deep: true,
},
// 观察内接收字符串count的对象形式
count: {// 对象形式
handler(newValue, oldValue) {
// 需求——》问题-》怎么去解决呢?》api》object-》 immediate true
console.log("newValue", newValue);//新值
console.log("oldValue", oldValue);//旧值
// 做一点异步的事
// fetch
// 翻页 page
// fetch("xxxxxxx"+newValue).then(() => {
// })
// 1 对 多 的关系 (一个值 ===》 影响了多个值)
this.hello1 = this.count + "hello1";
this.hello2 = this.count + "hello2";
},
immediate: true,
},
// 观察内接收字符串count的函数形式
count(newValue, oldValue) {// 函数形式
console.log("newValue", newValue);
console.log("oldValue", oldValue);
// 做一点异步的事
// fetch
// 翻页 page
// fetch("xxxxxxx"+newValue).then(() => {
// }
// )
// 1 对 多 的关系
// 一个值
// 影响了多个值
this.hello1 = this.count + "hello1";
this.hello2 = this.count + "hello2";
},
},
});
</script>
</body>
五、条件渲染
1.v-if
——v-else-if
——v-else
2.v-show
——display: none
3.v-if vs v-show
v-if (元素是没有的,不存在在dom内了)完全不渲染
v-show (元素是有的,只是通过样式display: none隐藏了) 渲染了但通过样式隐藏
<body>
<div id="app">
<div v-if="age === 18">花一样的年龄</div>
<div v-else-if="age > 18">成年人</div>
<div v-else>未成年</div>
<div v-show="age === 18">show</div>
</div>
<script>
// js -> if
// 在学习新知识的时候要联想起老知识
// else elseif
window.app = new Vue({
el: "#app",
data: {
age: 17,
},
});
</script>
</body>
六、列表渲染
1.v-for
(1)遍历数组
(2)遍历对象
(3)key (id -> 后端给我们的 :key = ‘item.id’ 需要有key,方便diff算法优化,方便查找进行比较值)
——a. 复用
——b. 优化查找算法
(4)v-for && v-if
<body>
<div id="app">
<div v-for="(item,index) in list">{{index}} - {{item}}</div> 遍历数组
<div v-for="val in users">{{val.name}}</div> 遍历对象
<div v-for="(val,key,index) in users" :key = 'item.id'> {{val.name}} - {{key}} - {{index}} </div>
</div>
<script>
// id -> 后端给我们的 :key = 'item.id' 需要有key,方便diff算法优化
// js -> for
window.app = new Vue({
el: "#app",
data: {
// 数组
list: ["xiaohong", "xiaohei", "haige", "zhonglaoshi"],
// 对象
users: {
xiaohong: {
name: "xiaohong",
},
haige: {
name: "haige",
},
},
},
});
</script>
</body>
七、class && style
1.数组形式 class & style(驼峰命名法)
2.对象形式 class & style(驼峰命名法)
3.推荐使用class
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="./node_modules/vue/dist/vue.js"></script>
<style>
.color {
color: pink;
}
.font {
font-size: 50px;
}
</style>
</head>
<body>
<div id="app">
<div :class="classes" :style="styleInfo">test class</div>
</div>
<script>
window.app = new Vue({
el: "#app",
data: {
msg: "hello world",
classes: [ 'color' , 'font' ],
// 表达式
classes: ["color", true === false ? "font" : ""], // true === true ? "font" : ""
// class数组形式
classes:[{
font: true
}],
// class对象形式
classes: {
font: true,
color: true
},
// style对象形式
styleInfo: {
color: "red",
fontSize: "50px",
},
// style数组形式
styleInfo: [
{
color: "red",
},
{
fontSize: "50px",
},
],
},
});
</script>
</body>
</html>
八、表单输入绑定
1.v-model(语法糖)
(可以类似理解为双向绑定,但不是双向绑定,只是一个语法,input内的值发生改变后,绑定上响应式数据内的值上)
2.原理
——双向绑定(语法糖),真正的双向绑定是数据与数据之间的绑定
3.修饰符
——number
查看API文档:搜索关键词v-model
v-model
预期:随表单控件类型不同而不同。
限制:input、select、textarea、components
修饰符:
.lazy - 取代 input 监听 change 事件
.number - 输入字符串转为有效的数字
.trim - 输入首尾空格过滤
用法:在表单控件或者组件上创建双向绑定。细节请看下面的教程链接。
参考:表单控件绑定;组件 - 在输入组件上使用自定义事件;
v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:
——text 和 textarea 元素使用 value property 和 input 事件;
——checkbox 和 radio 使用 checked property 和 change 事件;
——select 字段将 value 作为 prop 并将 change 作为事件。
<body>
<div id="app">
{{msg}} {{isCheckbox}}
<input type="text" @input="changeInput" /> 或者 <input type="text" v-model="msg" />
<!-- text 和 textarea 元素使用 value property 和 input 事件; -->
<input type="text" v-model.number="msg" /> .number修饰符
<!-- checkbox 和 radio 使用 checked property 和 change 事件; -->
<input type="checkbox" v-model="isCheckbox" />
<input type="checkbox" @change="changeCheckbox" />
</div>
<script>
window.app = new Vue({
el: "#app",
data: {
isCheckbox: false,
msg: "",
},
watch: {
msg(newValue, oldValue) {
console.log(typeof newValue);
},
},
methods: {
changeCheckbox(e) {
this.isCheckbox = e.target.checked;
},
changeInput(e) {
// changeinput -> 下面这个代码逻辑
this.msg = e.target.value;
},
},
});
</script>
</body>
小作业
- 点击按钮时,count 和 double 会增加
- double 的值为 count 的双倍
- double 需要用 computed 来实现
<body>
<div id="app">
{{ count }} {{ double }}
<button @click="fn">click</button>
</div>
<script>
window.app = new Vue({
el: "#app",
data: {
count: 0,
},
computed: {
double() {
console.log("double");
return this.count * 2
}
},
methods: {
fn() {
this.count++
}
}
});
</script>
</body>