Vue Note

Vue Note

Falling_Sakura HaHa

Vue

Vue.js 中文文档

API

什么是 API ?

API(Application Programming Interface,应用程序接口)是一组定义和协议,用于构建和集成软件应用程序。API 允许不同软件系统之间进行通信和数据交换。通过使用 API,开发者可以利用现有的功能,而无需从头开始编写代码。

选项式 API

选项API是Vue 2中使用的传统方法,通过在组件对象中定义各种选项来组织组件逻辑,如datamethodscomputedwatch等。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
export default {
data() {
return {
count: 0
};
},
methods: {
increment() {
this.count++;
}
},
computed: {
doubleCount() {
return this.count * 2;
}
},
watch: {
count(newValue, oldValue) {
console.log(`Count changed from ${oldValue} to ${newValue}`);
}
}
};

组合式 API

组合式API是Vue 3中引入的新特性,提供了一种更灵活的方式来组织和复用组件逻辑。通过使用setup函数和组合函数(Composition Functions),可以将逻辑分块,便于复用和测试。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { ref, computed, watch } from 'vue';

export default {
setup() {
const count = ref(0);

const increment = () => {
count.value++;
};

const doubleCount = computed(() => count.value * 2);

watch(count, (newValue, oldValue) => {
console.log(`Count changed from ${oldValue} to ${newValue}`);
});

return {
count,
increment,
doubleCount
};
}
};

响应式

响应式(reactivity)是指系统能够自动监测数据的变化并做出相应的反应。例如,当数据变化时,Vue 会自动重新渲染相关的 DOM 元素,以确保用户界面始终与数据保持同步。这种能力是 Vue 的核心特性之一,使得开发过程更加简洁和高效。

结构

1
2
3
4
5
6
7
8
9
10
11
<scirpt setup>
// JS
</script>

<template>
// HTML
</template>

<style scoped>
// CSS
</style>

每一个 .vue 文件是一个组件,不同的组件拼接成一个网页应用。

里面有三部分,分别是我们熟悉的 HTML CSS JS

在之前的写法中,我们需要告诉 Vue 这是个组件以及定义组件逻辑的地方,如:

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

setup 用于初始化组件的逻辑、状态、数据,返回值将给模板使用。

但在 Vue3 中,我们有更方便的定义数据和方法的方式:

1
2
3
4
5
<script setup>
//
//
//
</script>

这样的写法就方便许多。

当我们想在某一个 .vue 文件中导入其它组件时,这样写:

1
import {name} form '{path}'

{name} 是组件的名字,可以任意取,'{path}' 是一个字符串,代表组件所在路径。

使用时,在 <template> 中使用 <{name}></{name}> 即可,像是你自定义了一个新的 HTML 标签。

当我们只想给 CSS 添加到当前组件时,可以给 <style> 添加一个属性 scoped

Variable

script 中,创建变量需要先引入 ref/reactive API。

1
import { ref, reactive } from 'vue'

然后创建变量:

1
const str = ref()

ref() 内是变量值,可以是字符串、数组、数字、对象等等。

返回的是一个带有 value 属性的对象。

script 内访问变量值时,需要使用 var.value,而在 template 中访问变量值时,只需要 var,比如一个标题可以是 <h2>{{ str }}</h2>。这样标题的内容就可以随着变量的变化而变化。

ref 创建的是单一的,而 reactive 创建的是更为复杂的深度响应式对象,里面有很多键值对。

而由于返回的是一个对象,所以哪怕这个变量在定义时为 const,你依然可以修改它的 value

如果想要创建一个常量的话,可以使用 ref(Object.freeze({value}))

也可以使用 computed API,它可以用于创建一个计算属性,计算属性的值会自动缓存,只有它里面的变量发生变化时才会重新计算,那么我们只需要让里面没有变量就可以实现返回一个常量。

1
const computeValue = computed(() => 'This is a computed constant');

Watch

1
import { watch } from 'vue';

watch() 是一个方法,第一个参数是监听的变量,第二个参数是执行的函数。

当这个变量的值发生变化时,函数就会执行一次。

1
watch(object, add(oldValue, newValue), { })

同时这个执行的函数可以传入两个参数,一个是监听得到的新值,另一个是旧值。

监听的可以是普通响应式变量(ref),也可以是计算属性(computed),也可以是一个 getter 函数用于监听复杂的表达式,也可以监听多个值,打包成一个数组即可。

当监听的元素为一个对象时,修改对象中的某一个值,并不会触发监听函数。

如果想监听对象中的值,可以再加入一个参数选项对象

1
watch(object, add(oldValue, newValue), { deep: true })

一个对象 { deep: true },此为深度监听。

选项对象还有的属性是:

  • immediate:在监听器初始化时就会执行一次回调函数,默认为 false
  • flush:执行回调函数的时机,可以是如下值:
    • "pre":在视图更新之前调用(默认值)。
    • "post":在视图更新之后调用。
    • "sync":同步执行回调。

defineProps

defineProps 是一个函数,用于声明当前组件接收的 props。它返回一个包含所有 props 的对象,可以在组件的逻辑中使用。

1
2
3
import { defineProps } from 'vue';

const props = defineProps(['name']);

函数的参数是一个字符串数组,里面的字符串就是可以接收的 props,可以让父组件(调用组件的组件)通过属性将属性值传递给子组件(被调用的组件)的 props 中。

也可以接收一个对象,对象里可以详细配置 prop 的默认值,类型和验证等其它选项。

子组件调用这个值,通过 {{ props.name }} 即可。

举例:

  • 子组件:
1
2
3
4
5
6
7
<script setup>
...
const props = defineProps(['text']);
</script>
<template>
<h2>{{ props.text }}</h2>
</template>
  • 父组件:
1
<Mybutton text="Title"></Mybutton>

这样,父组件的数据就传递到子组件中了。

defineEmits

在 Vue 3 中,defineEmits 是一个组合式 API,用于在组件中定义可以触发的事件。其参数是一个数组,包含了该组件可以触发的事件名称,返回值是一个函数,用于触发事件。

1
const emit = defineEmits(['ok']);

emit 函数的第一个参数表示触发的事件(这个事件必须是可触发的),后续参数表示传递给事件处理函数的数据。

此时,就可以通过子组件中的一个定义的事件,向父组件中传递相应的数据。

  • 子组件:
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
<script setup>
import { defineProps, defineEmits } from 'vue';

const props = defineProps(['text']);

const emit = defineEmits(['ok']);

function send() {
emit('ok', 'hello');
}
</script>

<template>
<div @click="send" class="button">{{ props.text }}</div>
</template>

<style scoped>
.button {
width: 100px;
height: 50px;
border-radius: 10px;
line-height: 50px;
background-color: aliceblue;
text-align: center;
margin: 100px;
}
</style>
  • 父组件:
1
2
3
4
5
6
7
8
9
10
11
12
<script setup>
import Mybutton from '...';
...

function fn(str) {
console.log(str); //将输出 str
}
</script>
<template>
<Mybutton @ok="fn"></Mybutton>
</template>
...

这样,当点击父组件中引用的子组件(按钮)时,就会触发子组件中的 send() 函数,从而触发 ok 事件,并像父组件中的 function 函数传递了 hello 的参数。

也可以直接使用 this.$emit('name', args) 调用,会触发 name 事件,然后在父组件中监听 name 事件即可,这样就不用预定义 emit 了。

这样,父组件的数据就传递到子组件中了。

slot

插槽,用于子组件中占位,父组件可向其中传入内容。

props 不同,插槽传入的是具体的内容,而不是数据。

子组件:

1
2
3
<div>
<slot name="haha" :msg="message"></slot>
</div>

父组件:

1
2
3
<template #haha="{ msg }">
<h1>HaHa</h1>
</template>

这样就可以把父组件中的标题放入子组件中的 slot,同时子组件将属性 msg 传给父组件,父组件可以通过 v-slot:name 的方式找到命名插槽,也可以简写为 #name,后面加上等号可以接收一个子组件的 slotProps 对象,然后采用 ES6 里对象结构的语法就可以直接得到 message 的值。(注意变量名/键名要一样才能解构)。

其中父组件的 template 可以用子组件标签名代替。

Vue 指令

在 Vue.js 中,以 v- 开头的属性是 Vue 指令(directives)。指令是特殊的标记,添加在元素上的属性,用于在 DOM 上做特定的操作。

v-bind

动态绑定,在需要绑定的元素属性前加上 v-bind: 即可,属性值改为变量。

简写为 :

1
<div :class="str"></div>

这样的绑定是单向的,Vue 中的数据变动会导致 DOM 中的数据变动,但 DOM 属性变动不会导致 Vue 中的数据变动。

也可以绑定一个对象,这样就不需要 key 值,把对象中的每个键作为 key


动态绑定 css 属性时,情况有些不同。

传入的是一个对象,属性名是样式名,而 css 中很多样式名中含有 -,但对象的属性名是不可以包含 - 的,所以需要用驼峰命名法来规避。

动态绑定类时也可以传入一个对象,属性是对象名,属性值是布尔值。

通过传入对象的方式绑定 class 或 css 时,属性是常量,属性值是变量。

:class="{ classname1: true, classname2: false, ... }"

v-on

监听某个时间并执行相应的函数。

在事件前添加 v-on: 即可,例如:v-on:click

可以简写为 @click

  • .prevent 事件修饰符,可以阻止默认事件行为,可以组织表单提交后页面刷新,也可以点击链接后阻止导航。

v-model

input 标签中添加属性 v-model=“var"

变量值与输入框内的值便是双向绑定的。

即修改其中一个必然会影响另一个值。

不仅仅文本输入框可以进行双向绑定,checkbox 也可以,需要将绑定的值设为布尔类型。

v-for

1
<div v-for="(i, index) in list" :key="index">

这里通过遍历 list 并且按照其中元素个数渲染多个 divi 是形参,代表 list 中的值,index 表示数组下标。

:key 作用是提供唯一标识,防止渲染错误。

因为所有的 v-for 都是通过 key 值来渲染元素的,默认为当前数组的下标,当有多个 v-for 时,key 可能相同,就会导致渲染出错误的结果。

v-show

控制一个元素是否显示,属性值为布尔值。

v-if

v-show 用法相同,区别在于,如果元素不显示,不会创建这个元素,而 v-show 只是单纯利用 CSS 将元素进行隐藏。

v-else-if

v-if 相同,分支逻辑。

v-else

v-if 相同,分支逻辑。

Vue Router

Vue 路由,通过它我们可以避免像静态页面一样通过大量的发送请求得到不同的页面文件来实现单或多页面 APP

与多页面静态网页 APP 相比,Vue 实现的多页面 APP 区别在哪里?

  • HTML 多页面:
    • 每次更换页面都需要重新加载整个页面文件。
    • 不同的页面对应着不同的页面文件。
  • Vue 实现多页面:
    • 每次更换页面只需要请求需要的组件。(或者初始加载时一次性请求所有可能用到的组件,这样切换很快但初始加载很慢,所以用到懒加载技术实现按需加载)
    • 只有一个页面文件,通过修改 url 修改不同组件的呈现。

流程

flowchart LR;
    1["制定路由规则(index.js)"]-->2["使用规则(main.js)"] & 3["创建组件(views.vue)"]-->4["渲染路由" router-view];

注意:

  • a 标签会产生新的请求,所以要使用 router-link
  • JS 里属性名不可以包含 -,所以使用驼峰命名代替。

export & import

  1. Default Export

每个模块可以有且最多一个的默认导出值。

默认导出在导入时,可以随意命名,并且可以不需要花括号。

  1. Named Export

可以导出多个值。

在导入时,只能使用这个变量的名字,且必须使用花括号包裹。

Vue 项目

文件结构

页面本身是一个根组件。

不同的区域是不同的组件。

创建 Vue

CDN 创建

推荐小白先使用这个,因为 CLI 方式生成的结构比较复杂,令人费解。

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> 引入至 HTML 的 head 标签后便可使用。

创建一个 Vue APP:

1
Vue.createApp({}).mount('#app');

代表创建一个 APP,条件是一个对象,挂载在 DOM 中的 #app 节点上。

CLI

命令行 cd 至目标目录,输入 npm create vue@latest

预览

安装依赖:

1
npm install

本地运行(基于 Vite):

1
npm run dev

打包和发布

使用 npm run build 来构建项目,你会得到一个 dist 文件夹,里面就装有你打包好的文件,注意这里面的 index.html 文件所引入的 CSS 和 JS 路径均为绝对路径,要改为相对路径否则网页在云端预览时将会是一片空白,因为网页内容由 JS 生成。

如何发布?

1
2
3
git init
git add .
git commit -m ""

然后去 Github 创建一个仓库。

1
2
git remote add origin ...
git push -u origin ...

具体看 Github 创建仓库后下面的提示。

(这里的 -u 是指设置上游分支,即默认分支,设置好后以后只需要使用 git pushgit pull 即可,不需要加上 origin ...

然后这只是把项目的源代码上传上去了,但我想让这个项目跑起来。

然而上传的文件并没有 dist 目录,这是因为它被 .gitignore 文件给忽略了,我们可以使用 gh-pages 插件将项目文件上传到 gh-pages 分支。

1
npm install gh-pages --save-dev

在根目录的 package.json 文件中添加相应命令以及你的 homepage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"name": "your-vue-project",
"version": "1.0.0",
"private": true,
"homepage": "https://yourusername.github.io/your-repo-name",
"scripts": {
"build": "vue-cli-service build",
"deploy": "gh-pages -d dist"
},
"dependencies": {
// 项目依赖
},
"devDependencies": {
"gh-pages": "^3.2.3"
}
}

这里 gh-pages -d dist 就是上传 dist 目录,然后去 Github 开启 Github Pages 并把分支改为 gh-pages 即可。

Vue 实例

createApp 传入的参数是一个根组件,可以是一个 Vue 组件也可以是一个 Javascript 对象。

computed

计算属性,当里面的值所依赖的值发生变化时会重新计算。

它的值是一个对象。

在 Vue3 中,computed() 接收一个函数,返回值作为计算属性值,函数中的变量就是依赖。

data

一个函数,返回的是一个对象,里面包含着需要用到的数据。

将作为 Vue 实例的一个属性,在这个对象内访问 data 中的值时需要 this.

属性名和属性值相同时可以只写属性名。(ES6)

methods

一个对象,里面可以定义各种方法,相当于方法版的 data。

components

一个对象,用于注册子组件,里面包含着需要注册的子组件,需要提前 import

props

一个对象,可以在子组件的导出对象中定义 props,这个对象的属性代表父组件中可以传递给子组件的属性,属性值为这个属性所接收的值类型。

示例:

1
2
3
4
props: {
title: String,
age: Number,
}

ES6 模块

使用 export 关键字进行导出,可以导出任何值。

可以使用 export default 关键字导出一个默认的值。

在另一个文件内使用 import {name1, name2} from '././...' 导入。

同时需要在 HTML 文件中的 script 标签加入 type="module"

  • Title: Vue Note
  • Author: Falling_Sakura
  • Created at : 2024-06-16 14:24:03
  • Updated at : 2024-11-21 10:44:39
  • Link: https://vercel.fallingsakura.top/9f08e17f.html
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments