vue3 setup 语法糖
3、vue3 setup中使用动态 component、computed
4、vue3 setup中使用watch、ref修改data
5、vue3 setup中使用Pinia的action,监听pinia的state
6、vue3 setup 父子组件使用ref、refs以及调用子组件方法(子组件需要暴露出可以调用的方法)
XML/HTML Code复制内容到剪贴板
- <template>
- <a href="javascript:(0)" @click="toRouter({path: '/'})">首页</a>
- </template>
- <script setup>
- import { useRouter,useRoute } from 'vue-router'
- const route = useRoute()
- const router = useRouter()
- const toRouter = (params) => {
- router.push(params)
- }
- </script>
2、vue3 setup中使用component,可以不必声明,一定要加.vue
3、vue3 setup中使用动态组件 component、computed
XML/HTML Code复制内容到剪贴板
- <template>
- <ElConfigProvider :size="size" :z-index="zIndex">
- <component :is="layout">
- <RouterView />
- </component>
- </ElConfigProvider>
- </template>
- <script setup>
- import { ref, computed } from 'vue'
- import { RouterView,useRouter,useRoute } from 'vue-router'
- import { ElConfigProvider } from 'element-plus'
- import DefaultLayout from '@/layout/default.vue'
- import Layout from '@/layout/index.vue'
- const route = useRoute()
- const router = useRouter()
- const zIndex = ref(3000)
- const size = ref('default')
- // computed 根据路由决定是否引入layout布局
- const layout = computed(() => {
- return route.meta.noLayout ? DefaultLayout : Layout
- });
- </script>
4、vue3 setup中使用watch、ref修改data
XML/HTML Code复制内容到剪贴板
- <template>
- <!--pc端菜单-->
- <el-menu
- :default-active="activeIndex"
- class="menu-pc"
- mode="horizontal"
- :router="true"
- :ellipsis="false"
- @select="handleSelect"
- >
- <el-menu-item index="0">
- <img src="@/assets/home/logo.png" />
- </el-menu-item>
- <div class="base-flex1" />
- <el-menu-item index="/">首页</el-menu-item>
- <el-menu-item index="/energy">智慧节能</el-menu-item>
- <el-menu-item index="/product">AIoT产品中心</el-menu-item>
- <el-menu-item index="/case">节能工程案例</el-menu-item>
- <el-menu-item index="5">合作伙伴</el-menu-item>
- <el-menu-item index="6">个人中心</el-menu-item>
- <el-menu-item index="7">资源中心</el-menu-item>
- <el-menu-item index="8">关于xxx</el-menu-item>
- </el-menu>
- </template>
- <script setup>
- import { useRoute } from 'vue-router'
- import { ref, watch } from 'vue'
- const route = useRoute()
- let activeIndex = ref('')
- let drawer = ref(false)
- //监听一个值
- //watch(要监听的值,(新值,旧值)=>{......})
- watch(route, (curr, old) => {
- activeIndex.value = curr.path
- })
- const handleSelect = (key, keyPath) => {
- // 切换导航
- // console.log(key, keyPath)
- }
- </script>
- <style lang="less">
- .menu-pc {
- height: 100px;
- }
- .menu-app {
- display: none;
- }
- </style>
如果是监听某个对象下的子属性,建议箭头函数:
JavaScript Code复制内容到剪贴板
- watch(() => props.apiObj, (curr, old) => {
- // sth
- })
XML/HTML Code复制内容到剪贴板
- <script setup>
- import { ref, onMounted, getCurrentInstance } from 'vue'
- import useMainStore from '@/stores'
- const store = useMainStore()
- onMounted(() => {
- // 用户退出
- store.exit()
- })
- </script>
stores/index.js
JavaScript Code复制内容到剪贴板
- import { defineStore } from 'pinia'
- import axios from 'axios'
- import tool from '@/utils/tool'
- //这里是对pinia进行一个取名,state需要时一个函数的形式
- export default defineStore('main', {
- state: () => {
- return {
- count: 10,
- name: 'xxx'
- }
- },
- // 同步和异步皆可
- actions: {
- // 用户退出
- async exit() {
- console.log('用户退出')
- tool.cookie.remove("TOKEN")
- tool.data.remove("USER_INFO")
- }
- }
- })
JavaScript Code复制内容到剪贴板
- import { mainStore } from '@/stores/mainStore'
- const piniaMainStore = mainStore()
- const onClickTitle = () => {
- piniaMainStore.showMainPage = !piniaMainStore.showMainPage
- }
- watch(
- () => piniaMainStore.showMainPage,
- (currentVal, oldVal) => {
- if(currentVal === true) {
- // 如果要显示主页面
- showDom.value = false
- }else{
- showDom.value = true
- }
- },
- {
- deep:true
- }
- );
6、vue3 setup 父子组件使用ref、refs以及调用子组件方法
XML/HTML Code复制内容到剪贴板
- <template>
- <div class="base-flex1 base-flex base-rows base-align-items-center base-justify-content-end btn btn1" @click="onClickEdit(item)">
- <el-icon :size="18">
- <EditPen />
- </el-icon>
- <span class="base-ml5">编辑</span>
- </div>
- <AddressSave ref="AddressSaveRef" v-if="dialog.info" @ok=""></AddressSave>
- </template>
- <script setup>
- import { ref, onMounted, getCurrentInstance, nextTick } from 'vue'
- import { CollectionTag, EditPen, Delete } from '@element-plus/icons-vue'
- import AddressSave from '@/views/ucenter/address-save.vue'
- const { proxy } = getCurrentInstance()
- const $TOOL = proxy.$TOOL
- const $API = proxy.$API
- const AddressSaveRef = ref(null)
- // 编辑
- const onClickEdit = (row) => {
- dialog.value.info = true
- nextTick(() => {
- AddressSaveRef.value.open('edit').setData(row)
- })
- }
- </script>
子组件:
XML/HTML Code复制内容到剪贴板
- <template>
- <el-dialog :title="titleMap[mode]" v-model="visible" :width="480">
- // dosomething
- </el-dialog>
- </template>
- <script setup>
- import { ref } from 'vue'
- // 是否显示弹出框
- const visible = ref(false)
- // 模式,add新增,show查看,edit编辑
- const mode = ref('add')
- // 打开弹出框
- const open = (val = 'add') => {
- mode.value = val
- visible.value = true
- }
- //表单注入数据
- const setData = (data) => {
- Object.assign(form.value, data)
- console.log(data)
- // if(this.mode === 'edit'){
- // this.getInfo()
- // }
- }
- // 子组件中要通过defineExpose将方法暴露给父组件
- defineExpose({ open, setData })
- </script>
XML/HTML Code复制内容到剪贴板
- <template>
- <el-button type="primary" @click="onClickSave">保存</el-button>
- </template>
- <script setup>
- const emit = defineEmits(['ok']);
- // 提交
- const onClickSave = () => {
- console.log(form.value)
- emit('ok')
- }
- </script>
- <style scoped>
- </style>
JavaScript Code复制内容到剪贴板
- const emit = defineEmits(['change'])
- // 对象形式声明 props
- // 等价于以 字符串数组声明 props
- const props = defineProps({
- value: {
- type: Array,
- default: [],
- // required: true // 是否必传 ,在不声明为true 的情况下,所有prop 默认为非必填。
- },
- // 配置选项
- // https://element-plus.gitee.io/zh-CN/component/cascader.html#cascaderprops
- props: {
- type: Object,
- default() {
- return {
- expandTrigger: 'click' , // 'click' | 'hover' 次级菜单的展开方式
- // 'label': 'name',
- // 'value': 'val',
- // 'children': 'child'
- }
- }
- },
- style: {
- type: Object,
- default: {}, // 样式
- },
- size: {
- type: String,
- default: '', // 'large' | 'default' | 'small' 尺寸
- },
- placeholder: {
- type: String,
- default: '' // 输入框占位文本
- },
- disabled: {
- type: Boolean,
- default: false // 是否禁用
- },
- clearable: {
- type: Boolean,
- default: false // 是否支持清空选项
- },
- showAllLevels: {
- type: Boolean,
- default: true // 输入框中是否显示选中值的完整路径
- },
- separator: {
- type: String,
- default: ' / ' // 用于分隔选项的字符
- },
- filterable: {
- type: Boolean,
- default: true// 该选项是否可以被搜索
- },
- filterMethod: {
- type: Function // 自定义搜索逻辑,第一个参数是node,第二个参数是keyword,返回的布尔值表示是否保留该选项
- }
- })