一、isRef、toRef、toRefs、readonly
(1)isRef
- 判断是否为响应式变量
- 检查一个值是否是一个 ref 对象
示例:
<template>
<div>
<h3>isRef函数</h3>
<p>{{msg}}--响应式变量</p>
<button @click="changemsg">changemsg</button>
<button @click="lookmsg">lookmsg</button>
<p>{{msg1}}--非响应式变量</p>
<button @click="changemsg1">achangemsg1</button>
<button @click="lookmsg1">lookmsg1</button>
</div>
</template>
<script setup>
import { ref,isRef } from 'vue'
let msg=ref(0)
function changemsg() {
console.log(isRef(msg))
msg.value++
}
function lookmsg() {
console.log("msg的值:"+msg.value)
}
let msg1=2
function changemsg1() {
console.log(isRef(msg1))
msg1++
}
function lookmsg1() {
console.log("msg1的值:"+msg1)
}
</script>
结果显示:
(2)toRef
- 可用于为源响应对象上的属性创建 ref
- 创建的 ref 与其源属性同步:改变源属性将更新 ref
示例:
<template>
<div>
<h3>toRef</h3>
<p>obj对象:{{obj}}</p>
<p>解构赋值的结果: x:{{x}} y:{{y}}</p>
<p>响应式数据解构的结果: x:{{x1}} y:{{y1}}</p>
<button @click="changeobj">changeobj</button>
</div>
</template>
<script setup>
import { ref,isRef,reactive,toRef,toRefs } from 'vue'
function changeobj() {
x1.value++
y1.value++
console.log(x1.value)
console.log(y1.value)
x++
y++
console.log("解构赋值的x:"+x)
console.log("解构赋值的y:"+y)
}
//解构赋值可以解出单个对象 但是没有响应式功能--解构后声明的变量是普通变量
let obj=reactive({x:2,y:3})
let {x,y}=obj
// toRef解构出来拥有响应式功能---为源响应对象上的属性创建ref并响应到源对象
let x1=toRef(obj,"x")
let y1=toRef(obj,"y")
</script>
结果显示:
(3)toRefs
- 将响应式对象转换为普通对象,其中结果对象的每个属性都是指向原始对象相应属性的 ref
- 每个单独的 ref 都是使用创建的toRef()
- 响应式数据解构
示例:
<template>
<div>
<p>{{obj}}</p>
<p>{{a}}---{{b}}</p>
<button @click="changeobj">changeobj</button>
<button @click="lookobj">lookobj</button>
</div>
</template>
<script setup>
import { ref, isRef, reactive, toRef, toRefs } from "vue";
let obj = reactive({ a: 10, b: 20 });
let { a, b } = toRefs(obj);
function changeobj() {
a.value++;
b.value++;
}
function lookobj() {
console.log(a.value, obj.a);
}
</script>
结果显示:
(4)readonly
- 把数据变为只读
示例:
<template>
<div>
<h3>readonly</h3>
<p>{{obj2.age}}</p>
<button @click="changeobj">changeobj</button><br /><br />
<button @click="changeobj2">changeobj2</button><br /><br />
<button @click="lookage">lookage</button>
</div>
</template>
<script setup>
import { reactive, readonly } from "vue";
let obj = reactive({ age: 21 });
let obj2 = readonly(obj);
function changeobj() {
console.log("执行了修改obj的age属性的值的函数")
obj.age++ //obj是响应式的 obj2也是响应式的 而且关联 但obj是可读可写的 obj2是只读
}
function changeobj2() {
console.log("执行了修改obj2的age属性的值的函数")
obj2.age++ //obj是响应式的 obj2也是响应式的 而且关联 但obj是可读可写的 obj2是只读
}
function lookage() {
console.log("obj的age:"+obj.age,"obj2的age:"+obj2.age)
}
</script>
结果显示:
二、公共属性配置
- 因为vue2.0使用公共配置时一般是绑定在原型上的,无论是否使用都在每一个组件的this原型链上,这样的设计不太友好
- 所以vue3.0提供了专门公共数据配置的方式: globalProperties getCurrentInstance
在main.js中:
const app=createApp(App)
app.config.globalProperties.$globalP="公共数据"
在组件的生命周期函数中:
getCurrentInstance():获取当前组件实例对象
- 当前组件的实例对象解构的proxy对象中就有$globalpP
- 注意点是这个函数要在组件钩子中使用,不要在普通函数中使用
<script setup>
//只能在组件的钩子函数中使用,不能在普通函数中使用 否则会得到null
//调函数后得到的就是当前组件的实例对象 ci
import { getCurrentInstance, onMounted } from "vue";
let ci = getCurrentInstance();
console.log("当前组件的实例对象:",ci);
console.log("公共属性:",ci.proxy.$globalP);
onMounted(() => {
console.log(ci.proxy.$globalP,"挂载后执行的函数");
});
</script>
三、网络配置
vite环境配置代理:
export default defineConfig({
plugins: [vue()],
server: {
// port:"8080", 默认配置
// host
proxy: {
'/api': {
target: 'http://127.0.0.1:7001', // 代理的目标地址
rewrite: (path) => path.replace(/^\/api/, '/'), // 路径重写
changeOrigin: true,
// secure: true, // target是否https接口
// ws: true, // target是否代理websockets
}
}
}
})
axios配置:
在mian.js中:
import axios from "axios"
const app=createApp(App)
axios.defaults.baseURL="http://127.0.0.1:7001/api"
app.config.globalProperties.$axios=axios
app.mount('#app')
在组件.vue中:
<script setup>
import { onMounted,getCurrentInstance } from 'vue'
let {proxy}=getCurrentInstance()
onMounted(async () => {
let res=await proxy.$axios("/test1")
console.log(res)
})
</script>
四、插件配置
同vue2.0一样use函数接受一个函数或者对象(对象有install函数) 然后会调用这个传入的回调函数 给它传参app对象,以此来实现第三方插件
如将axios配置为插件:
在main.js文件中:
import { createApp} from 'vue'
import App from './App.vue'
const app=createApp(App)
import $axios from "./http/$axios.js"
app.use($axios)
app.mount('#app')
在$axios文件中:
import axios from "axios"
function $axios(app){
axios.defaults.baseURL="http://127.0.0.1:5173/api"
app.config.globalProperties.$axios=axios
}
export default $axios;
组件中就可通过获取实例对象 来获取公共属性中的 $axios的网络工具
在组件内:
//1.钩子函数中获取实例对象:
//2.获取公共属性中的数据
<script setup>
import {onMounted,getCurrentInstance} from "vue"
let {proxy}=getCurrentInstance()
onMounted(async ()=>{
let res=await proxy.$axios('/test')
// 真实请求的网址"http://127.0.0.1:5173/api/test"==>"http://127.0.0.1:7001/test"
})
</script>
五、路由配置
使用跟之前的vue2.0差不多 语法略微有变化 router-view和router-link组件不变
在main.js文件中引入路由文件
import router from "./router/index.js"
app.use(router)//记得在mount之前调用
在router/index.js文件中需要引入新的api:
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{
path: '/',
name: 'home',
component: () => import('../views/Home.vue'),
},
{
path: '/box1',
name: 'box1',
component: () => import('../views/Box1.vue'),
children:[
{
path: '/box1/box11',
name: 'box11',
component: ()=>import("../views/box11.vue")
}
]
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
在组件内部的使用:
<template>
<div>
<h2>home</h2>
<button @click="gobox1">go-box1</button>
</div>
</template>
<script setup>
import {useRouter,useRoute} from "vue-router"
let router=useRouter()
let gobox1=()=>{
let route=useRoute()
console.log(route.query)
router.push({path:"/box1/box11",query:{id:1}})
}
</script>