Skip to content

vue技术

🚀 基础

sh
# 安装
npm create vue@latest
# 项目打包
npm run build
# 打包项目预览
npm run preview

# 响应式数据
ref、reactive
# 计算属性
computed
# 监听元素
watch(value,(new,old)=>{})

# 渲染
:class
# 双向绑定
v-model="text"
# 组件创建完成初始化生命周期
onMounted

# 全局变量,main.js挂载
app.provide('$text',"成功");
# 使用
import { inject } from "vue";
const text = inject("$text");

万能的ref

  • 可以获取到绑定元素的内容和方法
  • 可以获取到组件实例
js
<div ref="divRef">这是一个 div 元素</div>
<script setup>
import { ref, onMounted } from 'vue'

const divRef = ref(null)

onMounted(() => {
  console.log(divRef.value) // 输出: <div>这是一个 div 元素</div>
  divRef.value.style.color = 'red' // 修改 div 元素的样式
  // 如果divRef绑定了函数,则可以调用
})
</script>

nextTick等待渲染完成

  • 在 Vue 中,DOM 的更新是异步的,这意味着当你在数据变化后立即访问 DOM,可能无法获取到最新的 DOM 状态。为了确保在 DOM 更新后执行代码,可以使用 nextTick 函数。
js
// 示例:理解 Vue 的异步更新机制
import { ref, nextTick } from 'vue'

const count = ref(0)

const updateCount = () => {
  count.value++ // 数据更新
  
  // 此时 DOM 还未更新
  console.log('同步代码:', document.querySelector('p').textContent) // 还是旧值
  
  nextTick(() => {
    // DOM 已经更新
    console.log('nextTick中:', document.querySelector('p').textContent) // 新值
  })
}
  • 使用办法:
js
1.
const updateMessage = async () => {
  // 更新数据
nextTick(() => {
    console.log('DOM 已更新')
  // 可以在这里进行 DOM 操作
  })
}

2.(推荐)
async function updateDOM() {
  // 更新数据...
  await nextTick()
  console.log('DOM 更新完成')
  // 进行 DOM 操作
}

js动态修改元素属性

  • :style=""
js
<div :style="bj">这是一个 div 元素</div>

const bj = {
  backgroundColor: "red",  // 横线后面大写,比如:background-color等于backgroundColor
};

🎯 组件

js
# 全局注册组件(main.js)
app.component('MyComponent', MyComponent)
js
# 父传子————
<component value="传递数据"/>
# 子组件接收
import { defineProps } from 'vue'
const props = defineProps(['value'])
console.log(props.value)
js
# 父组件调用子组件事件/父组件获取子组件的数据————
// 子组件:
const open = () => {
  console.log('open')
}
const value = ref(0)
defineExpose({ open, value })  // 把方法暴露出去
// 父组件:
<component ref="show"/> // 获取子组件实例
const show = ref(null)
const open = () => {
  show.value.open() // 调用子组件方法
  show.value.value() // 获取子组件数据
}
  • 当点击子组件的事件时,会触发父组件的点击事件,从而实现子组件向父组件传递数据
js
# 子传父/子触发父事件————
// 子组件:
import { defineEmits } from "vue";
// 定义可触发的事件
<button @click="but">触发自定义事件</button>
const emit = defineEmits(["custom"]);
const but = () => {
  // 触发事件并传递数据
  console.log("触发事件");
  const message = "子组件传递的数据";
  emit("custom",message);
};
// 父组件:
<component @custom="customData"/> // 监听子组件自定义事件
const customData = (data) => {
  console.log(data.message);
};

🌈 插槽

  • 父组件可以传递任何内容给子组件
js
// 单插槽
父组件:
<button><slot></slot></button>
子组件:
<buttonComponenst/>这里可以放任何内容</buttonComponenst>

// 多插槽
子组件:
<button><slot name="slot1"></slot></button>
父组件:
 <template #slot1>
    插槽1的内容放这里
 </template>

自定义指令

js
const custom = {
  // mounted是指令被绑定到元素上时调用
  mounted: (el, binding) => {
    const { value } = binding.value  // 获取到指令绑定的值,比如 v-custom="color"
    el.XXX = "自定义指令做什么,这可以用于直接操作 DOM"
    // 例:el.style.color = red
  }
}
// 使用案例:<div v-custom="{ color: 'red' }"></div>

// 全局注册 v-color,动态设置文本颜色
app.directive('color', (el, binding) => {
  el.style.color = binding.value
})

组件切换缓存

  • 在引入组件包裹KeepAlive标签,当组件切换时,组件不会被销毁,而是缓存起来
js
<KeepAlive :max="10">  // 设置最大缓存数
  <component :is="activeComponent" />
</KeepAlive>

✅ 路由

404页面

js
{
path: '/:pathMatch(.*)',
component: '/error',
}

路由配置

js
// 嵌套路由
children: [
{ path: '/', name: 'user', component: UserHome }
]
// 路由元信息
meta: { requiresAuth: true,title:"页面名字" }
// 路由跳转
import { useRouter } from 'vue-router'
const router = useRouter();
router.push({ path: '/indexView', query: { id: 123 } });
// 路由接收
import { useRoute } from 'vue-router'
const route = useRoute();
const id = route.query.id;
// 返回一条记录
router.go(-1)

路由守卫

js
// 全局前置路由
router.beforeEach((to, from, next) => { }
to:将要进入的路由
from:离开的路由
next():进入路由
next(false):中断当前导航
next('路径'):强行跳转路由说

始终跳转到页面顶部

js
const router = createRouter({
  scrollBehavior (to, from, savedPosition) {
    return { top: 0 }
  }
})

nginx刷新404

js
try_files $uri $uri/ /index.html;

动态添加路由

js
router.addRoute(route)

// 删除路由
// const removeRoute = router.addRoute(route)
// 后续需要移除时调用
// removeRoute()

路由动效

  • 根据name属性获取不同的class动效样式
js
<router-view v-slot="{ Component }">
    <transition name="scale" mode="out-in">
      <component :is="Component" />
    </transition>
  </router-view>
css
/* 渐变 mode="out-in" */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
/* 幻灯片 */
.slide-enter-active,
.slide-leave-active {
  transition: all 0.75s ease-out;
}


.slide-enter-to {
  position: absolute;
  right: 0;
}


.slide-enter-from {
  position: absolute;
  right: -100%;
}


.slide-leave-to {
  position: absolute;
  left: -100%;
}


.slide-leave-from {
  position: absolute;
  left: 0;
}
/* 缩放 mode="out-in" */
.scale-enter-active,
.scale-leave-active {
  transition: all 0.5s ease;
}


.scale-enter-from,
.scale-leave-to {
  opacity: 0;
  transform: scale(0.9);
}
/* 组合 */
.scale-slide-enter-active,
.scale-slide-leave-active {
  position: absolute;
  transition: all 0.85s ease;
}

.scale-slide-enter-from {
  left: -100%;
}

.scale-slide-enter-to {
  left: 0%;
}

.scale-slide-leave-from {
  transform: scale(1);
}

.scale-slide-leave-to {
  transform: scale(0.8);
}

当前选中路由css类

.router-link-active