记录学习与后端知识并分享学习代码过程(会飞的鱼Blog)

Vue.js混入mixin应用

会飞的鱼 0 2 2026年6月24日

Vue.js混入mixin应用

组件通信

<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中清理定时器和监听器。


技术分享,欢迎评论区交流讨论。

本文由 @会飞的鱼 于 2026-6-24 发布在 会飞的鱼Blog,如无特别说明,本博文章均为原创,转载请保留出处。

网友评论

    暂无评论

会飞的鱼 在线咨询

在线时间:9:00-22:00
周六、周日:14:00-22:00