OptionsAPI (选项式)和 CompositionAPI(组合式)
- vue2使用的是选项式的api风格
- 选项式的写法会使得 数据 方法 计算属性 是分散开的 不利于维护
- vue3 推荐使用的式组合式api 组合式api写在setup中
- 把一个元素的 各个属性 数据 方法 按照顺序排列 全部写在一起 组成一个函数setup()
- 这样的话 每个属性 都是一个整体的 便于维护
- setup()函数 没有this 弱化了this
- setup使用return导出数据
- 并且setup的执行比钩子函数 beforeCreate()还要早
- 在 data和methods 和setup 是可以共存的
- 并且 data还可以读取到 setup里的数据
- 但是setup 不能读取到data里的数据
- setup里面的数据不是相应式的
setup的语法糖
-
在vue3项目中可以写两个script
<script setup></script>
-
把这当成setup函数 还不用return导出数据 更加方便,会自动的return
-
使用ref 函数让数据变成相应式的数据 这个ref 和vue2 的不一样
-
需要手动的引入 import {ref} from ‘vue’
-
在需要相应的数据用ref()标签包裹就行
- ref 定义基本类型数据
- 在数据中存储的值 是不用 .value的
- 但是当我们想要 改变时 就需要 el.value = ’ ’
- reactive 对象,数组数据类型
- 同样的需要引入 reactive 函数
- 更该数据时不需要使用.value
- 有局限性,定义的对象不可以整体修改
- 要修改整体对象时使用 Object.assign(el,{ })的方法
- 特殊的是 ref 也可以定义 对象类型的数据
- 其实底层还是 在ref 中调用了 reactive方法
- 切记的是ref之后的数据要修改的话要加上.value
- ref和reactive的区别
- reactive 修饰的对象 是不能改变一个对象整体 就是重新分配对象的话会失去相应式
- 只要出现了 .vaule则数据就是响应式
- 需要一个基本数据类型 用 ref
- 一个对象 层级不深 使用 ref 和reactive都行
- 需要一个对象 层级较深 推荐使用reactive
- ref 定义基本类型数据
结构赋值 toRefs
- 当我们使用reactive定义了一个对象时,会得到一个可以相应式的对象数据,但是如果把这个对象里面的数据复制一份的话,得到的就不是响应式的数据了
- 这时我们就要引入toRefs,表层含义就是把 数据变成ref 也是需要引入的
- toRefs 接受一个由reactive定义的对象,会把里面的每一个key:value都提出来 形成新的相应式的对象
- 把响应式对象的每一个属性,都拿出来解构,成响应式的对象 ,结构出的对象和之前的对象值是一样的,一个改变,随之也改变
计算属性computed
-
在setup中 computed和ref一样 都需要导入才能使用
let fullName = computed(() => { return }) <!--里面是一个箭头函数--> let change = computed({ get(){ return *** }, set(){ return *** }, })
-
在计算属性里 还是有两个经典的方法,这个一般不用,常见的是直接return出的结果。但是当们需要把change中的值改变时就需要调用set方法:就是改变计算属性的值,如 fullName.value = ‘ ’
-
一般的情况中computed的返回值 只是一个只读的属性,使用了get和set之后才是响应式的数据
watch监视
1. vue3中的watch只能监听四种数据
-
ref定义的数据
-
ref定义的基本数据类型
-
let sum = ref(0) const stopWatch = watch(sum, (newValue, oldValue) => { console.log("new-value:" + newValue + '------' + oldValue); if (newValue > 5) { stopWatch() } })
-
ref定义对象数据类型
let person = ref({ name: "张三", age: 18, }) watch(person, (newValue, oldValue) => { console.log('变化了', newValue, oldValue);},{ deep: true }) function changeName() { person.value.name += '~' } function changePerson() { person.value = { name: '里斯', age: 990 }}
-
在ref的对象数据类型中,改变对象当中的元素值时,是不会发生监听的,但是直接改变了对象的地址时,就会发生监听,
-
当使用ref监听对象时,想要监听出属性值改变也会监听,就需要手动打开深度监听,需要在watch拆传递第三个参数{deep:true}
-
-
reactiev定义的数据
- reactive监视的数据 是隐式的创建了深度监听,是不可以关闭的
- 但是reactive定义的对象,修改对象整体需要注意使用assign
- 在以上的对象监听中,newValue和oldValue 打印出来都是一样的 原因是,对象的地址没有发生改变,只是改变了其中的值
-
函数的返回值,getter函数(能返回一个值的函数)
- 若监视的属性不是对象类型,这是就需要用一个函数返回值来监视,可以使用箭头函数return
- 若监视的是响应式对象中的某个属性,属性也是对象时,推荐也写成函数,但是这样的话,这个监视的对象内的元素发生改变时是监听不到的,需要添加deep配置项
-
一个包含上述内容的数组
- 在watch的参数中可以监听多个数据
2.watch的使用方法发生了改变
1. vue3中的watch的使用方法也不一样,首先watch(el,callback),el监视的元素
2. 这里监视的数据el是不用.value 的
3. 在这个监视器可以给一个名称,当达到判定条件时,可以调用这个方法,这时就会停止监视器
4. watch的三个参数watch(监视的对象,监视的回调,配置参数)
3.watchEffect
- 当监视的数据很多的时候,使用watch监视的话,要传入的监视对象会很多,但是watchEffect就比较的智能他会自动的监视,只需要写监视的回调函数就行了。不用明确的指出监视的数据
ref获取元素
- vue3中的ref和vue2中的获取元素的方法不一样,先要在页面导入ref方法
- 在要导出的标签上添加ref=“name”
- 在setup中使用 let name = ref() 让定义的name被ref处理
- 导出的时候直接使用 name.vaule
- ref能在普通的标签上加,也能加在组件上面,添加在组件上时获取的是组件的对象,但是无法读取打信息,这是因为vue3的保护机制,要想获取信息的话,需要在 子组件中添加defineExpose({})方法,里面写要暴露的内容
TS的接口,泛型和自定义类型
-
在ts中可以定义一个接口类型,这个接口可以是一个规范,当我们定义一个对象时,可以根据这个接口对 对象的属性名和属性值进行一定的 约束
-
export interface PersonInter { id: String; name: String; age: Number; }
-
import { type PersonInter } from '@/types'; imp //1.定义的对象要符合我的接口的规范 let Person: PersonInter = { id: '123456', name: '张十三', age: 20 } //2.泛型是不确定的类型,可以是自己定义的,下面具体的意思:定义一个数组 数组里面的的元素按照我的约束 let arrList: Array<PersonInter> = [ { id: '01', name: '张三', age: 20 }, { id: '03', name: '赵四', age: 30 }, { id: '05', name: '老王', age: 250 } ]
-
在接口的导入和引用时要注意使用的方法,普通的对象就是直接的引用接口,要注意使用的方法
-
导入时要加 type,在reactive后也可以直接的添加泛型 let arrList3 = reactive<persons>
- 引入接口的函数会报错可以引入1
Props
-
使用的方法发生了变化,props编程了一个方法,需要在子组件中导入definProps方法
-
在definProps中,接收的元素必须是一个数组
-
// 1.直接的传递 // const data = defineProps(['list']) //2.传递 + 限制类型 // defineProps<{ list: PersonInter }>() //3.传递 + 限制类型 + 限制必要性 // defineProps<{ list?: PersonInter }>() //4.传递 + 限制类型 + 限制必要性 + 指定默认值 withDefaults(defineProps<{ list?: persons }>(), { list: () => [{ id: '03', name: "666", age: 333 }] })
-
要是想限制传入的数据 可以在definProps<>(),在尖括号中写限制
-
withDefaults是一个函数,要把defineProps全部包裹进去,默认的要是一个方法
hooks,有hooks组合式API才发挥了威力
- 当我们在页面中编辑了大量的数据和方法时,代码就会非常的乱,可以使用hooks把代码的模块化发挥到极致,类似于vue2中的混入minxin
- 是一个js或者是ts的文件,但是命名有一定的规定 use…
- 先创建hooks文件夹,在里面写相应的文件
- 我们需要把一类的数据和方法全部的放入进去,同时需要用一个函数包裹
- 这个函数也需要默认的导出,并且需要把 数据和方法给return 出去 这样组件才可以接收
- 在组件中接收hooks 首先需要先导入 定义的方法 在使用 const { } = useSum()
{
"compilerOptions": {
// ...
"baseUrl": "./", // 这里需要配置
"paths": {
"@/*": ["./src/*"] // 这里需要配置
}
// 如果baseUrl设置为'src',那paths就应该配置为{"@/*": "./*"},如下:
// "baseUrl": "src",
// "paths": {
// "@/*": ["./*"]
// }
// 相关baseUrl,paths说明请查看官方文档
},
// include也需要配置以下:
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"exclude": ["node_modules"]
}
可以在tsconfig.json的文件中注释系统生成 的文件 粘贴上下面的文件 ↩︎