Skip to content

事件

自定义右击菜单-vue3

  1. 监听dom,添加事件
vue
<RouterView @contextmenu.stop.prevent="menu"/>

contextmenu:监听右键事件

stop:关闭冒泡

prevent:关闭默认的右击事件

使用修饰符时需要注意调用顺序,因为相关代码是以相同的顺序生成的。

@click.prevent.self 会阻止元素及其子元素的所有点击事件的默认行为@click.self.prevent 则只会阻止对元素本身的点击事件的默认行为。

vue
<!-- 单击事件将停止传递 -->
<a @click.stop="doThis"></a>

<!-- 提交事件将不再重新加载页面 -->
<form @submit.prevent="onSubmit"></form>

<!-- 修饰语可以使用链式书写 -->
<a @click.stop.prevent="doThat"></a>

<!-- 也可以只有修饰符 -->
<form @submit.prevent></form>

<!-- 仅当 event.target 是元素本身时才会触发事件处理器 -->
<!-- 例如:事件处理器不来自子元素 -->
<div @click.self="doThat">...</div>

事件修饰符文档

  1. 获取鼠标点击位置
  • 给dom绑定右击事件,获取鼠标x,y坐标,赋值给变量,动态绑定style
  • 改变menu的隐藏显示状态
typescript
const menu_hidden = ref(false);
const menu_left = ref(0);
const menu_top = ref(0);
const menu = (e:any)=> {
  menu_left.value = e.clientX
  menu_top.value = e.clientY
  menu_hidden.value = true 
}

pinia

在单独的js/ts文件中使用pinia

js
//对pinia进行注册
import { createPinia } from 'pinia';
const pinia = createPinia();
//引入 使用
import { start } from '@/stores/start'
const store = start(pinia);

setup

父子组件传参

  1. 父传子
  • js
    const props = defineProps({
    	msg:{
    		type:String,
    		requird:true,
    		default:"hello"
    	},
    	list:Array
    })
  • typescript
    const props = defineProps<{
         foo: string
     	 bar?: number
    }>()
  1. 子传父
  • 子组件创建自定义事件(typescript写法)
vue
//创建change事件
//点击clickChild触发事件向父组件发送
//定义param
//使用自定义事件发送
<script srtup lang="ts">
    const emit = defineEmits<{
      (e: 'change', param:object): void
    }>()
    const clickChild = () => {
        let param={
            content:'hello'
        }
        //传递给父组件
        emit('change',param)
    }
</script>

<template>
    <button @click="clickChild">点击子组件</button>
</template>
  • 父组件接收参数
vue
<script setup lang="ts">
import  Main from '../components/Main.vue'

const fun = (val:any) => {
  console.log(val);
}
</script>

<template>
	<Main @change="fun"/>
</template>
  • js语法
js
const emit = defineEmits(['change'])

watch监听

  • 单数据监听
js
import {watch} from 'vue'
watch(
()=>props.state,
(val,preVal)=>{
    console.log("state新数据,state旧数据:",val,preVal);
})
  • 多条数据监听,使用数组包裹
js
watch(
()=>[props.state,props.site],
(val,preVal)=>{
    console.log("state新数据,state旧数据:",val[0],preVal[0]);
    console.log("site新数据,site旧数据:",val[1],preVal[1]);
})

vue3监听页面尺寸改变

vue
onMounted(() => {
  window.onresize = async ()=>{
    consolg.log('尺寸改变了')
  }
})

vue-router

获取路由信息

vue
import { useRoute } from 'vue-router';
const route = useRoute(); //获取路由

路由错误页跳转配置

vue3

routes:[
{
    path:'/:pathMatch(.*)',//匹配除了已设置好的路由之外,全部重定向到错误页
    redirect: '/error/404'//重定向
}
]

路由打包时指定文名

webpack

vue
{
	path:'/home',
	name:'home',
	component: () => import(/* webpackChunkName: 'home' */ '../views/home')
}
  • 其中的/* webpackChunkName: 'home' */便是指定打包完的文件名为home.xxx.js

导航守卫

router.beforeEach注册全局守卫

js
router.beforeEach((to,from)=>{
	//进行登录判断等
    
	//返回false取消导航
	return false
    
    //返回登录页
    //return {name:login}
})

axios

请求拦截 请求响应

typescript
import axios from 'axios';

const icon = (config:string) => {
    const instance = axios.create({
        baseURL:"/api",
        timeout:30000,
        //声明可以携带cookie,session,需在api后台允许携带
        //withCredentials: true
    });
    // 请求拦截
    instance.interceptors.request.use(config=>{
        return config;
    },error => {
        return Promise.reject(error)
    });

    // 响应拦截
	instance.interceptors.response.use(response => {
        return response;
    },error => {
        return Promise.reject(error);
    });
    return instance(config);
}

Element-ui/plus

vue
<el-menu
    :default-active="$route.path"//使用$route.path让激活菜单和路由绑定
    :collapse="isCollapse"//展开或收起
    router="true"//开启路由模式
  >
 </el-menu>

路由切换效果

vue
<template>
  <router-view v-slot="{ Component }">
    <transition name="fade" mode="out-in">
      <component :is="Component" />
    </transition>
  </router-view>
</template>

js

刷新页面

js
location.reload();

页面跳转

js
//新窗口
window.open(url)
//当前窗口
window.location.href = url

获取屏幕宽高

js
const win = () => {
    let innWidth = document.body.clientWidth;
    let innHeight = document.body.clientHeight;
    let arr = [innWidth,innHeight];
    return arr;
}

暗色模式

vue3+element-plus+ts

  1. 针对element-plus的暗黑样式而不是自定义的dark.css
  • 导入element的暗黑模式css变量
typescript
// main.ts
import 'element-plus/theme-chalk/dark/css-vars.css'
  • 在vue页面设置切换开关
vue
<script setup lang="ts">
	import { useToggle } from '@vueuse/shared'
    import { useDark } from "@vueuse/core"

    import {ref} from 'vue'
    const theme = ref<boolean>(false)

    const isDark = useDark({
          // 存储到localStorage/sessionStorage中的Key 根据自己的需求更改
          storageKey: 'useDarkKEY',
          // 暗黑class名字
          valueDark: 'dark',
          // 高亮class名字
          valueLight: 'light',
        })

    const changeDark = useToggle(isDark)
</script>

<template>
    <div class="dark">
        <el-switch v-model="theme" style="--el-switch-on-color: #3c3c3c" @click="changeDark()"/>
    </div>
</template>
  1. element-plus的暗黑样式加自定义暗色模式css
  • 新建dark-vars.css,覆盖element的css变量
css
html.dark {
  /* 自定义深色背景颜色 */
  --el-bg-color: #626aef;
}
  • 导入暗黑模式css文件(同1)
typescript
// main.ts
import 'element-plus/theme-chalk/dark/css-vars.css'
import './styles/theme/dark-vars.css'
  • 在vue页面设置切换开关(同1)

vue 实现全屏

csdn

npm install --save screenfull
import screenfull from "screenfull";

然后就可以通过screenfull.toggle()来切换全屏模式了。