vue3
创建
注意vscode插件问题:vuter只适用于vue2,vue3换成volar,重启
文件目录
组合式API
1.setup
1.在生命周期钩子之前执行,
2.时机太早,获取不到this
3.需要return数据和方法 才可以在模板中应用
可以通过setup语法糖简化代码
<script>
export default{
setup(){
const massage = "hello world"
return{
massage
}
}
}
</script>
简化
<script setup>
const massage = "hello world"
</script>
2.reactive ref
reactive 接受一个对象类型数据,返回一个响应式对象
ref 接收简单类型,或对象类型数据, 多用,返回对象
本质:在传入的数据外包了一层对象,成为复杂类型,再借助reactive实现响应式
**注意:script中返回的数据必须用 .value取其值
<script setup>
import {reactive} from 'vue'
const state = reactive({
count:100
})
const setCount = ()=>{
state.count++
}
</script>
<template>
<div>
<div>
{{state.count}}
</div>
<button @click='setCount'>
+1
</button>
</div>
</template>
<script setup>
import {ref} from 'vue'
const count = ref(0)
const setCount = ()=>{
count.value++
}
</script>
<template>
<div>
<div>
{{count}} //js中需要通过 .value获取数据,template中不用
</div>
<button @click='setCount'>
+1
</button>
</div>
</template>
3.computed
计算属性,应只包含数据的计算。
只读写法
const count = ref(1)
const plusOne = computed(()=>count.value +1)
log一下plusOne打印2
4.watch
需要导入,对简单数据进行监视,复杂类型(对象)监视不到变化,因为对象地址没变
import {watch} from 'vue'
//单个数据
watch(ref对象,(newValue,oldValue) =>{......},{
immediate:true,
deep:true
})
//多个数据
watch([ref对象1,2],(newArr,oldArr) =>{......})
immediate:true一进页面立即执行
immediate:true
deep:true 深层监视
精确监听对象的某个属性
watch(()=>ref对象.value.数据名,(newValue,oldValue) =>{......})
5.生命周期
写成函数形式可以调用多次,不会冲突
beroreCreate/create 写在 setup
beroreMounted 写在 onBeroreUnmount
mounted 写在 onMounted
其他+on即可
6.父子通信
局部组件,导入就能用
父传子:给子组件,添加属性方式传值;在子组件,通过props接收
子传父: 在子组件,emit触发事件;在父组件,通过@监听
<script setup>
import {ref} from 'vue'
import SonCom from .....
const money = ref(100)
const changeFn = (newMoney)=>{
money.value = newMoney
}
</script>
<template>
<div>
<SonCom
car="给子组件传值"
:money="money">
@changeMoney="changeFn"
</SonCom>
</div>
</template>
<script setup>
const props = defineProps({
car:String,
money:Number
})
//2.接收父组件数据
console.log(props.car)
//子传父 ,宏里传数组 ,声明方法,再触发
const emit = defineEmits(['changeMoney'])
const buy = ()=>{
emit('changMoney',5)
}
</script>
<template>
<div>
{{car}} - {{money}}
<button @click="buy">
111花钱
</button>
</div>
</template>
7.模板引用
时机:组件渲染完成
1.生成ref’对象
2.通过ref标识绑定ref对象
<script>
import {ref,onMounted} from 'vue'
const com = ref(null)
console.log(inp)//挂载未完成,获取不到元素
onMounted(()=>{
console.log(inp)//挂载完成后才能绑定上
})
const focusFn = ()=>{
inp.value.focus()//此时button已经渲染完成
}
</script>
<template>
<div>
<input ref="com" type="text">
<button @click="focusFn">
点击使输入框对焦
</button>
</div>
</template>
在外部想要拿到组件信息,需要通过宏函数defineExpose({对象,对象…})
8.provide和inject
需要引入
顶层组件向任意底层组件传递数据和方法 ,响应式数据
顶层组件提供数据,方法
provide('key',组件数据)
provide('key',(newCount)=>{
count.value = newCount
})
底层组件接收数据
const message = inject('key')
defineOptions
vue3.3以上可用(加上setup无法在script里面提供平级方法)
定义一些配置:组件名name
defineOptions({
name:
})
defineModel
//在vite.config.js文件中
plugins:[
vue({
script:{
defineModel:true
}
})
]
之后重启一下npm run dev
父组件 v-model
<script setup>
import MyInput from '@/......'
import {ref} from 'vue'
const txt = ref('123456')
</script>
<template>
<MyInput v-model="txt"></MyInput>
</template>
子组件,通过defineModel接收,可以直接同步响应式数据你
<script setup>
import {defineModel} from 'vue'
const modelValue = defineModel()
</script>
<template>
<input
type="text"
:value="modelValue"
@input="e => modelValue = e.target.value"
>
</template>
Pinan
https://pinia.vuejs.org/zh/
状态管理工具,vuex的替代品,官方推荐
去掉mutation,action既可修改数据又可以异步操作
创建时勾选pinan选项
如要手动添加,则去vue3官网看文档
getters:基于数据派生的计算属性,用computed声明
//定义模块
import {defineStore} from 'pinia'
import {ref} from 'vue'
//定义模块名
export const useStore = defineStore('仓库唯一标识',()=>{
//声明数据
const count = ref(100)
//声明方法
const addCount = () => count.value++
//getters属性
const double = computed(() => count.value * 2)
return {
count,
addCount,
double
},
{
//第三个参数写持久化选项,刷新后修改的数据还在(默认)
presist : true
//或者
presist :{
key:'...',
paths:['...','']
}
}
})
<script setup>
import { useStore } from '@/store/....'
const data = useStore()
</script>
<template>
{{data.count}}
<button @click="useStore.addCount">
+
</button>
</template>
在子组件直接解构父组件对象,会失去响应性
store是一个用reactive包装的对象,解构相当于声明新变量,从对象取出一个值存在新变量中,与原来的响应式数据无关
方法可以直接解构
解决方法
import {storeToRefs} from 'pinia'
const store = useStore(
const {data,name} =storeToRefs(store)
const {addCount} = store
也可以store.属性名/方法名 属性方法使用不多时
持久化插件pinia-plugin-presistedstate
用时网上找教程
其他配置:key(默认为仓库唯一标识,可以自己改) storage paths(指定store中哪些数据需要持久化)