学习 vue 3.0

158 阅读1分钟

开始学vue3.0初学的写法

数据结构不复杂的情况下

<template>
  <div>
    {{msg}}-{{data.current}}
    {{data.doubleCounter}}
  </div>
</template>
<script>
import { computed, reactive,onMounted, onUnmounted } from 'vue'
export default {
  name:'test',
  props:{
    msg:String
  },
  setup(){
    const data = reactive({
      current:1,
      // 计算属性的使用
      doubleCounter:computed(()=> data.current * 2)
    })
    
    let timer
    // 注意生命周期都在setup里处理 更像create
    // 3.0 在onMounted请求数据异步
    onMounted(() => {
      timer = setInterval(() => {
        data.current++
      }, 1000);
    }),
    onUnmounted(() => {
      clearInterval(timer)
    })
    return {data}
  }
}
</script>

计算属性的使用

如果数据结果复杂的情况这样写会显得十分的乱就用分离利用toRefs结构出来

<template>
  <div>
    {{msg}}-{{current}}
    {{doubleCounter}}
    {{msg2}}
    <!-- 如何使用ref -->
    <p ref="desc"></p>
  </div>
</template>
<script>
import { computed, reactive,onMounted, onUnmounted, ref, toRefs, watch } from 'vue'
export default {
  name:'test',
  props:{
    msg:String
  },
  setup(){
    // 改变写法
    // const data = useCounter()
    // 使用了toRefs()就可以结构出来了 省略了html 中data. data.
    const {current,doubleCounter} = useCounter()
    
    const msg2 = ref('some message')
    // 使用ref元素的引用
    const desc = ref(null)
    // 监听属性
    // data.current如果发生变化监听值
    watch(current,(val,oldVal)=>{
      const p = desc.value
      p.textContent =  `counter change ${val} to ${oldVal}`
    })
    return {current,doubleCounter,msg2,desc}
  },
}
    // 改变写法
  function useCounter(){
    const data = reactive({
      current:1,
      // 计算属性的使用
      doubleCounter:computed(()=> data.current * 2)
    })
    
    let timer
    // 注意生命周期都在setup里处理 更像create
    // 3.0 在onMounted请求数据异步
    onMounted(() => {
      timer = setInterval(() => {
        data.current++
      }, 1000);
    }),
    onUnmounted(() => {
      clearInterval(timer)
    })
    // 这写法比较死板
    // return data
    //如果数据比较多使用toRefs会更香
    return toRefs(data)

  }
</script>

Teleport 传送门组件

<template>
  <div>
    <Composition></Composition>
    <ModalButton></ModalButton>
  </div>
</template>

<script>
import ModalButton from './ModalButton.vue'
components:{
    ModalButton
  }
</script>


Composition.vue

<template>
   <button @click="data.modelOpen=true">弹出一个模态弹窗</button>
   <teleport to="body">
     <div v-if="data.modelOpen" class="modal">
       <div>这是一个弹窗</div>
       <button @click="data.modelOpen= false">关闭</button>
     </div>
   </teleport>
</template>
<script>
import { reactive } from '@vue/reactivity'
export default {
  props:{
    msg:String
  },
  setup(){
    const data = reactive({
      modelOpen:true
    })
   return {data}
  },
}

</script>

image.png

Fragments

vue3.0项目中可以拥有多个根

emits

组件中

<template>
   <button @click="$emit('my-click')">自定义事件</button>
</template>
export default {
 emits:['my-click']
}

</script>

引用的地方 <Emites @my-click="onclick"></Emites>

自定义渲染器 custom renderer

image.png

时间控件

image.png

import dayjs from 'dayjs';

// 下发任务时间
 <a-date-picker v-model:value="model[field]" :disabled-date="disabledDate" placeholder="请选择时间" />

const disabledDate = current => {
  let dis: any = ''
  if (timeRange.length) {
    dis = current <= dayjs(timeRange[0]).startOf('day') || current >= dayjs(timeRange[1]).endOf('day')
  }
  return dis
}