vue3使用笔记

251 阅读4分钟

VUE3开发使用总结

平时使用的主要是vue3技术栈,平时使用的时候其实有时候还是有些方法不大熟练,需要去寻找想对应的vue3写法,于是就整理了一些平时在论坛或者其他地方总结性的文章,方便平时自己查找APi的方法

一:常用组合式API🔥

setup函数是CompositionAPI(组合API)的入口\color{#146eff}{setup函数是 Composition 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>

setup使用需要注意的问题\color{red}{setup使用需要注意的问题}

  • 定义组件的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
    // props
      import { toRef } from 'vue'
      setup(props) {
        const title = toRef(props, 'title')
        console.log(title.value)
      }
    
    context用法
      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

RUNOOB 图标

五: 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 全局 APIVue3.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