参考:丁丁的哔哩哔哩
1.使用vue
1.1 使用CDN的方式使用Vue
mount和<div id="counter">
关联起来
1.2 vue中的createApp
import { createApp } from "vue";
import App from "./App.vue";
createApp(App).mount("#app");
vue中的createApp方法将App组件挂载到id=app的HTML页面中。
2.模板语法
2.1 针对HTML元素的内容
// 最基本的数据绑定形式:文本插值,“Mustache”语法
<p>{{ msg }}</p>
// v-once:当数据改变时,插值处的内容不会更新
<p v-once> {{ userName }} </p>
// v-html:让内容以HTML的形式展示
<p v-html="userName"></p>
2.2 针对HTML元素的属性(attribute)
// v-bind:动态的绑定属性的内容
<p v-bind:id="id"></p>
2.3 使用js表达式
// 在事件中使用
<p @click="id=1" />
// 插值中使用
<p>{{ num + 1 }}</p>
// v-bind中使用
<p v-bind:id="id+1"></p>
2.4 指令
指令是带有v-前缀的特殊attribute,指令还有参数,冒号:后面的即为参数;
指令的值是单个js表达式
2.5 语法糖
// 监听dom事件
v-on:click --> @click
// 动态绑定HTML元素属性
v-bind:id --> :id
2.6 动态参数
// 原始形式
<p v-bind:id="id+1"></p>
// 动态属性
const attrName="id";
<p v-bind:[attrName]="id+1"></p>
// 动态事件
const mouseOver="click";
<p v-on:[mouseOver]="change"></p>
3.data属性和方法
// data是一个函数,methods是一个对象
export default {
data(){ return {} }, // 让每一个组件对象都返回一个新的对象,不会造成数据污染
methods:{}
}
Vue 自动为 methods绑定this ,以便于它始终指向组件实例。这将确保方法在用作事件监听或回调时保持正确的 this指向。在定义 methods 时应避免便用箭头函数,
因为这会阻止 Vue 绑定恰当的this 指向。
4.计算属性 — 模板语法不适宜复杂表达式时
- 计算属性调用时,没加括号,把他当作属性调用;
- 有依赖值,依赖值不变,就不会重新计算,有缓存
<p> {{ wordFlag }} </p>
const wordFlag=computed(()=>{
return wordFlag ==1 ? true : false
})
5.侦听器
和计算属性类似,在响应数据变化时(依赖值变化),侦听器适用在需要执行异步或开销较大的操作时。
简单示例
const message=ref("");
watch(message, (newValue,oldValue) => { // 一个数据影响多个数据,而计算属性只能影响一个数据
console.log(newValue);
console.log(oldValue);
// 执行一些异步操作
})
立即执行 初始化时就调用函数
watch(
source,
(newValue, oldValue) => {
// 立即执行,且当 `source` 改变时再次执行
},
{ immediate: true }
)
深度监听 适用于响应式对象中的属性
vue3 隐式地创建一个深层侦听器——该回调函数在所有嵌套的变更时都会被触发。
<p>{{msg.name}}</p>
const msg = reactive({
name: "hello world",
home:{
mother:"mother",
father:"father"
}
})
watch(msg, (newValue)=>{
console.log(newValue.name)
console.log("msg change")
})
当msg.home变化时,不执行回调
// 不执行回调
watch(()=> msg.home, (newValue, oldValue)=>{
console.log("深度监听生效",newValue.mother)
})
加上 deep 选项,强制转成深层侦听器,可以执行回调
watch(()=> msg.home, (newValue, oldValue)=>{
console.log("深度监听生效",newValue.mother)
}, {deep:true})
vue2深度监听
data(){
return {
user:{
name:"张三",
age:11
}
}
}
// 监听响应式对象所有属性
user:{
handler : function(newValue){
console.log(newValue);
}
//表示是否深度监听,侦听器会一层层的向下遍历,给对象每个属性都加上侦听器;性能开销大
deep:true,
}
// 单独监听某一属性
"user.name":{ //使用字符串的形式
handler:function(newValue){
console.log(newValue);
}
deep:true,//表示是否深度监听,侦听器会一层层的向下遍历,给对象每个属性都加上侦听器
}
6.class与style绑定
在将v-bind 用于 class 和 style时,表达式结果的类型除了`字符串`之外,还可以是`对象或数组`。
class绑定
- :class里面可以是对象
const isActive = ref(true)
<div :class="{ active: isActive }"></div>
- class 和 :class 可以共存
<div
class="static"
:class="{ active: isActive, 'text-danger': hasError }"
></div>
- 绑定的对象并不一定需要写成内联字面量的形式,也可以直接绑定一个对象:
const classObject = reactive({
active: true,
'text-danger': false
})
<div :class="classObject"></div>
- 绑定一个计算属性
const isActive = ref(true)
const error = ref(null)
const classObject = computed(() => ({
active: isActive.value && !error.value
}))
// 如果箭头函数的返回值是一个对象,可以直接省略 return 和花括号 {},将对象包裹在小括号 () 中
<div :class="classObject"></div>
- 数组语法 (不常用)
const activeClass = ref('active')
const errorClass = ref('text-danger')
<div :class="[activeClass, errorClass]"></div>
// 三元表达式
<div :class="[isActive ? activeClass : '', errorClass]"></div>
// 三元表达式 另一种形式
<div :class="[isActive ? 'active': '', 'text-danger']"></div>
// 数组中嵌套对象
<div :class="[{ [activeClass]: isActive }, errorClass]"></div>
.active {
font-size:33px;
}
.text-danger {
color:red;
}
style绑定
- style的属性值是变量
const activeColor = ref('red')
const fontSize = ref(30)
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
// 支持短横杠,用引号包含起来
<div :style="{ 'font-size': fontSize + 'px' }"></div>
- 绑定样式对象
const styleObject = reactive({
color: 'red',
fontSize: '30px'
})
<div :style="styleObject"></div>
绑定数组
// 绑定多个样式对象
<div :style="[baseStyles, overridingStyles]"></div>
7.条件渲染
- v-if v-else
const awesome = ref(true);
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>
<template>
上的 v-if
<template>不会被渲染
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
- v-show
v-show 不支持在 元素上使用,也不能和 v-else 搭配使用。
<h1 v-show="ok">Hello!</h1>
- v-if 和 v-show 区别
v-show:会在 DOM 渲染中保留该元素;v-show 仅切换了该元素上名为 display 的 CSS 属性
;如果需要频繁切换,则使用 v-show 较好;
v-if:只有后面为false,对应的元素以及子元素都不会被渲染,控制dom元素的创建和销毁,运行时条件很少改变,一次性的
8.列表渲染
- v-for 渲染数组
- v-for 渲染对象
const myObject = reactive({
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
})
获取对象的键值
<ul>
<li v-for="value in myObject">
{{ value }}
</li>
</ul>
获取对象的键名、键值
<li v-for="(value, key) in myObject">
{{ key }}: {{ value }}
</li>
获取对象的索引、键名、键值
<li v-for="(value, key, index) in myObject">
{{ index }}. {{ key }}: {{ value }}
</li>
-
通过 key 管理状态
当数据项的顺序改变时,Vue 不会随之移动 DOM 元素的顺序,而是就地更新
每个元素,确保它们在原本指定的索引位置上渲染。
为了给 Vue 一个提示,以 便它可以跟踪每个节点的标识,从而重用和重新排序现有的元素,需要为每个元素对应的块提供一个唯一的key 属性
-
数组变化侦测
Vue 能够侦听响应式数组的变更方法,并在它们被调用时触发相关的更新。这些变更方法包括:push():数组末尾后添加元素
pop():删除数组末尾元素
shift():删除数组首位元素
unshift():数组首位添加元素
splice():
(1): splice(1,2) 在数组索引为1的下标开始删除2个元素
(2): splice(1,0,5,6) 在数组索引为1的下标开始添加2个元素5和6
(3): splice(1,2,5,6) 在数组索引为1的下标开始的2个元素替换为5和6
sort():默认从小到大排序
reverse():翻转数组
9.事件处理
- 内联事件处理器: 简单场景
<button @click="count++">Add 1</button>
<p>Count is: {{ count }}</p>
const count = ref(0)
- 方法事件处理器
<!-- `greet` 是上面定义过的方法名 -->
<button @click="greet">Greet</button>
const name = ref('Vue.js')
function greet(event) {
// `event` 是 DOM 原生事件
if (event) {
alert(event.target.tagName)
}
}
- 方法与内联事件判断
foo、foo.bar 和 foo[‘bar’] 会被视为方法事件处理器,而 foo() 和 count++ 会被视为内联事件处理器。
- 在内联处理器中调用方法
<button @click="say('hello')">Say hello</button>
function say(message) {
alert(message)
}
- 在内联事件处理器中访问事件参数
<!-- 使用特殊的 $event 变量 -->
<button @click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
<!-- 使用内联箭头函数 -->
<button @click="(event) => warn('Form cannot be submitted yet.', event)">
Submit
</button>
function warn(message, event) {
// 这里可以访问原生事件
if (event) {
event.preventDefault()
}
alert(message)
}
一个事件,绑定多个处理函数
<button @click="func1(), func2()">
Submit
</button>
- 事件修饰符
<!-- 单击事件将停止传递到div元素 -->
<div @click="divClick">
<a @click.stop="doThis"></a>
</div>
<!-- 提交事件将不再重新加载页面,阻止提交事件这个默认行为 -->
<form @submit.prevent="onSubmit"></form>
<!-- 修饰语可以使用链式书写 -->
<a @click.stop.prevent="doThat"></a>
<!-- 也可以只有修饰符 -->
<form @submit.prevent></form>
<!-- 只触发一次回调 -->
<button @click.once="doThis"></button>
- 按键修饰符
<!-- {keyCode(键盘编码)| keyAlias (键盘的简写)}监听键盘的某个键帽 -->
<input type="text" @keyup.enter="keyUp" />
10.表单输入绑定
- v-model
<input v-model="text">
- v-model的实现原理:
<input
:value="text"
@input="event => text = event.target.value">
注意v-model在不同表单控件的用法
- 文本
const message=ref("hello")
<p>Message is: {{ message }}</p>
<input v-model="message" placeholder="edit me" />
- 多行文本
const message=ref("")
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message"></textarea>
- 复选框
const checked=ref(false)
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
- 多选框
选中某个复选框后,将其value属性对应的值添加到数组checkedNames中
const checkedNames = ref([])
<div>Checked names: {{ checkedNames }}</div>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames" />
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames" />
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames" />
<label for="mike">Mike</label>
- 下拉选择框
const selected=ref("")
<div>Selected: {{ selected }}</div>
<select v-model="selected">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
- 多选
const multiSelected=ref([])
<div>Selected: {{ multiSelected }}</div>
<select v-model="multiSelected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
- 值绑定
将vlaue值由静态变为使v-bind动态绑定 - 修饰符
1.lazy
<!-- 在 "change" 事件后同步更新而不是 "input" -->
<input v-model.lazy="msg" />
2.number
<!-- 用户输入自动转换为数字 -->
<input v-model.number="age" />
3.trim
<!-- 默认自动去除用户输入内容中两端的空格 -->
<input v-model.trim="msg" />