vue3 setup 语法糖
vue 2022-10-17 18:47:33

1、vue3 setup中使用router

2、vue3 setup中使用component

3、vue3 setup中使用动态 component、computed

4、vue3 setup中使用watch、ref修改data 

5、vue3 setup中使用Pinia的action,监听pinia的state

6、vue3 setup 父子组件使用ref、refs以及调用子组件方法(子组件需要暴露出可以调用的方法)

7、vue3 setup 使用emit 

8、vue3 setup 使用props

 

 

 

1、vue3 setup中使用router

XML/HTML Code复制内容到剪贴板
  1. <template>  
  2.   
  3. <a href="javascript:(0)" @click="toRouter({path: '/'})">首页</a>  
  4.   
  5. </template>  
  6.   
  7. <script setup>  
  8. import { useRouter,useRoute } from 'vue-router'  
  9. const route = useRoute()  
  10. const router = useRouter()  
  11.   
  12. const toRouter = (params) => {  
  13.   router.push(params)  
  14. }  
  15. </script>  

 

2、vue3 setup中使用component,可以不必声明,一定要加.vue

3、vue3 setup中使用动态组件 component、computed

XML/HTML Code复制内容到剪贴板
  1. <template>  
  2.   <ElConfigProvider :size="size" :z-index="zIndex">  
  3.     <component :is="layout">  
  4.       <RouterView />  
  5.     </component>  
  6.   </ElConfigProvider>  
  7. </template>  
  8.   
  9. <script setup>  
  10. import { ref, computed } from 'vue'  
  11. import { RouterView,useRouter,useRoute } from 'vue-router'  
  12. import { ElConfigProvider } from 'element-plus'  
  13. import DefaultLayout from '@/layout/default.vue'  
  14. import Layout from '@/layout/index.vue'  
  15. const route = useRoute()  
  16. const router = useRouter()  
  17. const zIndex = ref(3000)  
  18. const size = ref('default')  
  19.   
  20. // computed 根据路由决定是否引入layout布局  
  21. const layout = computed(() => {  
  22.   return route.meta.noLayout ? DefaultLayout : Layout  
  23. });  
  24. </script>  

 

4、vue3 setup中使用watch、ref修改data 

XML/HTML Code复制内容到剪贴板
  1. <template>  
  2.   <!--pc端菜单-->  
  3.   <el-menu  
  4.       :default-active="activeIndex"  
  5.       class="menu-pc"  
  6.       mode="horizontal"  
  7.       :router="true"  
  8.       :ellipsis="false"  
  9.       @select="handleSelect"  
  10.   >  
  11.     <el-menu-item index="0">  
  12.       <img src="@/assets/home/logo.png" />  
  13.     </el-menu-item>  
  14.     <div class="base-flex1" />  
  15.     <el-menu-item index="/">首页</el-menu-item>  
  16.     <el-menu-item index="/energy">智慧节能</el-menu-item>  
  17.     <el-menu-item index="/product">AIoT产品中心</el-menu-item>  
  18.     <el-menu-item index="/case">节能工程案例</el-menu-item>  
  19.     <el-menu-item index="5">合作伙伴</el-menu-item>  
  20.     <el-menu-item index="6">个人中心</el-menu-item>  
  21.     <el-menu-item index="7">资源中心</el-menu-item>  
  22.     <el-menu-item index="8">关于xxx</el-menu-item>  
  23.   </el-menu>  
  24.   
  25. </template>  
  26.   
  27. <script setup>  
  28. import { useRoute } from 'vue-router'  
  29. import { ref, watch } from 'vue'  
  30. const route = useRoute()  
  31. let activeIndex = ref('')  
  32. let drawer = ref(false)  
  33.   
  34. //监听一个值  
  35. //watch(要监听的值,(新值,旧值)=>{......})  
  36. watch(route, (curr, old) => {  
  37.   activeIndex.value = curr.path  
  38. })  
  39.   
  40. const handleSelect = (key, keyPath) => {  
  41.   // 切换导航  
  42.   // console.log(key, keyPath)  
  43. }  
  44. </script>  
  45.   
  46. <style lang="less">  
  47. .menu-pc {  
  48.   height: 100px;  
  49. }  
  50. .menu-app {  
  51.   display: none;  
  52. }  
  53.   
  54. </style>  

 

如果是监听某个对象下的子属性,建议箭头函数:

JavaScript Code复制内容到剪贴板
  1. watch(() => props.apiObj, (curr, old) => {  
  2.   // sth  
  3. })  

 

 

5、vue3 setup中使用Pinia的action

XML/HTML Code复制内容到剪贴板
  1. <script setup>  
  2.   import { ref, onMounted, getCurrentInstance } from 'vue'  
  3.   import useMainStore from '@/stores'  
  4.   
  5.   const store = useMainStore()  
  6.   onMounted(() => {  
  7.       // 用户退出  
  8.       store.exit()  
  9.   })  
  10. </script>  

 

stores/index.js

JavaScript Code复制内容到剪贴板
  1. import { defineStore } from 'pinia'  
  2. import axios from 'axios'  
  3. import tool from '@/utils/tool'  
  4.   
  5. //这里是对pinia进行一个取名,state需要时一个函数的形式  
  6. export default defineStore('main', {  
  7.     state: () => {  
  8.         return {  
  9.             count: 10,  
  10.             name: 'xxx'  
  11.         }  
  12.     },  
  13.     // 同步和异步皆可  
  14.     actions: {  
  15.         // 用户退出  
  16.         async exit() {  
  17.             console.log('用户退出')  
  18.             tool.cookie.remove("TOKEN")  
  19.             tool.data.remove("USER_INFO")  
  20.         }  
  21.     }  
  22. })  

 

JavaScript Code复制内容到剪贴板
  1. import { mainStore } from '@/stores/mainStore'  
  2. const piniaMainStore = mainStore()  
  3.   
  4.   
  5.   
  6. const onClickTitle = () => {  
  7.   piniaMainStore.showMainPage = !piniaMainStore.showMainPage  
  8. }  
  9.   
  10.   
  11. watch(  
  12.     () => piniaMainStore.showMainPage,  
  13.     (currentVal, oldVal) => {  
  14.       if(currentVal === true) {  
  15.         // 如果要显示主页面  
  16.         showDom.value = false  
  17.       }else{  
  18.         showDom.value = true  
  19.       }  
  20.     },  
  21.     {  
  22.       deep:true  
  23.     }  
  24. );  

 

 

6、vue3 setup 父子组件使用ref、refs以及调用子组件方法  

XML/HTML Code复制内容到剪贴板
  1. <template>  
  2.     
  3.                   <div class="base-flex1 base-flex base-rows base-align-items-center base-justify-content-end btn btn1" @click="onClickEdit(item)">  
  4.                     <el-icon :size="18">  
  5.                       <EditPen />  
  6.                     </el-icon>  
  7.                     <span class="base-ml5">编辑</span>  
  8.                   </div>  
  9.               
  10.   <AddressSave ref="AddressSaveRef" v-if="dialog.info" @ok=""></AddressSave>  
  11.   
  12. </template>  
  13.   
  14. <script setup>  
  15. import { ref, onMounted, getCurrentInstance, nextTick } from 'vue'  
  16. import { CollectionTag, EditPen, Delete } from '@element-plus/icons-vue'  
  17. import AddressSave from '@/views/ucenter/address-save.vue'  
  18. const { proxy } = getCurrentInstance()  
  19. const $TOOL = proxy.$TOOL  
  20. const $API = proxy.$API  
  21.   
  22. const AddressSaveRef = ref(null)  
  23. // 编辑  
  24. const onClickEdit = (row) => {  
  25.   dialog.value.info = true  
  26.   nextTick(() => {  
  27.     AddressSaveRef.value.open('edit').setData(row)  
  28.   })  
  29. }  
  30.   
  31. </script>  

 

子组件:

XML/HTML Code复制内容到剪贴板
  1. <template>  
  2.   <el-dialog :title="titleMap[mode]" v-model="visible" :width="480">  
  3.     // dosomething  
  4.   </el-dialog>  
  5. </template>  
  6.   
  7. <script setup>  
  8. import { ref } from 'vue'  
  9.   
  10. // 是否显示弹出框  
  11. const visible = ref(false)  
  12. // 模式,add新增,show查看,edit编辑  
  13. const mode = ref('add')  
  14. // 打开弹出框  
  15. const open = (val = 'add') => {  
  16.   mode.value = val  
  17.   visible.value = true  
  18. }  
  19.   
  20. //表单注入数据  
  21. const setData = (data) => {  
  22.   Object.assign(form.value, data)  
  23.   console.log(data)  
  24.   // if(this.mode === 'edit'){  
  25.   //   this.getInfo()  
  26.   // }  
  27. }  
  28. // 子组件中要通过defineExpose将方法暴露给父组件  
  29. defineExpose({ open, setData })  
  30. </script>  

 

7、vue3 setup 使用emit 

XML/HTML Code复制内容到剪贴板
  1. <template>  
  2.         <el-button type="primary" @click="onClickSave">保存</el-button>  
  3. </template>  
  4.   
  5. <script setup>  
  6.   
  7. const emit = defineEmits(['ok']);  
  8.   
  9. // 提交  
  10. const onClickSave = () => {  
  11.   console.log(form.value)  
  12.   emit('ok')  
  13. }  
  14.   
  15. </script>  
  16.   
  17. <style scoped>  
  18.   
  19. </style>  

 

8、vue3 setup 使用props 

JavaScript Code复制内容到剪贴板
  1. const emit = defineEmits(['change'])  
  2. // 对象形式声明 props  
  3. // 等价于以 字符串数组声明 props  
  4. const props = defineProps({  
  5.   value: {  
  6.     type: Array,  
  7.     default: [],  
  8.     // required: true // 是否必传 ,在不声明为true 的情况下,所有prop 默认为非必填。  
  9.   },  
  10.   // 配置选项  
  11.   // https://element-plus.gitee.io/zh-CN/component/cascader.html#cascaderprops  
  12.   props: {  
  13.     type: Object,  
  14.     default() {  
  15.       return {  
  16.         expandTrigger: 'click' , // 'click' | 'hover' 次级菜单的展开方式  
  17.         // 'label': 'name',  
  18.         // 'value': 'val',  
  19.         // 'children': 'child'  
  20.       }  
  21.     }  
  22.   },  
  23.   style: {  
  24.     type: Object,  
  25.     default: {}, // 样式  
  26.   },  
  27.   size: {  
  28.     type: String,  
  29.     default''// 'large' | 'default' | 'small' 尺寸  
  30.   },  
  31.   placeholder: {  
  32.     type: String,  
  33.     default'' // 输入框占位文本  
  34.   },  
  35.   disabled: {  
  36.     type: Boolean,  
  37.     defaultfalse  // 是否禁用  
  38.   },  
  39.   clearable: {  
  40.     type: Boolean,  
  41.     defaultfalse // 是否支持清空选项  
  42.   },  
  43.   showAllLevels: {  
  44.     type: Boolean,  
  45.     defaulttrue // 输入框中是否显示选中值的完整路径  
  46.   },  
  47.   separator: {  
  48.     type: String,  
  49.     default' / ' // 用于分隔选项的字符  
  50.   },  
  51.   filterable: {  
  52.     type: Boolean,  
  53.     defaulttrue// 该选项是否可以被搜索  
  54.   },  
  55.   filterMethod: {  
  56.     type: Function // 自定义搜索逻辑,第一个参数是node,第二个参数是keyword,返回的布尔值表示是否保留该选项  
  57.   }  
  58. })  

 

 

 

 

 

本文来自于:http://www.yoyo88.cn/study/vue/636.html

Powered by yoyo苏ICP备15045725号