数据驱动的框架,不需要大量DOM操作
基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>learn vue.js 01</title>
</head>
<body>
<div id="root">
<h1>hello,{{name}}</h1>
<a v-bind:href="url">这是一个链接</a>
<form action="#">
<input type="text" v-model:value="name" /><br />
<button @click="showInfo($event,66)">点击</button>
</form>
<hr />
<div>
<input type="text" v-model:value="firstName" /><br />
<input type="text" v-model:value="lastName" /><br />
<div><span>{{fullName}}</span></div>
</div>
<div>
<span v-for="(value,key) of arr" :key="key">{{value}}</span>
</div>
</div>
<script src="./js/vue.js"></script>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: '#root',
// data: {
// name: 'vue',
// url: 'www.hustwenhua.net'
// },
data() {
return {
name: 'vue',
url: 'www.hustwenhua.net',
firstName: '张',
lastName: '三',
isHot: true,
arr: ['a', 'b', 'c']
}
},
methods: {
showInfo(event, number) {
console.log(event, number);
}
},
computed: {
fullName: {
get() {
return this.firstName + this.lastName;
},
set(value) {
console.log(value);
}
},
//简写
/*fullName() {
return this.firstName + this.lastName;
}*/
},
watch: {
//正常写法
/* isHot:{
// immediate:true, //初始化时让handler调用一下
// deep:true,//深度监视
handler(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue)
}
}, */
//简写
isHot(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue,this)
}
}
});
// vm.$mount('#root');
</script>
</body>
</html>
模板语法
插值
{{xxx}}
,xxx
会被作为 JavaScript 表达式解析。
指令
Vue 提供的特殊 attribute,它们会在渲染的 DOM 上应用特殊的响应式行为。
- v-on:事件绑定。可简写为
@click="funcxx"
- v-bind:属性绑定,单向数据绑定。可简写为
:href="xxx"
- v-model:表单数据绑定,双向数据绑定。可简写为
v-model="xxx"
- v-for:循环
- v-show:通过控制 display 样式来控制显示/隐藏
- v-if:如果为 true, 当前标签才会输出到页面
- v-else-if
- v-else 如果为 false, 当前标签才会输出到页面
- v-pre:跳过其所在节点的编译过程
- v-once:只会执行一次模板渲染,之后模板改变时不再重新渲染
- v-html:直接作为 HTML 渲染
- v-text:直接文本输出
v-cloak : 防止闪现, 与 css 配合: [v-cloak] { display: none}
事件处理
事件的回调需要配置在 methods 对象中,最终会在 vm 上
- methods 中配置的函数,不要用箭头函数!否则 this 就不是 vm 了
- methods 中配置的函数,都是被Vue所管理的函数,this 的指向是 vm 或 组件实例对象
- 若 Vue 实例事件函数传参数,又需要使用
event
对象,写成handleFun($event,...arg)
的形式。 - @click=”demo” 和 @click=”demo($event)” 效果一致,但后者可以传参
事件修饰符
- .stop:阻止事件传播,相当于
event.stopPropagation()
- .prevent:阻止默认事件,相当于
event.preventDefault()
- .capture:使用事件捕获模式
- .self:只有 event.target 是当前操作的元素时才会触发事件
- .once:事件只触发一次
- .passive:事件的默认行为立即执行,无需等待事件回调执行完毕
按键修饰符
- .enter
- .tab(特殊 使用keydown事件捕获)
- .delete (捕获“删除”和“退格”键)
- .esc
- .space
- .up
- .down
- .left
- .right
系统修饰键(用法特殊) .ctrl .alt .shift .meta
- 配合 .keyup 使用:按下修饰键时同时按下其它键,事件才会被触发
- 配合 .keydown 使用:正常触发事件
属性的绑定
vue绑定值与字符串拼接两种写法
//第一种
<div :title="`字符串${xx}`" ><div>
//第二种
<div :title="'字符串' + xx" ><div>
计算属性和侦听器
计算属性将基于它们的响应依赖关系缓存。计算属性只会在相关响应式依赖发生改变时重新求值。这就意味着只要author.books
还没有发生改变,多次访问publishedBookMessage
时计算属性会立即返回之前的计算结果,而不必再次执行函数。
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。computed 中不能进行异步操作,而 watch 可以。
watch 默认不监测对象内部值的改变(一层)。深度侦听:配置 deep:true
可以监测对象内部值改变(多层)。Vue 自身可以监测对象内部值的改变,但 Vue 提供的 watch 默认不可以!使用 watch 时根据数据的具体结构,决定是否采用深度监视。
数组更新检测
变更方法
Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
你可以打开控制台,然后对前面例子的 items 数组尝试调用变更方法。
比如 example1.items.push({ message: 'Baz' })
替换数组
变更方法,顾名思义,会变更调用了这些方法的原始数组。相比之下,也有非变更方法,例如 filter()、concat() 和 slice()。它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组替换旧数组:example1.items = example1.items.filter(item => item.message.match(/Foo/))
你可能认为这将导致 Vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的启发式方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。
数据代理
Vue 中的数据代理:通过 vm 对象来代理 data 对象中属性的操作(读/写)。Vue 中数据代理更加方便的操作 data 中的数据。
基本原理:通过 Object.defineProperty()
把 data 对象中所有属性添加到 vm 上。为每一个添加到 vm 上的属性,都指定一个 getter/setter。在 getter/setter 内部去操作(读/写)data 中对应的属性。
生命周期
- 生命周期的函数中的 this 都是 vm 或者组件实例
组件
自定义事件
配合 v-model 使用
<script setup>
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script>
<template>
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
</template>