Vue.js混入mixin应用
0
2
2026年6月24日
组件通信
<template>
<div>
<Child
:message="parentMsg"
@reply="handleReply"
ref="childRef"
/>
<button @click="callChild">调用子组件</button>
</div>
</template>
<script>
import Child from './Child.vue'
export default {
components: { Child },
data() {
return { parentMsg: '来自父组件的消息' }
},
methods: {
handleReply(msg) {
console.log('子组件回复:', msg)
},
callChild() {
this.$refs.childRef.sayHello('父组件调用')
}
}
}
</script>
生命周期钩子
<template>
<div>
<p>计数: {{ count }}</p>
<button @click="count++">增加</button>
<p ref="time">时间: {{ time }}</p>
</div>
</template>
<script>
export default {
data() {
return { count: 0, time: '', timer: null }
},
created() {
this.timer = setInterval(() => {
this.time = new Date().toLocaleTimeString()
}, 1000)
},
mounted() {
console.log('DOM元素:', this.$refs.time)
},
beforeDestroy() {
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
}
}
</script>
Vuex Store
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
user: null,
token: localStorage.getItem('token') || '',
cart: []
},
getters: {
isLoggedIn: state => !!state.token,
cartCount: state => state.cart.length,
cartTotal: state => state.cart.reduce((sum, i) => sum + i.price * i.qty, 0)
},
mutations: {
SET_TOKEN(state, token) {
state.token = token
localStorage.setItem('token', token)
},
ADD_TO_CART(state, product) {
const exist = state.cart.find(i => i.id === product.id)
exist ? exist.qty++ : state.cart.push({...product, qty: 1})
},
LOGOUT(state) {
state.token = ''
state.user = null
localStorage.removeItem('token')
}
},
actions: {
async login({ commit }, credentials) {
const res = await api.login(credentials)
commit('SET_TOKEN', res.data.token)
}
}
})
自定义指令
Vue.directive('focus', {
inserted(el) {
el.focus()
}
})
Vue.directive('click-outside', {
bind(el, binding) {
el._clickOutside = e => {
if (!el.contains(e.target)) {
binding.value(e)
}
}
document.addEventListener('click', el._clickOutside)
},
unbind(el) {
document.removeEventListener('click', el._clickOutside)
}
})
Vue.directive('lazy-load', {
inserted(el) {
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
el.src = el.dataset.src
observer.unobserve(el)
}
})
})
observer.observe(el)
}
})
混入Mixin
const paginationMixin = {
data() {
return {
page: 1,
pageSize: 10,
total: 0,
list: []
}
},
computed: {
totalPages() {
return Math.ceil(this.total / this.pageSize)
}
},
methods: {
changePage(page) {
this.page = page
this.fetchData()
}
}
}
export default paginationMixin
路由守卫
import router from './router'
router.beforeEach((to, from, next) => {
const token = localStorage.getItem('token')
if (to.meta.requiresAuth && !token) {
next('/login')
} else if (to.meta.guest && token) {
next('/dashboard')
} else {
next()
}
})
最佳实践
组件化开发,小组件单一职责,严格的props验证,v-for始终配合:key使用唯一ID,频繁切换用v-show否则用v-if,复杂逻辑放在computed,beforeDestroy中清理定时器和监听器。
技术分享,欢迎评论区交流讨论。
在线咨询
上一个应该是我,我买了一年,实在没价值,...