0%

vue文档学习

Vue.js

vue官方文档 https://cn.vuejs.org/guide/introduction.html

基于vue方法文档的学习笔记,初学时主要记录基础知识,深度学习后希望能加上自己的理解!

更新时间

2024.05.18第一次更新

什么是Vue

一款用于构建用户界面的 (JavaScript )渐进式框架框架

两个功能:

  • 声明式渲染:vue的模板语法使得我们可以声明式地描述HTML和JS状态之间的关系
  • 响应性:自动跟踪JS状态并响应式地更新DOM

Vue可以使用的场景

  • 无需构建步骤,渐进式增强静态的 HTML
  • 在任何页面中作为 Web Components 嵌入
  • 单页应用 (SPA)
  • 全栈 / 服务端渲染 (SSR)
  • Jamstack / 静态站点生成 (SSG)
  • 开发桌面端、移动端、WebGL,甚至是命令行终端中的界面

单文件组件(SFC——*.vue)

vue的标志性功能

1
2
3
4
5
6
7
8
<script setup>
</script>

<template>
</template>

<style scoped scoped>
</style>

Vue组件的书写风格

选项式API (Option API)

  • 用对象来描述组件逻辑
  • 对象包括data、methos、mouted等属性,这些属性都是可选式的(我自己的理解,不一定对)
  • 选项定义的属性会暴露在函数内部的this上(即可以通过this访问到这个属性),this指向当前组件的实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<script>
export default {
// data() 返回的属性将会成为响应式的状态
// 并且暴露在 `this` 上
data() {
return {
count: 0
}
},

// methods 是一些用来更改状态与触发更新的函数
// 它们可以在模板中作为事件处理器绑定
methods: {
increment() {
this.count++
}
},

// 生命周期钩子会在组件生命周期的各个不同阶段被调用
// 例如这个函数就会在组件挂载完成后被调用
mounted() {
console.log(`The initial count is ${this.count}.`)
}
}
</script>

<template>
<button @click="increment">Count is: {{ count }}</button>
</template>

组合式API(Composition API)

  • 可以使用导入的API函数描述组件逻辑
  • 组合式API与<script setup>搭配使用,其中setup是一个标识,使得我们可以更简洁地使用组合式API(会在编译时做一些处理)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script setup>
import { ref, onMounted } from 'vue'

// 响应式状态
const count = ref(0)

// 用来修改状态、触发更新的函数
function increment() {
count.value++
}

// 生命周期钩子
onMounted(() => {
console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
<button @click="increment">Count is: {{ count }}</button>
</template>

两者之间的异同

  • 选项式API基于组件式API
  • 选项式有面对对象的思想,对初学者更友好,强制按照选项来组织代码
  • 组件式的核心思想是直接在函数作用域内定义响应式状态变量,并从多个函数中得到的状态组合起来处理复杂问题。更自由、灵活,但更难理解(确实,我不太能理解)

互动教程(组件式API+SFC)

响应式变量声明方式

说的明白点,就是动态的数据绑定,在reactive或ref中声明的变量可以响应式地用在html中

reactive()声明

  • reactive只适用于对象(包括数组和内置类型,如Map和Set)
  • reactive创建的对象时JS Proxy,行为与普通对象一致
1
2
3
4
5
6
7
8
import { reactive } from 'vue'

const counter = reactive({
count: 0
})

console.log(counter.count) // 0
counter.count++

ref()

  • ref接收任意类型数据
  • 返回值是一个对象,可以通过对象.value属性访问数据
1
2
3
4
5
6
import { ref } from 'vue'

const message = ref('Hello World!')

console.log(message.value) // "Hello World!"
message.value = 'Changed'

在模板template中使用响应式状态

响应式状态暂时我喜欢理解为响应式变量

  • 使用{{}}使用,并且ref中的对象的value可以不用message.value去访问,而是可以使用message直接访问(因为会被自动解包)
  • {{}}中不限制于变量名,也可以是表达式
1
2
3
4
5
6
//变量写法
<h1>{{ message }}</h1>
<p>Count is: {{ counter.count }}</p>

//表达式写法
<h1>{{ message.split('').reverse().join('') }}</h1>

Attribute绑定(v-bind)

  • Attribute n.属性,特质,在编程中通常用来描述数据对象的特征

  • v-bind用于绑定一个动态值,时v-开头的一种特殊Attribute

  • 绑定的值可以是calss,可以是id,也可以是一些参数

  • 可以简写为:

1
2
3
4
5
<div v-bind:id="dynamicId"></div>

//语法糖
<div :id="dynamicId"></div>

案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script setup>
import { ref } from 'vue'

const titleClass = ref('title')
</script>

<template>
<h1 :class="titleClass">Make me red</h1>
</template>

<style>
.title {
color: red;
}
</style>

事件监听(v-on)

  • 使用v-on监听DOM事件

  • 简写为@

    1
    2
    3
    4
    5
    6
    <template>
    <button v-on:click="increment">{{ count }}</button>
    //简写
    <button @click="increment">{{ count }}</button>

    </template>
  • 在script中声明回调函数increment

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <script setup>
    import { ref } from 'vue'

    const count = ref(0)

    function increment() {
    // 更新组件状态
    count.value++
    }
    </script>

表单的双向绑定

使用v-bind+v-on

当v-on监听到表单内容的变化,就使用回调函数获取到表单的新内容,更新数据后,重新响应在v-bind绑定的组件上

使用v-model(常用于表单、单选、多选、下拉框)

  • v-model是实质是上述方法的语法糖
  • V-model将绑定的值与input中的值自动同步,不需要在使用事件处理函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//用法
<input v-model="text">


//例子
<script setup>
import { ref } from 'vue'

const text = ref('')

</script>

<template>
<input v-model="text" placeholder="Type here">
<p>{{ text }}</p>
</template>

条件渲染(v-if)

  • v-if,只有在awesome为true时,h1标签才会被渲染
  • v-else-ifv-else用法与JS中if-else if-else的用法基本一致
1
2
3
4
5
6
//v-if
<h1 v-if="awesome">Vue is awesome!</h1>

//v-else
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>

列表渲染(v-for)

  • v-for用于循环渲染

  • 给每个 todo 对象设置了唯一的 id,并且将它作为特殊的 key attribute 绑定到每个 <li>key 使得 Vue 能够精确的移动每个 <li>,以匹配对应的对象在数组中的位置。

1
2
3
4
5
6
7
8
9
10
11
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
</li>
</ul>

//在数组中新增数据
todos.value.push(newTodo)

//在数组中删除数据,过滤数据
todos.value = todos.value.filter(/* ... */)

案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<script setup>
import { ref } from 'vue'

// 给每个 todo 对象一个唯一的 id
let id = 0

const newTodo = ref('')
const todos = ref([
{ id: id++, text: 'Learn HTML' },
{ id: id++, text: 'Learn JavaScript' },
{ id: id++, text: 'Learn Vue' }
])

function addTodo() {
// 新增todo
if(newTodo.value != ''){
console.log(newTodo.value);
todos.value.push({
id: id++,
text: newTodo.value
});
}
newTodo.value = ''//添加完数据后要重置为空
}

function removeTodo(todo) {
// 删除todo
todos.value = todos.value.filter((item)=>{
return item!=todo;
});

}
</script>

<template>
<form @submit.prevent="addTodo">
<input v-model="newTodo" required placeholder="new todo">
<button>Add Todo</button>
</form>
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
<button @click="removeTodo(todo)">X</button>
</li>
</ul>
</template>

计算属性(computed)

  • 创建一个计算属性 ref,这个 ref 会动态地根据其他响应式数据源来计算其 .value
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { ref, computed } from 'vue'

const hideCompleted = ref(false)
const todos = ref([
/* ... */
])

const filteredTodos = computed(() => {
// 根据 `todos.value` & `hideCompleted.value`
// 返回过滤后的 todo 项目
})

- <li v-for="todo in todos">
+ <li v-for="todo in filteredTodos">

案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<script setup>
import { ref, computed } from 'vue'

let id = 0

const newTodo = ref('')
const hideCompleted = ref(false)
const todos = ref([
{ id: id++, text: 'Learn HTML', done: true },
{ id: id++, text: 'Learn JavaScript', done: true },
{ id: id++, text: 'Learn Vue', done: false }
])

//当hideCompleted为true的时候,应该隐藏掉todos中done属性为ture的属性,所以过滤时返回done为false的属性的对象
const filteredTodos = computed(() => {
return hideCompleted.value
? todos.value.filter((t) => !t.done)
: todos.value
})

function addTodo() {
todos.value.push({ id: id++, text: newTodo.value, done: false })
newTodo.value = ''
}

function removeTodo(todo) {
todos.value = todos.value.filter((t) => t !== todo)
}
</script>

<template>
<form @submit.prevent="addTodo">
<input v-model="newTodo" required placeholder="new todo">
<button>Add Todo</button>
</form>
<ul>
<li v-for="todo in filteredTodos" :key="todo.id">
<input type="checkbox" v-model="todo.done">
<span :class="{ done: todo.done }">{{ todo.text }}</span>
<button @click="removeTodo(todo)">X</button>
</li>
</ul>
<button @click="hideCompleted = !hideCompleted">
{{ hideCompleted ? 'Show all' : 'Hide completed' }}
</button>
</template>

<style>
.done {
text-decoration: line-through;
}
</style>

生命周期和模板引用

  • 当我们需要手动操作DOM时,会需要使用模板引用,也就是指向模板中的一个DOM元素的ref
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<p ref="pElementRef">hello</p>
</template>


<script setup>
//使用同名ref访问该引用
const pElementRef = ref(null)


//要在挂载之后执行代码,我们可以使用 onMounted() 函数:
import { onMounted } from 'vue'
//ref引用的是一个DOM元素,在这个例子中,就是一个p标签
onMounted(() => {
// 此时组件已经挂载。
pElementRef.value.textContent = "你好"
})
</script>

此时,这个 ref 使用 null 值来初始化。这是因为当<script setup> 执行时,DOM 元素还不存在。模板引用 ref 只能在组件挂载后访问。

  • onMounted被称为生命周期钩子——它允许我们注册一个在组件的特定生命周期调用的回调函数。还有一些其他的钩子如 onUpdatedonUnmounted

侦听器(watch)

有时我们需要响应性地执行一些“副作用”——例如,当一个数字改变时将其输出到控制台。我们可以通过侦听器来实现它:

1
2
3
4
5
6
7
8
import { ref, watch } from 'vue'

const count = ref(0)

watch(count, (newCount) => {
// 没错,console.log() 是一个副作用
console.log(`new count is: ${newCount}`)
})
-------------本文结束感谢您的阅读-------------
原创技术分享,您的支持将鼓励我继续创作