Vue3 书写风格
- options API 风格(主要是Vue2)
<script>
export default {
// 定义变量(里面的数据都是响应式数据,随着数据的修改页面相关的数据随之发生变化)
data() {
return {
age: 18
}
},
// 定义方法
methods: {
// 定义方法
xxx () {
}
},
}
</script>
数据定义在data的return内和return外的区别:
1.return外:单纯修改这个数据是不可以修改的,因为没有被get/set
2,return内:是可以修改的
Options
类型的 API
,数据、方法、计算属性等,是分散在:data
、methods
、computed
中的,若想新增或者修改一个需求,就需要分别修改:data
、methods
、computed
,不便于维护和复用。
优先级从高到低为:props > methods > data > computed > watch
- Composition API 风格(Vue3)
可以用函数的方式,更加优雅的组织代码,让相关功能的代码更加有序的组织在一起。
说明:以上四张动图原创作者:大帅老猿
Compostion API 的优势:
- 在Compostion API 中时根据逻辑相关组织代码的,提高可读性和可维护性,类似于react的hook写法。
- 而且因为 composition API 几乎是函数,使用 ts 会有更好的类型推断。
- 更好的重用逻辑代码,在Options API中通过MIxins重用逻辑代码,容易发生命名冲突且关系不清。
- 解决在生命周期函数经常包含不相关的逻辑,但又不得不把相关逻辑分离到了几个不同方法中的问题,如在mounted中设置定时器,但需要在destroyed中来清除定时器,将同一功能的代码拆分到不同的位置,造成后期代码维护的困难。
- composition API 对tree-shaking 友好,代码跟容易压缩。
- composition API 没有 this 的使用,避免了 this 指向不明的问题。
2.1 setup 函数模式
setup
是Vue3
中一个新的配置项,值是一个函数,组件中所用到的:数据、方法、计算属性、监视…等等,均配置在setup
中。
setup
函数返回的对象中的内容,可直接在模板中使用。setup
中访问this
是undefined
。setup
函数会在beforeCreate
之前调用,它是“领先”所有钩子执行的。
<script>
export default {
// 定义变量(此时变量并不是响应式的)和方法
setup() {
const age = 18
const xxx = () => {
console.log('xxx')
}
// 返回一个对象,对象中的内容,模板中可以直接使用
return {
age,
xxx
}
}
}
</script>
2.2 setup 语法糖模式
由于将所有东西都写在 setup 函数里面,会导致整个函数变得非常臃肿,所以官方推出了 setup 语法糖。普通的变量依然不是响应式的。
<script setup lang="ts">
const a:number = 1
</script>
vue3如果用setup写如何获取类似于vue2中的this?
import {getCurrentInstance} from ‘vue’
let instance = getCurrentInstance();
console.log(instance.appContext.app.config.globalProperties.xxx;
一般情况下,我们Vue3文件名和Vue控制台调试工具中模块名相同。
但是,如果我们想要更改Vue控制台调试工具中模块名,就需要写成如下格式(添加一个script标签):
<script lang="ts">
export default {
name:'Layout',
}
</script>
<!-- 下面的写法是setup语法糖 -->
<script setup lang="ts">
</script>
上述代码,还需要编写一个不写setup
的script
标签,去指定组件名字,比较麻烦,我们可以借助vite
中的插件简化
- 第一步:
npm i vite-plugin-vue-setup-extend -D
- 第二步:
vite.config.ts
import { defineConfig } from 'vite' import VueSetupExtend from 'vite-plugin-vue-setup-extend' export default defineConfig({ plugins: [ VueSetupExtend() ] })
- 第三步:
<script setup lang="ts" name="Person">
模板插值语法
- 直接声明变量
<template>
<div>
{{ message }}
</div>
</template>
<script setup lang="ts">
const message = 'msg'
</script>
<style lang="scss" scoped>
</style>
- 运算表达式,三元表达式
<template>
<div>
{{ message + 1 }}
{{ (message === 0) ? 'true' : 'false' }}
</div>
</template>
<script setup lang="ts">
const message:number = 0
</script>
<style lang="scss" scoped>
</style>
- 操作API
<template>
<div>
{{ message.split(',') }}
</div>
</template>
<script setup lang="ts">
const message:string = "they, are, massages"
</script>
<style lang="scss" scoped>
</style>
结构块 | 是否必须 | 说明 |
---|---|---|
template | ❌ 不是必须的 | 如果有 render 函数(h函数创建节点),可以省略 |
script | ❌ 不是必须的 | 纯静态组件可以省略 |
style | ❌ 不是必须的 | 可以用全局 CSS 或外部样式 |
一般情况下,template
和 script
必须至少要有一个,否则组件没有意义,会报错。
指令
v- 开头都是 vue 的指令
- v-text 用来显示文本
- v-html 用来展示富文本,支持 html 标签,但是不支持组件
<div v-html="message"></div>
<div v-text="message"></div>
-
v-if 用来控制元素的显示隐藏(切换真假DOM,直接注释掉表达式内容)
-
v-else-if 表示 v-if 的“else if 块”。可以链式调用
-
v-else v-if条件收尾语句
-
v-show 用来控制元素的显示隐藏(display:none 的切换)
<template>
<div v-if="message === 1">
true
</div>
<div v-else>
false
</div>
</template>
<script setup lang="ts">
const message: number = 0
</script>
<style lang="scss" scoped></style>
v-if
和v-show
的区别: 【Vue】v-if 和 v-show 的区别
-
v-on 简写@ 用来给元素添加事件
-
<button v-on:事件名="内联语句">按钮</button>
-
<button v-on:事件名="处理函数">按钮</button>
-
<button v-on:事件名="处理函数(实参)">按钮</button>
区别 Vue2:
- data中的数据, 最终会被添加到实例上
- 事件处理函数应该写到一个跟data同级的配置项(methods)中
- methods中的函数内部的this都指向Vue实例 this.xxx 即为 data 中的数据 xxx
- 如果不传递任何参数,则方法无需加小括号;methods方法中可以直接使用 e 当做事件对象
- 如果传递了参数,则实参
$event
表示事件对象,固定用法。
<div id="example-2">
<!-- `greet` 是在下面定义的方法名 -->
<button v-on:click="greet">Greet</button>
</div>
//....
var example2 = new Vue({
el: '#example-2',
data: {
name: 'Vue.js'
},
// 在 `methods` 对象中定义方法
methods: {
greet: function (event) {
// `this` 在方法里指向当前 Vue 实例
alert('Hello ' + this.name + '!')
// `event` 是原生 DOM 事件
if (event) {
alert(event.target.tagName)
}
}
}
})
有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
// ...
methods: {
warn: function (message, event) {
// 现在我们可以访问原生事件对象
if (event) {
event.preventDefault()
}
alert(message)
}
}
<template>
<div>
<button @click="change">click me</button>
<!-- 也可以写成动态的 -->
<!-- <button @[event]="xxx">点我!</button> -->
</div>
</template>
<script setup lang="ts">
// const event = 'click'
const change = () => {
console.log('click++');
}
</script>
<style lang="scss" scoped></style>
- v-bind : 用来绑定元素的动态属性(简写为
:
),属性非常数,而是人为定义的变量或方法。
<template>
<!-- 动态类型多个则使用[]包含 -->
<!-- 每个元素中支持一个动态 class 和一个静态 class -->
<div :class="(boo ? 'a' : 'b')">
{{ num }}
</div>
</template>
<script setup lang="ts">
const num: number = 1
const boo = false
</script>
<style scoped>
.a {
color: red;
}
.b {
color: blue;
}
</style>
- v-model 双向绑定响应式数据,代替了手动连接值绑定和更改事件监听器的麻烦,会根据所使用的元素自动使用对应的 DOM 属性和事件组合。
v-model
支持input
,textarea
,selected
元素。v-model
会忽略任何表单元素上初始的value
、checked
或selected
属性。它将始终将当前绑定的 JavaScript 状态视为数据的正确来源,要使用响应式API来设定初始值。
<template>
<div>
<input v-model="a" type="text">
<div>{{ a }}</div>
</div>
</template>
<script setup lang="ts">
//ref reactive 使变为响应式
import {ref} from 'vue'
const a = ref('model')
</script>
<style lang="scss" scoped></style>
- v-for 用来遍历元素
<template>
<div>
<!-- 参数的顺序不能变 -->
<div :key="index" v-for="(item, index) in arr">
{{ index }} - {{ item }}
</div>
</div>
</template>
<script setup lang="ts">
const arr: string[] = ['red', 'blue', 'pink']
</script>
<style lang="scss" scoped></style>
优先级:
- Vue2: v-for > v-if
- Vue3: v-if > v-for
- v-once 性能优化,只渲染一次
- v-memo 性能优化