10 个超强 Vue3 实战指南,由此突破新特性!(上)

简介: 本篇介绍 10 点如何从实战中学习突破 Vue JS 3 的新特性,细细看完,一定会有收获~

image.png

本篇介绍 10 点如何从实战中学习突破 Vue JS 3 的新特性,细细看完,一定会有收获~

主体译自:【Vue JS 3 — The Practical Guide】

更多学习资料:【https://github.com/Jerga99/vue-3-updates】


你的点赞投票是我最大的动力,关注走一波,【2021】有更多好看~!😀😀😀


初始化挂载



在 Vue2 中,我们在 main.js 通常这样进行初始化挂载:


new Vue({
  render: h => h(App),
  components: { App }
}).$mount('#app')


在 Vue3 中,调整为这样:


import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app')


为什么发生这样的变化?原因是:如果我们在 Vue2 中创建多个 Vue 实例,那么所有应用(#app)都会共享全局相同的配置。


// 全局共享、相互影响
Vue.mixin({
  /* ... */
})
Vue.directive('...', {
  ...
})
const app1 = new Vue({ el: '#app-1' })
const app2 = new Vue({ el: '#app-2' })


显然,这并不是我们想要的。在 Vue3 中,你可以创建多个实例,且每个实例都可以拥有单独的配置。


import { createApp } from 'vue'
import App1 from './App1.vue'
import App2 from './App2.vue'
const app1 = createApp(App1)
const app2 = createApp(App2)
app1.mount('#app-1')
app2.mount('#app-2')
app1.directive('...', {
  ...
})
app2.directive('...', {
  ...
})


但是,这也并不影响我们设置共享全局配置,我们可以通过如下工厂函数方式实现:


import { createApp } from 'vue';
import App1 from './App1.vue';
import App2 from './App2.vue';
const createApp = (Instance) => {
    const App = createApp(Instance);
  App.directive('i-am-cool', {
      inserted: () => {
      console.log('I am cool!');
    },
  });
}
createIdolApp(App1).mount('#app-1');
createIdolApp(App2).mount('#app-2');


Composition API



受到 React 的启发,Vue3 引入 Composition API 和 “hook” 函数。有了它,Vue 组件的使用变得更加灵活,也变得更加强大。特别是针对大型应用,以下会给出示例。

以前在 Vue2 中我们是这样写组件的:获取数据,设置数据。


<script>
import { fetchResources } from '@/actions'
import ResourceDetail from '@/components/ResourceDetail'
import ResourceList from '@/components/ResourceList'
export default {
  components: {
    ResourceDetail,
    ResourceList,
  },
  data() {
    return {
      title: 'Your resources',
      selectedResource: null,
      resources: []
    }
  },
  async created() {
    this.resources = await fetchResources()
  },
  computed: {
    hasResources() {
      return this.resourceCount > 0
    },
    activeResource() {
      return this.selectedResource || (this.hasResources && this.resources[0]) || null
    },
    resourceCount(){
      return this.resources.length
    }
  },
  methods: {
    selectResource(resource) {
      this.selectedResource = {...resource}
    }
  }
}
</script>


完整代码在这里

如果我们使用 composition API,会是这样写:


import { ref, onMounted, computed } from 'vue'
import { fetchResources } from '@/actions'
export default function useResources() {
  const resources = ref([])
  const getResources = async () => resources.value = await fetchResources()
  onMounted(getResources);
  const resourceCount = computed(() => resources.value.length)
  const hasResources = computed(() => resourceCount.value > 0 )
  return {
    resources,
    resourceCount,
    hasResources
  }
}


这是一个非常简单的 Composition function 实现了获取 resources 数据的功能。

Composition 函数通常用 use 开头作为关键字,比如此处的 “useResources”,以此区别于普通函数。


下面针对以上代码关键点进行一一释义:


1.ref 会创建一个动态对象。如果你要从 ref 获取原始值,则需要取 “value” 属性,比如 —— resources.value


看以下示例:

var a = 7;
var b = a;
b = 10;
// a = 7
// b = 10
var a = ref(7);
var b = a;
b.value = 100;
// a = 100
// b = 100


我们将返回的 resoure 数组设置为 ref。是因为如果数组有新增项或移除项,这样做能在程序中有所表现。


一图胜万言:

image.png

2.getResources 函数用于获取数据。

3.onMounted 生命周期函数会在组件添加到 Dom 时调用。

4.computed 属性会随着它的依赖(resources or resourceCount)变化而重新计算。

5.  return 最后一步我们将返回 data/function,我们再向组件暴露 useResource hook 函数以供使用。


最终 hook-in:

<script>
import ResourceDetail from '@/components/ResourceDetail'
import ResourceList from '@/components/ResourceList'
import useResources from '@/composition/useResources';
export default {
  components: {
    ResourceDetail,
    ResourceList,
  },
  data() {
    return {
      title: 'Your resources',
      selectedResource: null
    }
  },
  setup() {
    return {
      ...useResources() // 在 setup 里
    }
  },
  computed: {
    activeResource() {
      return this.selectedResource || (this.hasResources && this.resources[0]) || null
    }
  },
  methods: {
    selectResource(resource) {
      this.selectedResource = {...resource}
    }
  }
}
</script>


我们再 setup 中进行引用,返回值都可以再通过 this 进行调用。

我们在 computed 和 methods 也能同样进行调用 Composition 函数的返回。

注意:setup 钩子函数执行在组件实例创建(created)之前。


在组件创建前 setup 中 hook 被执行,只要 props 被解析,服务就会以 composition API 作为入口。因为此时当 setup 执行时,组件实例还未生成,没有 this 对象。

神奇吗?我们就这样将获取数据进行封装然后应用到了 hook 调用中。

再写一个对 resources 资源进行搜索过滤的功能:


  • useSearchResource
import { ref, computed } from 'vue'
export default function useSearchResource(resources) {
  const searchQuery = ref('')
  const setSearchQuery = searched => {
    searchQuery.value = searched
  }
  const searchedResources = computed(() => {
    if (!searchQuery.value) {
      return resources.value
    }
    const lcSearch = searchQuery.value.toLocaleLowerCase();
    return resources.value.filter(r => {
      const title = r?.title.toLocaleLowerCase()
      return title.includes(lcSearch)
    })
  })
  return {
    setSearchQuery,
    searchedResources
  }
}


  • useResources
export default function useResources() {
  const resources = ref([])
  const getResources = async () => resources.value = await fetchResources()
  onMounted(getResources);
  const resourceCount = computed(() => resources.value.length)
  const hasResources = computed(() => resourceCount.value > 0 )
  const { searchedResources, setSearchQuery } = useSearchResources(resources)
  return {
    resources: searchedResources,
    resourceCount,
    hasResources,
    setSearchQuery
  }
}


拆解分析:

  1. searchQuery 包含一个空字符串,使用了 ref,computed searchedResources 可以检测 searchQuery 的变化值。
  2. setSearchQuery 是一个简单的赋值给 searchQuery 的函数。
  3. searchedResources会在 searchQuery 或 resources 变化的时候触发。
  4. searchedResources 负责过滤 resources。每个 resource 包含一个 title,如果 title 包含 searchedQuery 字符串,那么 resource 就会被加入到 searchedResources 数组中。
  5. 最后函数返回 setSearchQuerysearchedResourced,再在 useResources 中进行引用及返回。


再看下在组件中使用它到底有多简单:

<template>
...
<input
  @keyup="handleSearch"
  type="text"
  class="form-control"
  placeholder="Some title" />
...
</template>
<script>
...
methods: {
  ...
  handleSearch(e) {
    this.setSearchQuery(e.target.value)
  }
}
...
</script>


真有你的! 无论何时执行 setSearchQuery 更改 searchQuery 的值,都将重新执行 searchedResources 将其进行过滤操作并返回结果。

以上便是超重要的新特性 composition API 的实战介绍。


Data 选项



在 Vue2 中,data选项不是对象就函数,但是在 Vue3 中将只能是函数。这将被统一成标准。


<script>
  export default {
    data() {
      return {
        someData: '1234'
      }
    }
  }
</script>


Filters 被移除



不会再出现这样的写法:

<h1>{{title | capitalized }} </h1>


这样的表达式不是合法有效的 Javascript,在 Vue 中实现这样的写法需要额外的成本。它可以很容易被转化为计算属性或函数。


computed: {
 capitalizedTitle() {
   return title[0].toUpperCase + title.slice(1);
  }
}


多个根标签



在 Vue2 中我们经常这样包裹我们的根标签:


<template>
  <div>
    <h1>...</h1>
    <div class="container">...</div>
    ...
  </div>
</template>


在 Vue3 中将不再有此限制:


<template>
  <h1>...</h1>
  <div class="container">...</div>
  ...
</template>


Suspense


Suspense 是一种特殊的 Vue 组件,用于解析有异步数据的组件。


比如:

<Suspense>
  <template #default>
    <AsyncComponent>
  </template>
  <template #fallback>
    Loading Data...
  </template>
</Suspense>


使用新的 Composition API,setup 可设置异步函数。Suspense 可以展示异步的模板直到 setup 被解析完。


实战代码:

<template>
  Welcome, {{user.name}}
</template>
<script>
  import { fetchUser } from '@/actions';
  export default {
    async setup() {
      const user = await fetchUser();
      return { user }
    }
  }
</script>
<Suspense>
  <template #default>
    <UserPanel/>
  </template>
  <template #fallback>
    Loading user ...
  </template>
</Suspense>


相关文章
|
1月前
|
JavaScript 前端开发 安全
Vue 3
Vue 3以组合式API、Proxy响应式系统和全面TypeScript支持,重构前端开发范式。性能优化与生态协同并进,兼顾易用性与工程化,引领Web开发迈向高效、可维护的新纪元。(238字)
502 139
|
6月前
|
人工智能 自然语言处理 JavaScript
通义灵码2.5实战评测:Vue.js贪吃蛇游戏一键生成
通义灵码基于自然语言需求,快速生成完整Vue组件。例如,用Vue 2和JavaScript实现贪吃蛇游戏:包含键盘控制、得分系统、游戏结束判定与Canvas动态渲染。AI生成的代码符合规范,支持响应式数据与事件监听,还能进阶优化(如增加启停按钮、速度随分数提升)。传统需1小时的工作量,使用通义灵码仅10分钟完成,大幅提升开发效率。操作简单:安装插件、输入需求、运行项目即可实现功能。
377 4
 通义灵码2.5实战评测:Vue.js贪吃蛇游戏一键生成
|
1月前
|
缓存 JavaScript 算法
Vue 3性能优化
Vue 3 通过 Proxy 和编译优化提升性能,但仍需遵循最佳实践。合理使用 v-if、key、computed,避免深度监听,利用懒加载与虚拟列表,结合打包优化,方可充分发挥其性能优势。(239字)
213 1
|
2月前
|
开发工具 iOS开发 MacOS
基于Vite7.1+Vue3+Pinia3+ArcoDesign网页版webos后台模板
最新版研发vite7+vue3.5+pinia3+arco-design仿macos/windows风格网页版OS系统Vite-Vue3-WebOS。
375 11
|
1月前
|
JavaScript 安全
vue3使用ts传参教程
Vue 3结合TypeScript实现组件传参,提升类型安全与开发效率。涵盖Props、Emits、v-model双向绑定及useAttrs透传属性,建议明确声明类型,保障代码质量。
254 0
|
3月前
|
缓存 前端开发 大数据
虚拟列表在Vue3中的具体应用场景有哪些?
虚拟列表在 Vue3 中通过仅渲染可视区域内容,显著提升大数据列表性能,适用于 ERP 表格、聊天界面、社交媒体、阅读器、日历及树形结构等场景,结合 `vue-virtual-scroller` 等工具可实现高效滚动与交互体验。
431 1
|
3月前
|
缓存 JavaScript UED
除了循环引用,Vue3还有哪些常见的性能优化技巧?
除了循环引用,Vue3还有哪些常见的性能优化技巧?
245 0
|
4月前
|
JavaScript
vue3循环引用自已实现
当渲染大量数据列表时,使用虚拟列表只渲染可视区域的内容,显著减少 DOM 节点数量。
136 0
|
6月前
|
JavaScript 前端开发 API
Vue 2 与 Vue 3 的区别:深度对比与迁移指南
Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架,在过去的几年里,Vue 2 一直是前端开发中的重要工具。而 Vue 3 作为其升级版本,带来了许多显著的改进和新特性。在本文中,我们将深入比较 Vue 2 和 Vue 3 的主要区别,帮助开发者更好地理解这两个版本之间的变化,并提供迁移建议。 1. Vue 3 的新特性概述 Vue 3 引入了许多新特性,使得开发体验更加流畅、灵活。以下是 Vue 3 的一些关键改进: 1.1 Composition API Composition API 是 Vue 3 的核心新特性之一。它改变了 Vue 组件的代码结构,使得逻辑组
1746 0
|
2月前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
311 2

热门文章

最新文章