当前位置: 首页 > article >正文

Vue 3 部分新特性解析

1. 引言

Vue 3 引入了许多新特性和改进,使得开发更加高效和灵活。本文将深入探讨 Vue 3 的高阶部分,包括 Composition API、自定义指令、插件开发、状态管理和性能优化。

2. Composition API

2.1 引入 Composition API

Composition API 是 Vue 3 中引入的一种新的代码组织方式,它允许你更灵活地组织和复用逻辑。

2.1.1 基本用法

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { ref } from 'vue';

export default {
  setup() {
    const count = ref(0);
    const increment = () => {
      count.value++;
    };

    return {
      count,
      increment
    };
  }
};
</script>

2.1.2 使用多个逻辑组合

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
    <p>Double Count: {{ doubleCount }}</p>
  </div>
</template>

<script>
import { ref, computed } from 'vue';

export default {
  setup() {
    const count = ref(0);
    const increment = () => {
      count.value++;
    };

    const doubleCount = computed(() => count.value * 2);

    return {
      count,
      increment,
      doubleCount
    };
  }
};
</script>

2.2 生命周期钩子

在 Composition API 中,生命周期钩子以 on 开头。

<template>
  <div>
    <p>Component is mounted!</p>
  </div>
</template>

<script>
import { onMounted } from 'vue';

export default {
  setup() {
    onMounted(() => {
      console.log('Component is mounted!');
    });

    return {};
  }
};
</script>

3. 自定义指令

3.1 创建自定义指令

自定义指令可以让你对 DOM 元素进行底层操作。

<template>
  <div v-focus></div>
</template>

<script>
export default {
  directives: {
    focus: {
      mounted(el) {
        el.focus();
      }
    }
  }
};
</script>

3.2 全局注册自定义指令

// main.js
import { createApp } from 'vue';
import App from './App.vue';

const app = createApp(App);

app.directive('focus', {
  mounted(el) {
    el.focus();
  }
});

app.mount('#app');

4. 插件开发

4.1 创建插件

插件可以用来扩展 Vue 的功能。

// myPlugin.js
export default {
  install(app, options) {
    app.config.globalProperties.$myMethod = function (methodOptions) {
      console.log(options, methodOptions);
    };
  }
};

4.2 使用插件

// main.js
import { createApp } from 'vue';
import App from './App.vue';
import MyPlugin from './myPlugin';

const app = createApp(App);

app.use(MyPlugin, { someOption: true });

app.mount('#app');

5. 状态管理

5.1 使用 Vuex 4

Vuex 是 Vue 的状态管理库,适用于大型应用。

5.1.1 安装 Vuex

npm install vuex@next

5.1.2 创建 Store

// store/index.js
import { createStore } from 'vuex';

export default createStore({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    increment({ commit }) {
      commit('increment');
    }
  },
  getters: {
    doubleCount: (state) => state.count * 2
  }
});

5.1.3 使用 Store

// main.js
import { createApp } from 'vue';
import App from './App.vue';
import store from './store';

const app = createApp(App);

app.use(store);

app.mount('#app');

5.1.4 在组件中使用

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { mapState, mapGetters, mapActions } from 'vuex';

export default {
  computed: {
    ...mapState(['count']),
    ...mapGetters(['doubleCount'])
  },
  methods: {
    ...mapActions(['increment'])
  }
};
</script>

5.2 使用 Pinia

Pinia 是 Vue 3 的新状态管理库,更简单易用。

5.2.1 安装 Pinia

npm install pinia

5.2.2 创建 Store

// stores/counter.js
import { defineStore } from 'pinia';

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++;
    }
  },
  getters: {
    doubleCount: (state) => state.count * 2
  }
});

5.2.3 使用 Store

// main.js
import { createApp } from 'vue';
import App from './App.vue';
import { createPinia } from 'pinia';

const app = createApp(App);
const pinia = createPinia();

app.use(pinia);

app.mount('#app');

5.2.4 在组件中使用

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { useCounterStore } from '../stores/counter';

export default {
  setup() {
    const counterStore = useCounterStore();

    return {
      count: counterStore.count,
      doubleCount: counterStore.doubleCount,
      increment: counterStore.increment
    };
  }
};
</script>

6. 性能优化

6.1 使用 v-once

v-once 可以用于渲染静态内容,避免不必要的更新。

<template>
  <div v-once>
    <p>This content will never change.</p>
  </div>
</template>

6.2 使用 v-memo

v-memo 可以缓存计算属性的结果,避免不必要的重新计算。

<template>
  <div v-memo="[list]">
    <ul>
      <li v-for="item in list" :key="item.id">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      list: [
        { id: 1, name: 'Item 1' },
        { id: 2, name: 'Item 2' }
      ]
    };
  }
};
</script>

6.3 使用 key

key 属性可以强制 Vue 重新渲染组件。

<template>
  <div>
    <button @click="toggle">Toggle</button>
    <component :is="currentComponent" :key="currentComponent"></component>
  </div>
</template>

<script>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';

export default {
  components: {
    ComponentA,
    ComponentB
  },
  data() {
    return {
      currentComponent: 'ComponentA'
    };
  },
  methods: {
    toggle() {
      this.currentComponent = this.currentComponent === 'ComponentA' ? 'ComponentB' : 'ComponentA';
    }
  }
};
</script>

6.4 使用 keep-alive

keep-alive 可以缓存组件实例,避免重新创建和销毁。

<template>
  <div>
    <button @click="toggle">Toggle</button>
    <keep-alive>
      <component :is="currentComponent"></component>
    </keep-alive>
  </div>
</template>

<script>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';

export default {
  components: {
    ComponentA,
    ComponentB
  },
  data() {
    return {
      currentComponent: 'ComponentA'
    };
  },
  methods: {
    toggle() {
      this.currentComponent = this.currentComponent === 'ComponentA' ? 'ComponentB' : 'ComponentA';
    }
  }
};
</script>

http://www.kler.cn/a/538706.html

相关文章:

  • git fetch和git pull 的区别
  • 【Qt 常用控件】输入类控件1(QLineEdit和QTextEdit 输入框)
  • 小红书提出新面部视频交换方法DynamicFace,可生成高质量且一致的视频面部图像。
  • 网络安全:挑战、技术与未来发展
  • TaskBuilder项目实战:创建项目
  • 数字化转型的三个阶段:信息化、数字化、数智化
  • 【Unity】从父对象中获取子对象组件的方式
  • RNN-day1-NLP基础
  • 大模型推理——MLA实现方案
  • 寒假集训思维训练1题解
  • node 程序占用处理方法与后台运行方法
  • Qt 支持的动画格式对比,Lottie/APNG/GIF/WEBP
  • 已经安装了Visual C++ 2015-2022 Redistributable,但运行程序时,提示找不到VCRUNIME140_1D.dll
  • 通过多层混合MTL结构提升股票市场预测的准确性,R²最高为0.98
  • 【Java基础】序列化、反序列化和不可变类
  • HTML 颜色值
  • 蓝桥杯备赛——进制转化相关问题
  • 数据结构(Java)—— 优先级队列(堆)
  • 深度整理总结MySQL——事务隔离级别实现原理
  • 昇腾,mindie,镜像,部署vllm:第1篇,安装新的docker 镜像
  • 【MySQL】第一弹---MySQL 在 Centos 7环境安装
  • 前端高级面试题及其答案
  • git SourceTree 使用
  • 工作案例 - python绘制excell表中RSRP列的CDF图
  • 登录到docker里
  • 在 NXP Yocto 环境下实现 Qualcomm Wi-Fi Driver 的 GitLab CI/CD