Vue 进阶

 前端   打工人   2024-09-14 07:01   196
  Vue

1. Vue 组件通信的原理及示例

在 Vue.js 中,组件是应用的核心模块。由于 Vue 是单向数据流的框架,组件之间的通信主要依赖于父子组件的关系,以及特定的工具和模式,如 props$emit$parent$refs 等。

组件通信的方式

  1. 父组件向子组件通信(通过 props
    父组件通过 props 向子组件传递数据,props 是一种单向绑定,子组件不能直接修改父组件传递的数据。

    <!-- 父组件 -->
    <template>
      <div>
        <child-component :message="parentMessage"></child-component>
      </div>
    </template>
    
    <script>
    import ChildComponent from './ChildComponent.vue';
    
    export default {
      data() {
        return {
          parentMessage: 'Hello from Parent'
        };
      },
      components: {
        ChildComponent
      }
    };
    </script>
    
    <!-- 子组件 -->
    <template>
      <p>{{ message }}</p>
    </template>
    
    <script>
    export default {
      props: ['message']
    };
    </script>
    
  2. 子组件向父组件通信(通过 $emit
    子组件可以通过 $emit 事件通知父组件,父组件可以监听子组件触发的事件。

    <!-- 父组件 -->
    <template>
      <div>
        <child-component @update-message="handleMessageUpdate"></child-component>
        <p>{{ message }}</p>
      </div>
    </template>
    
    <script>
    import ChildComponent from './ChildComponent.vue';
    
    export default {
      data() {
        return {
          message: 'Hello from Parent'
        };
      },
      methods: {
        handleMessageUpdate(newMessage) {
          this.message = newMessage;
        }
      },
      components: {
        ChildComponent
      }
    };
    </script>
    
    <!-- 子组件 -->
    <template>
      <button @click="updateParentMessage">Update Parent Message</button>
    </template>
    
    <script>
    export default {
      methods: {
        updateParentMessage() {
          this.$emit('update-message', 'Hello from Child');
        }
      }
    };
    </script>
    
  3. 兄弟组件通信(通过事件总线)
    兄弟组件之间可以通过事件总线进行通信。

    const EventBus = new Vue();
    
    // 兄弟组件 A
    EventBus.$emit('event-name', data);
    
    // 兄弟组件 B
    EventBus.$on('event-name', (data) => {
      // 处理数据
    });
    
  4. 通过 provide/inject 传递数据
    provideinject 用于祖先组件和子代组件之间的数据传递,可以实现多层级组件的通信。

    // 父组件
    provide() {
      return {
        message: 'Provided Message'
      };
    }
    
    // 子组件
    inject: ['message']
    

2. Vue Router(路由管理)

Vue Router 是 Vue.js 官方的路由管理器,用于创建单页应用(SPA)。它允许你在不同的 URL 地址之间切换,并且无需重新加载页面。

Vue Router 的核心功能

  1. 路由配置
    路由是 URL 与组件之间的映射关系。

    import Vue from 'vue';
    import VueRouter from 'vue-router';
    import HomeComponent from './components/Home.vue';
    import AboutComponent from './components/About.vue';
    
    Vue.use(VueRouter);
    
    const routes = [
      { path: '/', component: HomeComponent },
      { path: '/about', component: AboutComponent }
    ];
    
    const router = new VueRouter({
      routes
    });
    
    new Vue({
      router,
      render: h => h(App)
    }).$mount('#app');
    
  2. 路由导航守卫
    路由守卫允许在进入或离开某个页面时执行特定操作。

    router.beforeEach((to, from, next) => {
      // 执行权限检查等逻辑
      next();
    });
    
  3. 动态路由
    动态路由用于匹配不同参数的 URL。

    const routes = [
      { path: '/user/:id', component: UserComponent }
    ];
    
  4. 嵌套路由
    Vue Router 支持在组件内部定义嵌套路由,用于复杂的页面布局。

    const routes = [
      {
        path: '/parent',
        component: ParentComponent,
        children: [
          { path: 'child', component: ChildComponent }
        ]
      }
    ];
    

3. Vuex(状态管理)

Vuex 是 Vue.js 的状态管理库,适用于管理复杂的应用状态。它将组件的共享状态集中在一个 store 中,方便在应用中多个组件之间共享数据。

Vuex 核心概念

  1. State(状态)
    State 是 Vuex 的核心,它存储了应用中的共享数据。

    const store = new Vuex.Store({
      state: {
        count: 0
      }
    });
    
  2. Getters(派生状态)
    Getters 用于从状态中派生出新的数据。

    const store = new Vuex.Store({
      state: { count: 0 },
      getters: {
        doubleCount: state => state.count * 2
      }
    });
    
  3. Mutations(变更状态)
    Mutations 用于同步更新状态,必须是同步操作。

    const store = new Vuex.Store({
      state: { count: 0 },
      mutations: {
        increment(state) {
          state.count++;
        }
      }
    });
    
  4. Actions(异步操作)
    Actions 用于执行异步操作,然后提交 mutation。

    const store = new Vuex.Store({
      state: { count: 0 },
      actions: {
        incrementAsync({ commit }) {
          setTimeout(() => {
            commit('increment');
          }, 1000);
        }
      }
    });
    

4. 生命周期钩子

Vue 提供了生命周期钩子,让开发者可以在组件的不同阶段执行代码。常见的生命周期钩子包括:

  1. beforeCreate:实例初始化后,数据观测和事件配置之前调用。
  2. created:实例创建完成,数据观测和事件处理已经完成,但未挂载到 DOM。
  3. beforeMount:在挂载之前调用。
  4. mounted:组件挂载到 DOM 上后调用。
  5. beforeUpdate:数据发生变化且 DOM 重新渲染之前调用。
  6. updated:数据变化导致 DOM 更新后调用。
  7. beforeDestroy:实例销毁之前调用。
  8. destroyed:实例销毁后调用。

示例:

export default {
  data() {
    return { message: 'Hello' };
  },
  created() {
    console.log('Component has been created');
  },
  mounted() {
    console.log('Component has been mounted');
  },
  beforeDestroy() {
    console.log('Component is about to be destroyed');
  }
};

5. 插槽与作用域插槽

插槽

插槽允许开发者向子组件传递 HTML 结构。

<!-- 父组件 -->
<template>
  <child-component>
    <p>This is a slot content</p>
  </child-component>
</template>

<!-- 子组件 -->
<template>
  <div>
    <slot></slot>
  </div>
</template>

作用域插槽

作用域插槽允许子组件向父组件提供数据,父组件通过插槽访问这些数据。

<!-- 父组件 -->
<template>
  <child-component v-slot="{ data }">
    <p>{{ data }}</p>
  </child-component>
</template>

<!-- 子组件 -->
<template>
  <div>
    <slot :data="message"></slot>
  </div>
</template>

<script>
export default {
  data() {
    return { message: 'Hello from child' };
  }
};
</script>

6. Vue 组件库(Element UI、Ant Design Vue)

Vue 的组件库极大简化了开发过程,常见的库有 Element UI 和 Ant Design Vue。

Element UI

Element UI 是一套基于 Vue.js 的桌面端组件库,提供了丰富的 UI 组件。

<template>
  <el-button type="primary">Primary Button</el-button>
</template>

<script>
import { Button } from 'element-ui';
export default {
  components: {
    'el-button': Button
  }
};
</script>

Ant Design Vue

Ant Design Vue 是一套高质量的 Vue 组件库,基于 Ant Design 设计体系,适用于企业级后台系统。

<template>
  <a-button type="primary">Primary

 Button</a-button>
</template>

<script>
import { Button } from 'ant-design-vue';
export default {
  components: {
    'a-button': Button
  }
};
</script>