目录:一篇通识Vue3.0
1.OptionsAPI(选项式)和CompositionAPI(组合式)
params(接受的地方query换成params就可以了)
readonly和shallowReadonly(保护原始数据)
核心语法
1.OptionsAPI(选项式)和CompositionAPI(组合式)
选项式API:data,methods,name等Vue2的基础写法
弊端:数据方法计算属性分别在不同的api中不便于维护和复用
组合式API?
2.setup
原来数据是写在data里面的现在这样的写法不是响应式的
而且setup会比beforeCreate要响应的更早,
setupreturn也可以是一个渲染函数
return ()=>'hellow'
export default {
name: 'person',
setup() {
let name = '张三'//此时的name不是响应式的
let age = 20/此时的age不是响应式的
let tel = '11111111'/此时的tel不是响应式的
function showTel() {
alert(tel)
}
return {
name,
age,
tel,
showTel
}
}
setup与data,methods同时存在
data能不能拿到setup中的值呢?可以拿到!
setup是生命周期里面最早的
setup能拿到data里面的值么?不能
谁更厉害?setup更厉害
setup语法糖
<script setup>
相当于在setup函数里面写,而且不用自己return
<script>
但是呢语法糖里不能写组件相关的这时候需要用到一个插件
npm i vite-plugin-vue-setup-extend
在vite.config.ts中配置即可
import VueSetup from 'vite-plugin-vue-setup-extend'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
VueSetup()
],
<script lang="ts">
export default {
name: 'person',
}
</script>
<script setup lang="ts">
let name = '张三'
let age = 20
let tel = '11111'
let a = 101
function showTel() {
alert(tel)
}
</script>
不想写两个标签可以直接在script标签上使用name属性自定义,如果与文件名同名不用插件也可以
ref响应式数据
基本类型的响应式数据
引入
//引入ref
import { ref } from 'vue'
想让什么数据是响应式的就用ref包住
let name = ref('张三')
let age = ref(20)
let tel = '11111'
let a = 101
console.log(1, name, 2, age, 3, tel)
看看区别
而且插值上会自动.value 不用写,但是修改值的时候需要使用.value修改
}
function changeName() {
name.value = '大哥'
}
function addAge() {
age.value++
}
reactive只能定义对象类型的响应式数据(用情专一)
import { reactive } from 'vue'
//基本类型的响应式数据
let name = ref('张三')
let age = ref(20)
//对象类型的响应式数据hobby
let hobby = reactive({
name: '章子怡',
age: 45,
sex: '男'
})
ref可以定义基本类型的响应式数据,也可以定义对象类型的响应式数据
ref的底层还是reactive
区别:
1.ref创建的变量必须使用.value可以使用volar自动添加.value
2.reactive重新定义一个对象hobby的时候,这个对象就失去了响应式属性
hobby={name:'',age:''.......},
可以使用Object.assign(1,2)1和2的都会对比不一样就新建,一样就替换
let assign = { name: 'ls', age: 12, sex: '5' }
let tel = '11111'
let a = 101
console.log(hobby)
function changeC() {
hobby={ name: 'ls', age: 12, sex: '5'}//页面不更新hobby用reactive包裹
Object.assign(hobby, assign)//这样页面才会更新hobby用reactive包裹
hobby.value={ name: 'ls', age: 12, sex: '5'}//页面更新hobby用ref包裹
console.log(hobby)
}
toRefs解构
确保结构出来的对象都是响应式对象
通过把reactive中每一组键值提出来成一个新的对象
解构后页面也可以直接使用name
let person = reactive({ name: '章子怡', age: 45 })
let { name, age } = toRefs(person)
function changeName() {
name.value += '冯刚'
}
function changeAge() {
age.value += 1
}
计算属性computed
只读的计算属性,fullName不能修改
let fullName = computed(() => {
const name = na.value.slice(0, 1).toUpperCase() + na.value.slice(1) + me.value
return name
})
v-model修改后发现是只读,也就是没有set
怎么改成可读可写呢?写get,set函数
set接收的参数就是修改后的值
set(val) {
const [str1, str2] = val.split('-')
console.log(str1, str2)
}
;(na.value = str1), (me.value = str2)
watch侦听
vue3中watch可以监视的数据只有四种
1.ref定义的数据
基本类型
watch(na, (newV, oldV) => {
console.log(newV, oldV)
})
watch(me, (newV, oldV) => {
console.log(newV, oldV)
})
对象类型
watch(
hud,
(newV, oldV) => {
//监视对象类型的数据但是对象里面的数据修改监听需要添加属性deep:true
console.log(newV, oldV)
},
{ deep: true,immediate:true }
)
总结:如果是修改的整个对象那就有新旧值之分,修改的是对象里面的某个属性那新的和旧的都是一样的
2.reactive定义的对象
如果监视的是reactive类型的对象数据已经隐式创建了深层监听,而且关不掉
因为修改姓名和age都是在原对象上操作原对象并没发生改变所以newval和oldval是一样的
watch(obj, (n, o) => {
console.log('obj', n, o)
})
let obj = reactive({
a: {
b: {
c: 100
}
}
})
修改整个对象后才分新旧值
function changePerson() {
Object.assign(hud, { name: '终南山', age: 68 })
}
3.getter函数(能返回一个值的函数)只想让监视对象中的某个属性
let person = reactive({
name: '张宝果',
age: 18,
car: {
c1: '奔奔',
b1: '江淮',
a1: '解放'
}
})
watch(
() => person.name,//getter函数一个有返回值的函数
(n, o) => {
console.log('person', n, o)
}
)
监视对象里面的对象的时候可以直接写对象但是修改对象整个的时候不会被监听到
watch(person.car, (n, o) => {
console.log('person', n, o)
})
加上函数后就会被监听到,但是里面的属性就监听不到了
watch(
() => person.car,
(n, o) => {
console.log('person', n, o)
}
)
怎么解决呢?加deep:true
watch(
() => person.car,
(n, o) => {
console.log('person', n, o)
},
{ deep: true }
)
总:1.监视对象中基本类型的数据的时候需要写成函数式
2.监视对象中对象类型的数据时,不需要监听整个对象变化时可以直接写 ,需要监听整个对象不监听对象里面的变化时可以写成函数式,既需要监听整个对象变化,又要监听对象中属性的变化是时不仅要写成函数式,还要加deep:true;
推荐使用函数式
4.一个包含上述内容的数组
监视对象中指定的多个值
//监视对象中的多个函数
watch(
[() => person.car.a1, () => person.name],
(n, o) => {
console.log('person', n, o)
},
{ deep: true }
)
WatchEffect
用到谁就监视谁,加载自动执行一次
// watch([sum, count], (val) => {
// let [n, o] = val
// if (n > 200) {
// console.log(n, o)
// }
// })
watchEffect(() => {
if (sum.value >= 60) {
console.log('水温过高')
}
})
标签的Ref属性
在html标签上就是获取DOM元素
<template>
<div class="person">
<button class="btn" @click="aler"></button>
<h2 ref="cl">123</h2>
</div>
</template>
<script setup lang="ts" name="person">
//引入ref
import { ref } from 'vue'
let cl = ref()
function aler() {
console.log(cl.value)
cl.value.innerText = '128'
}
</script>
组件上的ref就是获取组件实例
打印获取到的发现获取不到身上的值,还需要一个属性defineExpose公开要给看到的值