# Vue3 语法变化

# vue3 配置项

# 1.vue.config.js

module.exports = {
  devServer: {
	port: 80,								// 程序启动端口
    open: true,								// 启动是是否主动打开界面
    proxy: 'http://localhost:4000',			// 指向开发环境 API 服务器,任何未知请求代理到此地址
  }
}

# 2.Vue-router 配置

import {createRouter,createWebHistory} from "vue-router";
import Demo01 from "../components/Demo01";
const  routes = [
    {path: '/demo',component: Demo01},
]
export default createRouter({
    history: createWebHistory(),		//history 模式路径中没有 #
    //history: createWebHashHistory (),	hash 模式路径中含有#
    routes
})

# 3.Vue 对象实例化

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const  app = createApp(App)
app.use(router)
app.mount('#app')

# 4.npm 常用命令

  1. 查看 vue 最新版本 npm list vue
  2. 升级 vue 版本 npm install vue@next --save
  3. 升级 vue-router 版本 npm install vue-router@next --save
  4. 查找模块 : npm search moduleName
  5. 安装最新模块 : npm istall moduleName@latest
  6. 卸载模块 : npm uninstall moduleName
  7. 清除 npm 缓存 : npm cache clean --force
  8. 打开模块文档 : npm docs moduleName
  9. 常用参数:
    • @next npm 上的可用最新版本
    • --save 运行时依赖
    • --save-dev 开发时依赖

# Node 17.+

启动参数变化

//    "serve": "vue-cli-service serve",
//    "build": "vue-cli-service build",

# vue3 + TypeScript

# 1.vue-router

# 1. 创建并使用 vue-router

// 声明创建路由参数列表
const routes: Array<RouteRecordRaw> = [
    {
        path: '/'
    }
]
// 创建路由
const router = createRouter({
  history: createWebHashHistory(process.env.BASE_URL), 	//webHash 路由
  history: createWebHistory(process.env.BASE_URL)		// 普通路由
  routes
})
export default router

# 2. 路由信息对象: route

route 对象属性

属性名类型释义
pathstring当前路由路径 <解析为绝对路径>
paramsobject动态片段和全匹配片段,无查询参数则为空
hashstring当前路由的 hash 值
fullPathstring解析后的 URL, 含查询参数和 hash 路径
matchedArray<RouteRecord>当前路由所有前台路径片段的路由记录 (routes 中的对象)
namestring当前路由名称
redirectedFromstring重定向来源路由名称
metastring路由元信息

setUp 模式下获取 route 对象

// 1. 从当前实例中获取路由信息对象
const route = getCurrentInstance()?.proxy?.$route
// 2. useRoute () 函数
const route  = useRoute()

# 3. 全局路由实例: router

router 路由实属性

属性名类型释义
app配置了 router 的 Vue 根实例
modestring路由使用的模式
currentRouteRoute当前路由的路由信息对象
START_LOCATIONRoute初始路由地址

router 实例方法

方法名方法签名作用
beforeEachrouter.beforeEach ((to, from, next) => <br />{/* 必须调用 next */})全局前置守卫
beforeResolverouter.beforeResolve ((to, from, next) => <br />{/* 必须调用 next */})全局解析守卫
afterEachrouter.afterEach((to, from) => {})全局后置钩子
pushrouter.push(location)<br />.then(onComplete).catch(onAbort)路由到新路由
replacerouter.replace(location)<br />.then(onComplete).catch(onAbort)替换当前路由,history 不会添加新记录
gorouter.go(n)history 变化 n 步
backrouter.back()history 回退一步
forwardrouter.forward()history 前进一步
getMatchedComponentsconst matchedComponents: Array<Component> = router.getMatchedComponents(location?)返回目标位置,或当前路由匹配的组件数组
resolveconst resolved: {<br /> location: Location;<br /> route: Route;<br /> href: string;<br />} = router.resolve(location, current?, append?)解析目标位置
addRouteaddRoute(route: RouteConfig): ()=>void添加一条路由规则,相同则覆盖
addRouteaddRoute(parentName: string,route: RouteConfig): ()=> void添加一条现有路由的子路由
getRoutesgetRoutes(): RouteRecord[]获取活跃路由记录列表
onReadyrouter.onReady(callback,[errorCallback])callback: 路由初始化回调 <br />errorCallback: 初始化路由出错时回调
onErrorrouter.onError(callback)注册一个路由出错时的回调

setup 模式下获取 router 实例

// 1. 从当前实例中获取路由实例
const router = getCurrentInstance()?.proxy?.$router
// 2. useRouter 函数
const router = useRouter()
// 路由参数传递 
// 方式一:  name: 路由名称 + params 路由参数		(参数不在 url 中显示)
router.push({name:'echartsMap',params:{id:10001,name:'从主页跳转的路由'}})
// 方式二: path: 路由路径 + query 查询参数			(参数在 url 中显示)
router.push({path:'/echarts/province',query:{id:10001,name:'从主页跳转的路由'}})

# vue3 组合式 API

# 1.setup 函数

<script>
export default {
    setup(){
        const res = 'str'
        const arr = [1, 3, 5, 7, 9]
        const func = ()=>{
            ...
        }
        // setUp中的数据,方法 必须导出才可以使用
        return {res, arr, func}
    }
}
</script>

# 2.ref 响应式数据

  • ref 创建一个响应式的对象 ref(val)
  • 当 ref 中的值发生改变时,视图层会自动更新
  • ref 可操作基本数据类型,也可以操作复杂数据类型:对象,数组
  • 默认: ref 默认用于操作基本数据类型:数字,字符串

# 3.reactive 响应式引用

  • reactive 为传入值创建一个响应式的引用 reactive({ data: {code: 200}})
  • 定义基本数据类型 只能 使用 ref
  • reactive 主要定义复杂数据类型, <数组,对象>
  • reactive 可响应深层次的数据,<多维数组>
  • reactive 返回一个响应式的 proxy 对象

# 4.toRef 介绍

  • toRef 创建一个响应式的数据
  • ref 本质是拷贝粘贴一份数据,脱离了原数据的交互
  • ref 函数将对象中的属性变成响应式的数据,修改响应式数据 不会影响到原数据,但是会更新视图层
  • toRef 本质是引用,与原数据有交互,修改响应式数据会影响到原数据,但是 不会更新视图层
  • toRef 接收两个参数,第一个参数是要操作的对象,第二个参数是对象的某个属性
import {toRef} from 'vue'
const obj = {name: 'user'}
toRef(obj,'name')

# 5.toRefs 介绍

  • 用于批量设置多个数据为响应式数据 toRefs(obj)
  • toRefs 与原始数据有交互,修改响应式数据会影响到原数据,但是不会更新视图层
  • toRefs 还可以与其他响应式函数交互,更加方便处理视图层数据

# 6.computed 计算属性

  • 监听数据变化,并进行联动改变
const num1,num2 = 0
const res = reactive({num1,num2})
const sum = computed(()=>{
    return res.num1 + res.num2
})

# 7.watch 侦听器

  • 用于侦听数据变化
<script>
    const p1 = ref(0)
    const p2 = ref(0)
    const p3 = reactive({
        name: '',
        age: {
            num: 1
        }
    })
一: 监听一个 ref数据变化
	watch(p1,(newVal,oldVal)=>{
        // oldVal: 变化前的数据  newVal: 变化后的数据
        console.log(newVal,oldVal)
    })
二: 监听多个 ref的数据变化
	watch([p1,p2],(newVal,oldVal)=>{
        console.log(newVal,oldVal)
    })
三: 监听整个 reactive响应式数据变化 
	// 只能监听到最新的结果,上一次的数据无法监听
	watch(p3,(newVal,oldVal)=>{
        console.log(newVal,oldVal)
    })
四: 监听 reactive响应式数据中某一个值的变化
	/**
	* 变化前后的结果都可以得到
	* {immediate: true}: 页面挂载完成立即开启监听
	*/
	watch(()=>p3.age.num,(newVal,oldVal)=>{
        console.log(newVal,oldVal)
    },{immediate: true})
</script>	

# 8. watchEffect

  • watchEffect 在组件初始化的时候就会执行一次用以收集依赖

  • watch 可以获取新值与旧值 (更新前后的值), 而 watchEffect 中拿不到

  • watchEffect 不需要指定监听的属性,会自动收集依赖,

    只要回调中引用了响应式属性,当属性变更时,这个回调都会执行,

    watch 只监听指定的属性而做出变更

const p1 = ref(0)
const p2 = reactive({
    name: 'name',
    age: {
		num: 1
    }
})
const res = watchEffect(()=>{
    const temp = p1.value
    const b = p3.age.num
    console.log(a,b)
})
// 调用一次监听函数即可 停止监听
res()

# 9. shallowRef 和 shallowReactive

  • shallowRef 只处理基本数据类型 (string, boolean, number, arr)
  • shallowReactive 只处理第一层数据 (无法处理对象中深层嵌套属性)
/* 以下两种方式均无法触发响应式数据效果 */
//shallowReactive: 只处理对象的第一层属性
const p1 = shallowReactive({
    name: 'name',
    product: {
        money: 10
    }
})
//shallowRef: 只处理基本数据类型
const p2 = shallowRef({
    val: 1
})
return {...toRefs(p1),p2}

# 10. 组件传值

  1. 进入页面后即刻传值 (无论组件层次结构有多深,子组件都可以通过 Inject 接收数据)

组件传值

const p1 = reactive({name:'bai',age:20})
// 父组件传 键为 key 的数据 p1
provide('key',p1)
// 所有子组件均可接收到来自父组件的数据
const res = inject('p')
  1. 点击触发传值
// 子组件
<components ref="moduleName" />
// 子组件定义供父组件传值的方法
const receive = (val) =>{ console.log(val)}
// 父组件使用子组件的方法传递数据
const moduleName = ref()
const p1 = reactive({name: 'father',data: 'defaultData'})
// 调用子组件的 receive 方法传递数据给子组件
moduleName.value.receive(p1)