VUE3开发使用总结
平时使用的主要是vue3技术栈,平时使用的时候其实有时候还是有些方法不大熟练,需要去寻找想对应的vue3写法,于是就整理了一些平时在论坛或者其他地方总结性的文章,方便平时自己查找APi的方法
一:常用组合式API🔥
// 下面的写法 所有的变量和方法都需要最后在return出去,否则不会编译,其实我平时到时不怎么使用return的写法感觉很麻烦 各有所爱吧
<script>
export default {
name: 'App',
setup(){
let name = 'vue3'
//方法
function say(){
}
//返回一个对象
return {
name,
say
}
}
}
</script>
如果不喜欢经常return可以使用 vue3新语法糖 <script setup>
属性和方法无需挂载到对象上后再次返回, 好几套系统使用的都是这个语法 挺顺手的,推荐一下
<template>
<div>
<Foo />
<h2 @click="increment">{{ count }}</h2>
</div>
</template>
<script setup>
import { ref } from 'vue'
import Foo from './components/Foo.vue'
const count = ref(0)
const increment = () => count.value++
</script>
- 定义组件的name: 用单独的script块来定义
<script>
export default {
name: 'ComponentName',
}
</script>
- 对await的支持: 不必再配合 async 就可以直接使用 await 了,这种情况下,组件的 setup 会自动变成 async setup 。
<script setup>
const post = await fetch('/api').then(() => {})
</script>
- setup在beforeCreate,created前,它里面的this打印出来是undefined
- 使用 setup 函数时,它将接收两个参数:
- props
- context
context用法// props import { toRef } from 'vue' setup(props) { const title = toRef(props, 'title') console.log(title.value) }export default { setup(props, context) { // Attribute (非响应式对象,等同于 $attrs) console.log(context.attrs) // 插槽 (非响应式对象,等同于 $slots) console.log(context.slots) // 触发事件 (方法,等同于 $emit) console.log(context.emit) // 暴露公共 property (函数) console.log(context.expose) } }
二: ref和reactive
######ref的一般使用方法:
- ref用来定义:[基本类型数据]。
- ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value。
<template>
<h1>姓名:{{name}}</h1>
</template>
<script setup>
import {ref} from 'vue'
let name = ref('vue3')
//方法 在修改的时候要.value去修改
function say(){
name.value = 'ref'
}
</script>
######reactive的一般使用方法
- reactive用来定义:[对象或数组类型数据]。
- reactive定义的数据:操作数据与读取数据:均不需要.value。
- reactive会变成Proxy,而且它是进行的一个深层次的响应式,也可以进行数组的响应式
<template>
<h1>姓名:{{d.name}}</h1>
</template>
<script setup>
import {reactive} from 'vue'
let d = reactive({
name: 'vue3'
})
//方法
function say(){
d.name = 'ref'
}
</script>
三: computed,watch与watchEffect
vue3中 computed,watch,watchEffect都变成了组合式API
computed
import { computed } from "vue";
const options = computed(() => {});
watch
import { watch } from "vue";
let num=ref('0')
watch(num,(newValue,oldValue)=>{
console.log(newValue,oldValue)
}),{immediate:true,deep:true})
// {immediate:true,deep:true})根据实际需求填写
当我们监视的不是reactive定义的响应式数据的全部属性,是只监听其中的一个属性
watch(()=>names.age,(newValue,oldValue)=>{
console.log(newValue,oldValue)
})
如果需要监听多个属性可以用一下写法,懒人的话可以多复制写多个watch(我就是懒人)
watch([()=>names.age,()=>names.familyName],(newValue,oldValue)=>{
console.log(newValue,oldValue)
})
watchEffect
watchEffect是vue3的新函数 默认自动开启immediate:true,ps:好吧我基本没用过但是都是大佬总结性的东西 也说不定就用上了 所以先写着吧 留着以后用
watchEffect(()=>{
const name = d.name
console.log('watchEffect')
})
四: vue3生命周期
发现用了这么久vue,vue2的生命周期背的滚瓜乱熟的,vue3的用了快一年还是没背熟,是不是要去面试一下才记得住,(只有面试才能逼急了记住,摸鱼太久什么都不会了)
在vue3中,beforeCreate与created并没有组合式API中,setup就相当于这两个生命周期函数 其他的生命周期在setup里面应该这样写
. beforeCreate => 不使用*
. created => 不使用*
. beforeMount => onBeforeMount
. mounted => onMounted
. beforeUpdate => onBeforeUpdate
. updated => onUpdated
. beforeUnmount=> onBeforeUnmount
. unmounted => onUnmounted
五: Store
也是相比于vue2方便了很多,感觉还是vue3的使用起来更好用,个人见解
import { useStore } from 'vuex'
const store = useStore()
// 在 computed 函数中访问一个 state
const count = computed(() => store.state.count),
// 在 computed 函数中访问一个 getter
const count = computed(() => store.getters.double)
// 访问一个 mutation
increment: () => store.commit('increment'),
// 访问一个 action
asyncIncrement: () => store.dispatch('asyncIncrement')
六: Router
router的使用 route和router总是打错 果然我是菜鸟
import { useRouter,useRoute } from 'vue-router'
const router = useRouter()
const route = useRoute()
// 获取url参数
console.log(route.query)
// 路由跳转
router.push({ //有参数
path:'/',
query:{
inType:1
}
})
// 监听路由变化
watch(()=>route,(newValue,oldValue)=>{
console.log(newValue,'新的路由')
console.log(newValue,'旧的路由')
})
路由导航守卫
<script setup>
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
// 添加一个导航守卫,在当前组件将要离开时触发。
onBeforeRouteLeave((to, from, next) => {
next()
})
// 添加一个导航守卫,在当前组件更新时触发。
// 在当前路由改变,但是该组件被复用时调用。
onBeforeRouteUpdate((to, from, next) => {
next()
})
</script>
七: setup的props父传子
子组件
<template>
<span>{{props.name}}</span>
// 可省略【props.】
<span>{{name}}</span>
</template>
<script setup>
// import { defineProps } from 'vue'
// defineProps在<script setup>中自动可用,无需导入
// 需在.eslintrc.js文件中【globals】下配置【defineProps: true】
// 声明props
const props = defineProps({
name: {
type: String,
default: ''
}
})
</script>
父组件
<template>
<child name='Jerry'/>
</template>
<script setup>
// 引入子组件(组件自动注册)
import child from './child.vue'
</script>
八: setup的emit子传父
子组件
<template>
<span>{{name}}</span>
<button @click='changeName'>更名</button>
</template>
<script setup>
// import { defineEmits, defineProps } from 'vue'
// defineEmits和defineProps在<script setup>中自动可用,无需导入
// 需在.eslintrc.js文件中【globals】下配置【defineEmits: true】、【defineProps: true】
// 声明props属性
const props = defineProps({
name: {
type: String,
default: ''
}
})
// 声明事件
const emit = defineEmits(['updateName'])
const changeName = () => {
// 执行
emit('updateName', 'vue3')
}
</script>
父组件
<template>
<child :name='d.name' @updateName='updateName'/>
</template>
<script setup>
import { reactive } from 'vue'
// 引入子组件
import child from './child.vue'
const d = reactive({
name: 'vue3'
})
// 接收子组件触发的方法
const updateName = (name) => {
d.name = name
}
</script>
九: 子父组件的v-model用法
子组件
<template>
<span @click="changeInfo">{{ modelValue }}:{{ age }}</span>
</template>
<script setup>
defineProps({
modelValue: String,
age: Number
})
const emit = defineEmits(['update:modelValue', 'update:age'])
const changeInfo = () => {
// 触发父组件值更新
emit('update:modelValue', 'vue3')
emit('update:age', 30)
}
</script>
父组件
<template>
// v-model:modelValue简写为v-model
// 可绑定多个v-model
<child
v-model="d.name"
v-model:age="d.age"
/>
</template>
<script setup>
import { reactive } from 'vue'
// 引入子组件
import child from './child.vue'
const d = reactive({
name: 'vue2',
age: 20
})
</script>
十: 子组件ref变量和defineExpose
- 在标准组件写法里,子组件的数据都是默认隐式暴露给父组件的,但在 script-setup 模式下,所有数据只是默认 return 给 template 使用,不会暴露到组件外,所以父组件是无法直接通过挂载 ref 变量获取子组件的数据。
- 如果要调用子组件的数据,需要先在子组件显示的暴露出来,才能够正确的拿到,这个操作,就是由 defineExpose 来完成。
子组件
<template>
<span>{{state.name}}</span>
</template>
<script setup>
import { defineExpose, reactive, toRefs } from 'vue'
const state = reactive({
name: 'Jerry'
})
// 将方法、变量暴露给父组件使用,父组件才可通过ref API拿到子组件暴露的数据
defineExpose({
// 解构state
...toRefs(state),
// 声明方法
changeName () {
state.name = 'Tom'
}
})
</script>
父组件
<template>
<child ref='childRef'/>
</template>
<script setup>
import { ref, nextTick } from 'vue'
// 引入子组件
import child from './child.vue'
// 子组件ref
const childRef = ref('childRef')
// nextTick
nextTick(() => {
// 获取子组件name
console.log(childRef.value.name)
// 执行子组件方法
childRef.value.changeName()
})
</script>
十一: CSS变量注入
<template>
<div>Jerry</div>
</template>
<script setup>
import { reactive } from 'vue'
const d = reactive({
color: 'red'
})
</script>
<style scoped>
div {
// 使用v-bind绑定state中的变量
color: v-bind('d.color');
}
</style>
十二: 全局API的转移
2.x 全局 API(Vue) 3.x 实例 API (app)
Vue.config.xxxx => app.config.xxxx
Vue.config.productionTip => 移除
Vue.component => app.component
Vue.directive => app.directive
Vue.mixin => app.mixin
Vue.use => app.use
Vue.prototype => app.config.globalProperties