本文最后更新于:2023年10月26日 晚上
创建 Vue 应用
执行以下命令
选择相应的插件
1 2 3 4 5 6 7 8 9 10 11 12
| Vue.js - The Progressive JavaScript Framework
√ 请输入项目名称: ... vue_base √ 是否使用 TypeScript 语法? ... 否 / 是 √ 是否启用 JSX 支持? ... 否 / 是 √ 是否引入 Vue Router 进行单页面应用开发? ... 否 / 是 √ 是否引入 Pinia 用于状态管理? ... 否 / 是 √ 是否引入 Vitest 用于单元测试? ... 否 / 是 √ 是否要引入一款端到端(End to End)测试工具? » 不需要 √ 是否引入 ESLint 用于代码质量检测? ... 否 / 是
正在构建项目 D:\thl\vue3_demo\vue_base...
|
进行目录安装依赖并运行
1 2 3 4 5
| 项目构建完成,可执行以下命令:
cd vue_base npm install npm run dev
|
目录结构如下

模板语法(指令)
文本插值/v-text
{{ }}
为文本插值语法,v-text:更新元素的文本内容
最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号):
1 2 3 4 5 6 7
| <script setup lang="ts"> import { ref, reactive } from "vue"; let count = ref(3); </script> <template> <div>渲染数字为:{{ count }}</div> </template>
|

1 2 3
| <span v-text="msg"></span> <!-- 等同于 --> <span>{{msg}}</span>
|
v-text 跟{{ }}
效果是一样的,v-text 不能在标签中输入内容
原始 HTML
v-html
指定内容渲染为 html
1 2 3 4 5 6 7 8 9 10 11
| <script setup lang="ts"> import { ref, reactive } from "vue"; let html = "<span>我是如来佛祖玉皇大帝观音菩萨指定取西经特派使者花果山水濂洞美猴王齐天大圣孙悟空啊 帅到掉渣</span>"; </script> <template> <div> <p>html:内容为:{{ html }}</p> <span v-html="html"></span> </div> </template>
|

显示
v-show
基于表达式值的真假性,来改变元素的可见性。
v-show
通过设置内联样式的 display
CSS 属性来工作,当元素可见时将使用初始 display
值。当条件改变时,也会触发过渡效果
v-if
基于表达式值的真假性,来条件性地渲染元素或者模板片段。
当 v-if
元素被触发,元素及其所包含的指令/组件都会销毁和重构。如果初始条件是假,那么其内部的内容根本都不会被渲染
可用于 <template>
表示仅包含文本或多个元素的条件块。
当条件改变时会触发过渡效果
v-else
表示 v-if
或 v-if
/ v-else-if
链式调用的“else 块”。
v-else-if
表示 v-if
的“else if 块”。可以进行链式调用
循环
基于原始数据多次渲染元素或模板块
列表渲染
使用 v-for
指令基于一个数组来渲染一个列表
v-for
指令的值需要使用 item in items
形式的特殊语法,其中 items
是源数据的数组,而 item
是迭代项的别名
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 lang="ts"> import { ref, reactive } from "vue"; const userList = reactive([ { name: "隆海", age: 18, hobby: "旅游", }, { name: "晚生", age: 20, hobby: "唱歌", }, { name: "熙熙", age: 23, hobby: "吃", }, ]); </script> <template> <ul> <li v-for="(item, index) in userList" :key="index"> 姓名:{{ item.name }},年龄:{{ item.age }},爱好:{{ item.hobby }} </li> </ul> </template>
|

对象渲染
遍历的顺序会基于对该对象调用 Object.keys()
的返回值来决定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <script setup lang="ts"> import { ref, reactive } from "vue"; const userInfo = reactive({ name: "隆海", age: 18, hobby: "旅游", }); </script> <template> <ul> <li v-for="value in userInfo"> {{ value }} </li> </ul> </template>
|

可以通过提供第二个参数表示属性名 (例如 key):
1 2 3 4 5 6 7 8 9 10 11 12 13
| <script setup lang="ts"> import { ref, reactive } from "vue"; const userInfo = reactive({ name: "隆海", age: 18, hobby: "旅游", }); </script> <template> <ul> <li v-for="(value, key) in userInfo">{{ key }} : {{ value }}</li> </ul> </template>
|

第三个参数表示位置索引
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <script setup lang="ts"> import { ref, reactive } from "vue"; const userInfo = reactive({ name: "隆海", age: 18, hobby: "旅游", }); </script> <template> <ul> <li v-for="(value, key, index) in userInfo"> {{ index }}-{{ key }} : {{ value }} </li> </ul> </template>
|

数组变化侦测
Vue 能够侦听响应式数组的变更方法,并在它们被调用时触发相关的更新。这些变更方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
绑定属性
v-bind:<name>
动态的绑定一个或多个 attribute,也可以是组件的 prop。
1 2 3 4 5 6 7 8 9 10 11
| <!-- 绑定 attribute --> <img v-bind:src="imageSrc" />
<!-- 动态 attribute 名 --> <button v-bind:[key]="value"></button>
<!-- 缩写 --> <img :src="imageSrc" />
<!-- 缩写形式的动态 attribute 名 --> <button :[key]="value"></button>
|
绑定事件
v-on
给元素绑定事件监听器
缩写:@
修饰符
.stop
- 调用 event.stopPropagation()
。
.prevent
- 调用 event.preventDefault()
。
.capture
- 在捕获模式添加事件监听器。
.self
- 只有事件从元素本身发出才触发处理函数。
.{keyAlias}
- 只在某些按键下触发处理函数。
.once
- 最多触发一次处理函数。
.left
- 只在鼠标左键事件触发处理函数。
.right
- 只在鼠标右键事件触发处理函数。
.middle
- 只在鼠标中键事件触发处理函数。
.passive
- 通过 { passive: true }
附加一个 DOM 事件。
双向绑定
v-model
在表单输入元素或组件上创建双向绑定。
插槽
v-slot
用于声明具名插槽或是期望接收 props 的作用域插槽。
忽略编译
v-pre
跳过该元素及其所有子元素的编译
渲染一次
v-once
仅渲染元素和组件一次,并跳过之后的更新。
模板引用
标签上的 ref
特殊的 ref
attribute
为了通过组合式API
获得该模板引用,我们需要声明一个同名的 ref
1 2 3 4 5 6 7 8 9 10 11
| <script setup lang="ts"> import { ref, onMounted } from "vue"; const ipt = ref(); onMounted(() => { ipt.value.focus(); }); </script> <template> <div></div> <input type="text" ref="ipt" /> </template>
|
组件上 ref
新建一个子组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <script setup lang="ts"> import { ref, reactive } from "vue"; const name = "隆海"; const age = ref(18); defineExpose({ name, age, }); </script> <template> <div>我是子组件</div> </template>
<style scoped lang="scss"></style>
|
父组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <script setup lang="ts"> import Child from "@/components/Child.vue"; import { ref, onMounted } from "vue";
const child = ref(); onMounted(() => { console.log(child.value.name); }); </script> <template> <div> <Child ref="child" /> </div> </template>
|

获取组件上的属性和值
1 2 3 4 5 6 7 8 9 10 11
| <script setup lang="ts"> import { ref, onMounted } from "vue"; const bind = ref(); onMounted(() => { bind.value.style.background = "red"; console.log("bind", bind.value.getAttribute("id")); }); </script> <template> <div ref="bind" num="s1" v-bind:id="'s13'">bind语法</div> </template>
|

依赖注入
Provide(提供)
父级提供子孙使用
home.vue
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 lang="ts"> import { ref, reactive, provide, inject } from "vue"; import Chlid from "@/components/Child.vue"; const userList = reactive([ { name: "隆海", age: 18, hobby: "旅游", }, { name: "晚生", age: 20, hobby: "唱歌", }, { name: "熙熙", age: 23, hobby: "吃", }, ]); provide("arrList", userList); </script> <template> <h1>我是home</h1> <div>home中的数据</div> <Chlid /> </template>
|
child.vue
1 2 3 4 5 6 7 8 9
| <script setup lang="ts"> import { ref, reactive, provide, inject, onMounted } from "vue"; import Sun from "@/components/Sun.vue"; </script> <template> <h2>我是child</h2> <div>child中的数据</div> <Sun /> </template>
|
sun.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <script setup lang="ts"> import { inject, onMounted } from "vue"; const arrList = inject("arrList"); onMounted(() => { console.log("arrList", arrList); }); </script> <template> <h2>我是sun</h2> <ul> <li v-for="(item, index) in arrList" :key="index"> 姓名:{{ item.name }},年龄:{{ item.age }},爱好:{{ item.hobby }} </li> </ul> </template>
|
Inject(注入)