基本使用:setup写在标签script上,script setup 标签中无需return 变量、函数
注意:使用setup时就忘记vue2中的 this 吧 setup中不需要this就能直接使用变量或方法
1:组件的使用,直接import后无需在components注册就能使用
//父级页面
<script setup lang="ts">//这里setup写在script标签中,使用ts直接写lang="ts"
import HelloWorld from '@/components/HelloWorld.vue'//这里直接引入 无需注册
//这里使用了setup语法糖后 也不需要 return 返回
</script>
<template>
<HelloWorld />//这里可以直接使用了
</template>
2:语法糖中变量,函数的定义和使用
//父级页面
<script setup lang="ts">
//先引入 ref,reactive 方法
import { ref,reactive } from 'vue';
//定义变量的两种方法 ref 和 reactive
//ref主要定义基本数据类型如:number string 等
let a = ref('abc')
//script中需a.value 获取ref的值
// reactive主要定义引入数据类型:对象 数组和基本数据类型 number string 等
let obj = reactive({
num:100,
str:'abcd',
obj:{num:10},
list:[{a:1}]
})
//函数的定义和使用
function getFun(){
console.log(a.value)//ref定义的值使用需要a.value获取
}
const getBox = ()=>{
console.log(obj.num)
}
getFun()//直接调用函数方法
getBox()
</script>
<template>
<h1>{{a}}</h1>//template中可以直接使用无需a.value
<h1>{{obj.num}}</h1>
</template>
3:onMounted,nextTick 方法的使用
//父级页面
<script setup lang="ts">
//先引入onMounted ,nextTick 方法在使用
import { ref,reactive,onMounted ,nextTick } from 'vue';
let name = ref('张三')
let obj:any = reactive({
num:100,
})
//函数的定义和使用
function getFun(){
console.log(name.value)
}
//生命周期函数 等待页面加载完成后执行和vue2中mounted一样
onMounted(()=>{
getFun()//等待页面加载完成后调用方法
})
// vue2方法一样 等待页面加载完毕后执行
nextTick(()=>{
getFun()//等待页面加载完成后调用方法
})
</script>
<template>
<h1>{{obj.num}}</h1>
</template>
4:数据监听方法 watchEffect ,watch 的使用
//父级页面
<script setup lang="ts">
//先引入watchEffect ,watch 方法在使用
import { ref,reactive,watchEffect ,watch } from 'vue';
let name = ref('张三')
let obj:any = reactive({
num:100,
})
//watchEffect 和watch 都是事件监听方法
//watch可以监听新旧属性
//name是需要监听的ref的变量值,默认不执行只有name的值发生改变才会执行方法
watch(name, (newValue,oldValue)=>{
console.log(newValue,oldValue);
})
//监听引用类型reactive的时候如下
//多个属性使用数组[() => obj.num, () => obj.num2]
watch(()=>obj.num, (newValue,oldValue)=>{//obj.num是需要监听的reactive的变量值
console.log(newValue,oldValue);
},{ //深度监听
immediate: true,
deep: true
})
//watchEffect不用直接指定要监听的数据,使用的那些响应式数据就监听那些响应式数据
watchEffect(()=>{//vue3中新增的监听方法,初始化就会执行一次,
console.log(name);
console.log(obj.num);
})
</script>
<template>
<h1>{{obj.num}}</h1>
</template>
5:路由的使用
//router.ts页面--------------------------------------
import { createRouter , createWebHashHistory } from 'vue-router'
const router = createRouter({
history:createWebHashHistory(), // history 模式则使用 createWebHistory()
routes:[//路由信息
{ path: '/', name: '', component: () => import('./views/A.vue')},
{ path: '/A', name: 'A', component: () => import('./views/A.vue')},
{ path: '/B', name: 'B', component: () => import('./views/B.vue')}
]
})
//路由守卫拦截
router.beforeEach((to,from,next)=>{
console.log(1111,to,from);
if(to.path == "/B"){
console.log('B页面');
next()
//next({ name: 'login' }) 不满足条件跳转到登录页面
}else{
next()
}
})
//导出路由
export default router
//main.ts页面--------------------------------------
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'//路由
createApp(App).use(router).mount('#app')//挂载路由
//A页面--------------------------------------
<script setup lang="ts">
//先引入路由方法 useRouter
import { useRouter } from 'vue-router'
let router = useRouter()//路由跳转方法
function toB(){
router.push({
path:'/B',
query:{userName:'张三'}//
})
//这里是params 方式传参 只能用name不能用path
//注意:这种方式有可能获取不到params 传参值 推荐使用query
//router.push({ name: 'B', params: { id: 123 } })
}
</script>
<template>
<button @click="toB">跳转到B页面</button>
</template>
//B页面--------------------------------------
<script setup lang="ts">
//先引入路由方法 useRoute
import { useRoute } from 'vue-router'
let route = useRoute()//获取路由传参方法
console.log(route.query)//输出路由传递的参数信息
</script>
<template>
<p>{{route.query}}</p>
<button @click="toA">跳转到A页面</button>
</template>
6:父传子数据props
//父级页面
<script setup lang="ts">
import HelloWorld from '@/components/HelloWorld.vue'
import { ref,reactive } from 'vue';
let name = ref('张三')
let obj:any = reactive({
num:100,
})
</script>
<template>
<HelloWorld :msg="obj.num" />//这里传参
</template>
//子级页面
<script setup lang="ts">
// props方法使用
const props = defineProps({//defineProps为setup语法糖中props的替代方案
msg: {
type: String
}
})
//const props = defineProps(['msg','dd']) //多个参数使用数组
</script>
<template>
<h1>{{msg}}</h1>
</template>
7:子传父(子组件调用父组件中定义的函数方法) emit
//父级页面
<script setup lang="ts">
import HelloWorld from '@/components/HelloWorld.vue'
function toSun(val:any){//子组件调用的父级方法
console.log(val)//子组件传的值
//这可以调用父组件中的方法 比如刷新页面数据初始化页面等
}
</script>
<template>
<HelloWorld @toSun="toSun" />//这里接收子传父的方法
</template>
//子级页面------------------------------------
<script setup lang="ts">
// emit方法使用
const emit = defineEmits(["toSun"]);//多个使用逗号分隔//defineEmits为setup语法糖中emit的替代方案
function onClickButton(){
//触发父组件中暴露的toSun方法并携带数据
emit("toSun",'我是子组件');
}
</script>
<template>
<button @click="onClickButton">子组件调用父组件方法</button>
</template>
8:父组件调用子组件中的属性或者函数方法
//子级页面 首先暴露出可供父组件使用的属性和方法 defineExpose
<script setup lang="ts">
import { ref,reactive } from 'vue';
let name = ref('张三')
function sunFun(val:any){
console.log('子级方法',val)//可接收参数
}
// 暴露出去方法给父级调用
defineExpose({ sunFun, name })
</script>
//父级页面 ------------------------------------
<script setup lang="ts">
import HelloWorld from '@/components/HelloWorld.vue'
import { ref,reactive,getCurrentInstance} from 'vue';
const data = reactive({
num:'1'
})
//页面加载完成后获取
nextTick(()=>{
data.num = childRef.value.name//这里直接获取数据name
})
//第一种方法
const childRef= ref() //注册响应数据
function getChildData(){//子组件调用的父级方法
console.log(childRef.value.name )//获取子组件暴露的数据name
childRef.value.sunFun(2)//调用子组件暴露出来的方法并可以传参
}
//第二种方法 getCurrentInstance //相当于创建了个this 但是不能滥用
let currentInstance:any = getCurrentInstance()
function getChildData(){
currentInstance.ctx.$refs.childRef.sunFun(333)
}
</script>
<template>
<HelloWorld ref='childRef' />//组件绑定模板ref
<button @click='getChildData'>通过ref获取子组件的属性 </button>
</template>
9:Hooks 函数
在目录src下新建文件夹 hooks ==> index.ts
// index.ts页面 定义公用的方法和属性 并导出
import {ref} from 'vue'
export function addNum(n:any,m:any){
console.log(n+m)
}
export const xxx = 11000
//使用的页面 父级页面 ------------------------------------
<script setup lang="ts">
import {ref,onMounted} from 'vue'
// hooks方法
import {addNum,xxx} from '../hooks/index'//引入hooks方法
onMounted(()=>{
addNum(10,20)//使用hooks方法
cosnole.log(xxx)//获取hooks属性xxx
})
function hooksFun(){
addNum(10,20)//使用hooks方法
data.msg = xxx.toString()//使用hooks属性
}
</script>
<template>
<button @click="hooksFun">hooks方法的使用</button>
</template>
10:Provide(提供) / Inject (注入)
vue提供了provide和inject帮助我们解决多层次嵌套通信问题
//父页面
<script setup lang="ts">
import {ref,provide } from 'vue'
provide('name', '张三') // 单个提供的形式
// 多个提供的形式
provide('status', {
age: 18,
name: '李四',
})
</script>
<template>
</template>
//子页面-----------------
//孙级页面------------
<script setup lang="ts">
import { inject} from 'vue'
const name = inject('name')//接收name数据
const status= inject('status')//接收status对象数据
</script>
<template>
<div>name:{{name}},status:{{status}}</div>
</template>
11:状态管理 pinia
详情见另一篇文章
https://blog.csdn.net/weixin_45547638/article/details/127070911?spm=1001.2014.3001.5502