1.shallowRef与shallowReactive
<template>
<div class="app">
<h2>求和为:{{ sum }}</h2>
<h2>名字为:{{ person.name }}</h2>
<h2>年龄为:{{ person.age }}</h2>
<button @click="sum += 1">sum+1</button>
<button @click="updateName">修改名字u</button>
<button @click="updateAge">修改年龄</button>
<button @click="update">修改整个人</button>
<hr />
<h2>汽车名称:{{ car }}</h2>
<button @click="updateCarName">修改起床名字</button>
<button @click="updateCarColor">修改颜色</button>
<button @click="updateCar">修改整个车</button>
</div>
</template>
<script setup lang="ts" name="App">
import { ref, reactive, shallowRef, shallowReactive } from "vue";
let sum = shallowRef(0); //浅层次变成响应式 等号改变的才有响应式
let person = shallowRef({
name: "张三",
age: 18,
});
let car = shallowReactive({//只有第一层有效果,深层次无响应式
name: "宝马",
options: {
color: "红色",
engine: "V8",
},
});
function update() {
person.value = { name: "王五", age: 20 };
}
function updateName() {
person.value = { name: "王五", age: person.value.age };
}
function updateAge() {
person.value = { name: person.value.name, age: 13 };
}
function updateCar() {}
function updateCarName() {
car.name = "奔驰";
}
function updateCarColor() {
car.options.color = "red";
}
</script>
<style>
.app {
background-color: #ddd;
border-radius: 10px;
box-shadow: 0 0 10px;
padding: 10px;
}
button {
margin: 0 10px;
}
</style>
2.readonly与shallowReadonly
<template>
<div class="app">
<h2>当前求和为:{{ sum }}</h2>
<h2>当前求和为:{{ sum2 }}</h2>
<button @click="changeSum">点我加一</button>
<button @click="changeSum2">点我加一</button>
</div>
</template>
<script setup lang="ts" name="App">
import { ref, readonly,shallowReadonly } from "vue";
let sum = ref(0);
let sum2 = readonly(sum);//不仅仅能让ref不能改 reactive也不能改
console.log(sum2.value);//0
// shallowReadonly//浅层只读 第一层只读,深层可以改
function changeSum(){
sum.value += 1;
}
function changeSum2(){
sum2.value += 1;//不允许改的/Cannot assign to 'value' because it is a read-only property.
}
</script>
<style>
.app {
background-color: #ddd;
border-radius: 10px;
box-shadow: 0 0 10px;
padding: 10px;
}
button {
margin: 0 10px;
}
</style>
3.toRaw与markRaw
<template>
<div class="app">
<h2> 姓名:{{ person.name }}</h2>
<h2> 年龄:{{ person.age }}</h2>
<button @click="update1">修改响应式</button>
<button @click="update2">修改普通</button>
</div>
</template>
<script setup lang="ts" name="App">
import { ref, reactive,toRaw ,markRaw} from "vue";
let person = reactive({
name: '张三',
age: 18,
})
let p = toRaw(person);//将响应式对象变成普通对象
//markRaw 是一个对象永远变不了响应式
console.log(person);
console.log(p);//可以改,是同一个对象,改了下一次渲染模板页面也会带着它的值
function update1(){
person.name = '李四';
p.age = 20;
}
function update2(){
person.name = '王五';
p.age = 22;
}
</script>
<style>
.app {
background-color: #ddd;
border-radius: 10px;
box-shadow: 0 0 10px;
padding: 10px;
}
button {
margin: 0 10px;
}
</style>
mockjs 是模仿后端的接口
4.自定义Ref customRef
import { customRef } from "vue";
export default function(initValue:string,delay:number){
//使用Vue提供的默认ref定义
// let msg = ref('你好')
//使用Vue提供的customRef定义响应式数据
let timer:any;
//track (跟踪) trigger(触发)
let msg = customRef((track, trigger) => {
return {
//get 何时调用? --msg 被读取
get() {
track(); //告诉vue 数据msg很重要,你要对msg进行持续关注, 一旦msg变化,就去更新
return initValue;
},
//set 何时调用 ? --msg 被修改
set(value) {
clearTimeout(timer);
timer = setTimeout(() => {
initValue = value;
trigger(); //通知vue一下数据msg变化了
}, delay);
},
};
});
return {msg}
}
<template>
<div class="app">
<h2>{{ msg }}</h2>
<input type="text" v-model="msg" />
</div>
</template>
<script setup lang="ts" name="App">
import userMsgRef from './userMsgRef';
let {msg} = userMsgRef('你好',1000);
</script>
<style>
.app {
background-color: #ddd;
border-radius: 10px;
box-shadow: 0 0 10px;
padding: 10px;
}
button {
margin: 0 10px;
}
</style>
5.Vue3新组件
1.Teleport
<template>
<button @click="isShow = true">展示弹窗</button>
<!-- #app . html -->
<teleport to="body">
<!-- 传送到body下了 -->
<div class="model" v-show="isShow">
<h2>我是弹窗的标题</h2>
<p>我是弹窗的内容</p>
<button @click="isShow = false">关闭弹窗</button>
</div>
</teleport>
</template>
<script setup lang="ts" name="Model">
import { ref } from "vue";
let isShow = ref(false);
</script>
<style lang="css" scoped>
.model {
width: 200px;
height: 150px;
background-color: skyblue;
border-radius: 10px;
padding: 5px;
box-shadow: 0 0 5px;
text-align: center;
position: fixed;
left: 50%;
margin-left: -100px;
top: 20px;
}
</style>
<template>
<div class="outer">
<h2>我是App组件</h2>
<img src="https://tse1-mm.cn.bing.net/th/id/OIP-C.Zte3ljd4g6kqrWWyg-8fhAHaEo?w=303&h=189&c=7&r=0&o=5&pid=1.7" alt="">
<br>
<Model/>
</div>
</template>
<script setup lang="ts" name="App">
import Model from './Model.vue';
</script>
<style scoped>
.outer {
background-color: #ddd;
border-radius: 10px;
box-shadow: 0 0 10px;
padding: 10px;
width: 400px;
height: 400px;
/**饱和度滤镜 */
filter: saturate(200%);
}
img {
width: 270px;
}
</style>
2.Suspense
推荐这个开放Api网站
<template>
<div class="app">
<h2>我是App组件</h2>
<Suspense>
<template #default>
<!-- 异步任务做完的时候出现 -->
<Child/>
</template>
<template #fallback>
<!-- 异步任务没有做完的时候出现 -->
<div>加载中...</div>
</template>
</Suspense>
</div>
</template>
<script setup lang="ts" name="App">
import { Suspense } from 'vue';
import Child from './Child.vue';
</script>
<style scoped>
.app {
background-color: #ddd;
border-radius: 10px;
box-shadow: 0 0 10px;
padding: 10px;
}
</style>
<template>
<div class="child">
<h2>我是Child组件</h2>
<h2>当前求和为:{{sum}}</h2>
</div>
</template>
<script setup lang="ts" name="">
import { ref } from "vue"
import axios from "axios";
let sum = ref(0);
let {data:{content}} = await axios.get('https://api.uomg.com/api/rand.qinghua')
console.log(content);
</script>
<style lang="css" scoped>
.child{
background-color: skyblue;
border-radius: 10px;
box-shadow: 0 0 10px;
padding: 10px;
}
</style>
3.全局Api转移到应用对象
Vue3 Api
app.component 定义全局组件
import {createApp} from 'vue'
import App from './App.vue'
import Hello from './Hello.vue'
// 创建应用
const app = createApp(App)
app.component('Hello',Hello)
//全局变量
app.config.globalProperties.x=99;
declare module 'vue'{
interface ComponentCustomProperties{
x:number
}
}
//全局自定义指令 v-beauty
app.directive('beauty',(element,{value})=>{
element.innerText +=value;
element.style.color='red'
element.style.backgroundColor='yellow'
})
app.mount('#app')
setTimeout(()=>{
//卸载
app.unmount()
},3000)
// 使用插件
// app.use(router)
4.其他
记得看这个
完结撒花