vue3常用api介绍和使用(上)

241 阅读6分钟

前言

若有新知识点会在这边加入的

注意:以下的知识点,并非以文档或者别人的博客为准的,只是我这边使用的场景为准,均以本人自己的学习和研究得理解出来的,如有错误或者疑问可以自行去下面的链接[vue3文档]查看或者谷歌等搜索

vue3文档

\

常用应用API

import { createApp } from 'vue'

const app = createApp({})
//调用 createApp 返回一个应用实例。该实例提供了一个应用上下文。应用实例挂载的整个组件树共享相同的上下文
app.use({Object | Function} plugin]) //实例化一个对象或者方法的插件,用法如下
app.use(List)  //以vant ui中的List组件为例,当使用此方法时,即可全局使用List组件

//注册全局组件
app.component('要使用的组件名称',被导入的组件名)

//根组件实例,将应用实例的根组件挂载在提供的 DOM 元素上。
app.mount('#app')


//在应用程序内的任何组件实例中访问的全局 property。属性名冲突时,组件的 property 将具有优先权。
import daysJs from 'dayjs'
//在vue2里面添加全局变量方式如下
Vue.prototype.daysJs=daysJs
//调用
console.log(this.daysJs)
//在vue3里面添加全局变量方式如下(限在开发环境下,生产环境建议不要使用)
app.config.globalProperties.key=()=>console.log('逻辑体')
app.config.globalProperties.daysJs = daysJs;
//调用
setup(){
const {ctx} =getCurrentInstance()
console.log(ctx.daysJs)
}

常用全局API

 //nextTick  更改了一些数据以等待 DOM 更新后立即使用它

//用法
import {nextTick} from 'vue'

await nextTick()
console.log('nextTick数据修改了')

常用新内置API

<!--teleport 指定将在其中移动 <teleport> 内容的目标元素-->
//示例
<!-- 正确 -->
<teleport to="#some-id" />
<teleport to=".some-class" />
<teleport to="[data-teleport]" />

<!-- 错误 -->
<teleport to="h1" />
<teleport to="some-string" />

<!--disabled - boolean。此可选属性可用于禁用 <teleport> 的功能,这意味着其插槽内容将不会移动到任何位置,而是在您在周围父组件中指定了 <teleport> 的位置渲染。-->
<teleport to="#popup" :disabled="displayVideoInline">
  其他模板
</teleport>

组合式 API

//setup 用于组件式api的入口 条件可以接收(0个或者最多2个参数的情况)
//注意在setup()方法前使用如下格式是不允许的,因为setup(){}函数 不属于异步操作,不能使用async这种方式去处理数据
async setup(){


}  
//示例
setup(){

  return {
  
  
  }
  
}
//当使用 setup 函数时,它将接受两个参数:
/*
1.props
2.context
*/
// props setup 函数中的 props 是响应式的,当传入新的 prop 时,它将被更新。
//注意,因为 props 是响应式的,你不能使用 ES6 解构,因为它会消除 prop 的响应性。
export default{
props:{
   list:{
     type:Array,
     default(){
         return []
     
     }
   }

},
  setup(props){
    console.log(props.list)
  return {
  
  
  }
  
}


}
//如果需要解构 prop,可以通过使用 setup 函数中的 toRefs 来完成此操作
import { toRefs } from 'vue'
export default{
props:{
   list:{
     type:Array,
     default(){
         return []
     
     }
   }

},
  setup(props){
    const {list} = toRefs(props)
    console.log(list.value)
  return {
  
  
  }
  
}


}

//传递给 setup 函数的第二个参数是 context。context 是一个普通的 JavaScript 对象,它暴露组件的三个 property:
  setup(props,context){
  // Attribute (非响应式对象)
    console.log(context.attrs)

    // 插槽 (非响应式对象)
    console.log(context.slots)

    // 触发事件 (方法)
    console.log(context.emit)
    
    //解构方式
    const {emit,slots,attrs} = context
  return {
  }
  
}


//

生命周期钩子

import { onActivated,onDeactivated,onErrorCaptured
,onBeforeMount, onRenderTracked, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onRenderTriggered }

setup() {
onBeforeMount(()=>{
console.log('在挂载开始之前被调用:相关的 render 函数首次被调用。')

})
  //例子
  onBeforeMount(()=>{
     horizontalBsScroll = null
   })
onRenderTracked(()=>{
console.log('是render函数首次被重新调用时触发')
})
  onRenderTriggered(()=>{
console.log('是render函数被重新调用时触发')
})
  onMounted(()=>{
  console.log('组件挂载完成后执行的函数')
  
  })
  //例子
  onMounted(async ()=>{
    await  调用接口方法()
  
  })
  onBeforeUpdate(()=>{
    console.log('组件更新之前执行的函数。')
  
  })
  onUpdated(()=>{
     console.log('组件更新完成之后执行的函数')
  })
  onBeforeUnmount(()=>{
     console.log('组件卸载之前执行的函数')
  
  })
  onUnmounted(()=>{
   console.log('组件卸载完成后执行的函数')
  
  })
  //例子
  onUnmounted(()=>{
    horizontalBsScroll.destroy()
  })
  onActivated(()=>{
    console.log('被包含在中的组件,会多出两个生命周期钩子函数。被激活时执行')
  })
  onDeactivated(()=>{
   console.log('比如从 A 组件,切换到 B 组件,A 组件消失时执行。')
  
  })
  onErrorCaptured(()=>{
   console.log(' 当捕获一个来自子孙组件的异常时激活钩子函数)')
  })
}

响应式 API

//reactive 返回对象的响应式副本
//例子
const  obj = reactive({
list:[],
data:{}
})

//ref 接受一个内部值并返回一个响应式且可变的 ref 对象

const  count = ref(0)
console.log(count.value) // 0
//注意:在模板中使用ref变量时,无需带上.value方式,因为vue底层已经处理了模块中.value问题,可以直接使用如下
{{count}}
//如果在js中使用,需要加上.value这个进行相应的操作
count.value++
//若要处理refs这种情况,需要如下的情况
//首先先在模板中创建一个名字
<div ref="div"></div>
//在js中使用
setup(){
const div=ref(null)
 onMounted(()=>{
    console.log(div.value)
  })
return {
div
}

}

//Computed
//接受一个 getter 函数,并为从 getter 返回的值返回一个不变的响应式 ref 对象。
//例子
 const dayTime = computed(()=>{
      const d=new Date()
      return d.getDate()
    })
//是否禁用按钮
    const isDisabled = computed(()=>(password.value.length)?false:true)
//watch
//侦听一个单一源
//监听切换的状态
    watch(artis, (count, prevCount) => {
      console.log(count,prevCount)
    })
//侦听多个源
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
     console.log('返回的数据结果')
})

hooks的使用(直接以几个例子解释)

//创建hooks的示例
import {onMounted, ref, onUnmounted, watch,onBeforeMount ,nextTick,onUpdated,reactive }  from'vue'
import BScroll from 'better-scroll'
 function horizontalHooksBsScroll(){
  const horizontalScroll = ref(null)
  let horizontalBsScroll = null

   onBeforeMount(()=>{
     horizontalBsScroll = null
   })

  onUnmounted(()=>{
    horizontalBsScroll.destroy()
  })
  onMounted(()=> {
    horizontalBsScroll = new BScroll(horizontalScroll.value, {
      scrollX: true,
      probeType: 3,
      click: true
    })

   return  _registerHooks(['scroll','scrollEnd'], (pos) => {
      console.log(pos,'done')
    })
  })
   onUpdated(async()=>{
     await nextTick()
     bsRefresh()
   })
   watch(horizontalScroll,()=>{
     bsRefresh()
   })
   const _registerHooks = (hookNames, handler)=>{
     hookNames.forEach((name) => {
       horizontalBsScroll.on(name, handler)
     })
   }
   //页面加载,去重置
   function bsRefresh(){
     horizontalBsScroll.refresh()
   }

   return horizontalScroll
}
export  default horizontalHooksBsScroll
//调用(a.vue)
import horizontalHooksBsScroll from './hooks/useHorizontalScroll'
setup(){
const horizontalScroll = horizontalHooksBsScroll()

return {
  horizontalScroll
}
}
//videoHooks.js
import {ref,reactive,onMounted,computed,nextTick,onUnmounted} from 'vue'
import {useRoute} from 'vue-router'
let audioInterval;

function realFormatSecond(second) {
  const secondType = typeof second
  if (secondType === 'number' || secondType === 'string') {
    second = parseInt(second)
    // var hours = Math.floor(second / 3600)
    // second = second - hours * 3600
    const _second = second
    var mimute = Math.floor(second / 60)
    const a_second = _second - mimute * 60
    return ('0' + mimute).slice(-2) + ':' + ('0' + a_second).slice(-2)
  } else {
    return '00:00'
  }
}

const videoMvHooks = ()=>{
  const route = useRoute()
  const videoRefPlay = ref(null) //操作时
  const detail =reactive({
    url:'', //要播放的mv地址
    data:{},//其他消息
    info:{},//转的数据
  })
  const videoData =reactive({
    audioTime:0,//音频进度百分比
    audioCurrentTime:'00:00',//音频当前播放时间
    audioAllTime:'00:00',//音频总播放时间
    audioAllDuration:0,//音频总播放秒数
    bsize:`var(--f8)`,//默认为8
    onOff: true, // 控制播放暂停按钮
    isAutoplay:true,//是否要自动播放
    brsShow:false,//清晰度调整
    br:1080,//默认清晰度为1080
    artistsShow:false,//查看更多作用
  })
  //开始时间
  const startTimer =computed(()=>{
    return videoData.audioCurrentTime
  })
  //结束时间
  const endTimer =computed(()=>{
    return videoData.audioAllTime
  })

  //动态创建video标签
  const videoCreated = (url)=>{
    const x = document.createElement("VIDEO");
    x.setAttribute("width", "100%");
    x.setAttribute("class", "video-wrap");
    x.setAttribute("id", "videoWrap");
    x.setAttribute("max-height", "320");
    x.setAttribute("controls", false);
    x.setAttribute("show-mute-btn", true);
    x.setAttribute("muted", true);
    x.setAttribute("loop ", true);
    x.setAttribute("x5-video-player-type", 'h5');
    x.setAttribute("object-fit", 'contain');
    x.setAttribute("custom-cache", false);
    x.setAttribute("show-center-play-btn", false);
    x.setAttribute("autoplay", true);
    x.setAttribute("x5-playsinline", true);
    x.setAttribute("webkit-playsinline", true);
    x.setAttribute("ref", 'videoRefPlay');
    x.setAttribute("src", url);
    x.onContextMenu =()=>{
      return false
    }
    x.onClick =()=>{
      onPlayVidoPause()
      return false
    }
    document.body.appendChild(x);
    document.getElementById("demo").innerHTML = "<b>注释:</b>IE 和 Safari 不支持 .ogg 文件格式。这只是一个例子。如需使其在所有浏览器中运行,您应该在 video 元素中使用 source 元素。";
  }

  //点击视频暂停
  const onPlayVidoPause= ()=>{
    const _audioPlayer=document.getElementById('videoWrap')
    if(_audioPlayer?.play){
      videoData.onOff = true
      _audioPlayer.pause()
    }
  }
  //设置定时检测
  const setAudioInterval=()=>{
    const _audioPlayer=document.getElementById('videoWrap')
    videoData.onOff = false
    if(_audioPlayer.play){
      audioInterval = setInterval(()=>{
        getAudiTime()

        if(_audioPlayer.ended){
          clearInterval(audioInterval)
          videoData.audioTime = 0
          _audioPlayer.currentTime = 0
          videoData.audioCurrentTime ='00:00'
        }
      },500)
    } else {
      clearInterval(audioInterval)
    }

  }
  //视频的其他变化
  const getAudiTime = ()=>{
    const _audioPlayer=document.getElementById('videoWrap')
    videoData.audioAllTime=realFormatSecond(_audioPlayer.duration)
    videoData.audioAllDuration =_audioPlayer.duration
    videoData.audioCurrentTime = realFormatSecond(_audioPlayer.currentTime)
    videoData.audioTime =(_audioPlayer.currentTime*100/_audioPlayer.duration).toFixed(3)
  }
  //进度变化时实时触发
  const onChange=value =>{
    const _audioPlayer=document.getElementById('videoWrap')
    videoData.audioCurrentTime = realFormatSecond(videoData.audioAllDuration*value/100)
    _audioPlayer.currentTime = parseInt(videoData.audioAllDuration*value/100)
    _audioPlayer.play()
    if(_audioPlayer.play){
      videoData.onOff = false
    }

  }
  const onInput = value=>{
    videoData.onOff = false
  }
  //开始拖动时触发
  const onDragStart = ()=>{
    videoData.onOff = false

  }
  //结束拖动时触发
  const onDragEnd = ()=>{
    const _audioPlayer=document.getElementById('videoWrap')
    videoData.onOff = false
    _audioPlayer.play()
  }
  //开始播放
  const onPlayVideo = ()=>{
    const _audioPlayer=document.getElementById('videoWrap')
    if(_audioPlayer.pause){
      videoData.onOff = false
      setTimeout(()=>{
        _audioPlayer.play()
      },150)

    }
  }
  //重置
  const onRestPlay=(br)=>{
    videoData.br =br
    videoData.brsShow = false
    videoData.audioTime=0
    videoData.audioCurrentTime='00:00'
    videoData.audioAllTime='00:00'
    videoData.audioAllDuration=0
  }
  onUnmounted(()=>{
    clearInterval(audioInterval)
    onPlayVidoPause()
  })
  return {
    route,videoRefPlay,detail,
    startTimer,endTimer,videoCreated,
    onPlayVidoPause,setAudioInterval
    ,getAudiTime,onChange,onDragStart,
    onDragEnd,onPlayVideo,onRestPlay,videoData,onInput
  }
}
export default videoMvHooks


//调用a.vue
import videoHooks from '@/hooks/videoHooks'
setup(){
const {
      route,videoRefPlay,detail,
      startTimer,endTimer,videoCreated,
      onPlayVidoPause,setAudioInterval
      ,onChange,onDragStart,
      onDragEnd,onPlayVideo,videoData,onInput
    } = videoHooks();
  return {
     route,videoRefPlay,detail,
      startTimer,endTimer,videoCreated,
      onPlayVidoPause,setAudioInterval
      ,onChange,onDragStart,
      onDragEnd,onPlayVideo,videoData,onInput
  
  }
  
}