实用的Vue开发技巧

1 状态共享

随着组件的细化,就会遇到多组件状态共享的情况,Vuex当然可以解决这类问题,不过就像Vuex官方文档所说的,如果应用不够大,为避免代码繁琐冗余,最好不要使用它,今天我们介绍的是vue.js 2.6新增加的Observable API,通过使用这个api我们可以应对一些简单的跨组件数据状态共享的情况。

如下这个例子,我们将在组件外创建一个store,然后在App.vue组件里面使用store.js提供的store和mutation方法,同理其它组件也可以这样使用,从而实现多个组件共享数据状态。

首先创建一个store.js,包含一个store和一个mutations,分别用来指向数据和处理方法。

import Vue from "vue";
export const store = Vue.observable({ count: 0 });
export const mutations = {
setCount(count) {
store.count = count;
}
};

然后在App.vue里面引入这个store.js,在组件里面使用引入的数据和方法

<template>
<div id="app">
<img width="25%" src="./assets/logo.png">
<p>count:{{count}}</p>
<button @click="setCount(count+1)">+1</button>
<button @click="setCount(count-1)">-1</button>
</div>
</template>
<script>
import { store, mutations } from "./store";
export default {
name: "App",
computed: {
count() {
return store.count;
}
},
methods: {
setCount: mutations.setCount
}
};
</script>
<style>

你可以点击在线DEMO查看最终效果

2 长列表性能优化

我们应该都知道vue会通过object.defineProperty对数据进行劫持,来实现视图响应数据的变化,然而有些时候我们的组件就是纯粹的数据展示,不会有任何改变,我们就不需要vue来劫持我们的数据,在大量数据展示的情况下,这能够很明显的减少组件初始化的时间,那如何禁止vue劫持我们的数据呢?可以通过object.freeze方法来冻结一个对象,一旦被冻结的对象就再也不能被修改了。

export default {
data: () => ({
users: {}
}),
async created() {
const users = await axios.get("/api/users");
this.users = Object.freeze(users);
}
};

另外需要说明的是,这里只是冻结了users的值,引用不会被冻结,当我们需要reactive数据的时候,我们可以重新给users赋值。

export default {
data: () => ({
users: []
}),
async created() {
const users = await axios.get("/api/users");
this.users = Object.freeze(users);
},
methods:{
// 改变值不会触发视图响应
this.users[0] = newValue
// 改变引用依然会触发视图响应
this.users = newArray
}
};

3 去除多余的样式

随着项目越来越大,书写的不注意,不自然的就会产生一些多余的css,小项目还好,一旦项目大了以后,多余的css会越来越多,导致包越来越大,从而影响项目运行性能,所以有必要在正式环境去除掉这些多余的css,这里推荐一个库purgecss,支持CLI、JavascriptApi、Webpack等多种方式使用,通过这个库,我们可以很容易的去除掉多余的css。

我做了一个测试,在线DEMO

<h1>Hello Vanilla!</h1>
<div>
We use Parcel to bundle this sandbox, you can find more info about Parcel
<a href="https://parceljs.org" rel="external nofollow" target="_blank" rel="noopener noreferrer">here</a>.
</div>
body {
font-family: sans-serif;
}
a {
color: red;
}
ul {
li {
list-style: none;
}
}
import Purgecss from "purgecss";
const purgecss = new Purgecss({
content: ["**/*.html"],
css: ["**/*.css"]
});
const purgecssResult = purgecss.purge();

最终产生的purgecssResult结果如下,可以看到多余的a和ul标签的样式都没了

4 作用域插槽

利用好作用域插槽可以做一些很有意思的事情,比如定义一个基础布局组件A,只负责布局,不管数据逻辑,然后另外定义一个组件B负责数据处理,布局组件A需要数据的时候就去B里面去取。假设,某一天我们的布局变了,我们只需要去修改组件A就行,而不用去修改组件B,从而就能充分复用组件B的数据处理逻辑,关于这块我之前写过一篇实际案例,可以点击这里查看。

这里涉及到的一个最重要的点就是父组件要去获取子组件里面的数据,之前是利用slot-scope,自vue 2.6.0起,提供了更好的支持 slot 和 slot-scope 特性的 API 替代方案。
比如,我们定一个名为current-user的组件:

<span>
<slot>{{ user.lastName }}</slot>
</span>

父组件引用current-user的组件,但想用名替代姓(老外名字第一个单词是名,后一个单词是姓):

<current-user>
{{ user.firstName }}
</current-user>

这种方式不会生效,因为user对象是子组件的数据,在父组件里面我们获取不到,这个时候我们就可以通过v-slot
来实现。

首先在子组件里面,将user作为一个<slot>元素的特性绑定上去:

<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>

之后,我们就可以在父组件引用的时候,给v-slot带一个值来定义我们提供的插槽 prop 的名字:

<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>

这种方式还有缩写语法,可以查看独占默认插槽的缩写语法,最终我们引用的方式如下:

<current-user v-slot="slotProps">
{{ slotProps.user.firstName }}
</current-user>

相比之前slot-scope代码更清晰,更好理解。

5 属性事件传递

写过高阶组件的童鞋可能都会碰到过将加工过的属性向下传递的情况,如果碰到属性较多时,需要一个个去传递,非常不友好并且费时,有没有一次性传递的呢(比如react里面的{...this.props})?答案就是v-bind和v-on。
举个例子,假如有一个基础组件BaseList,只有基础的列表展示功能,现在我们想在这基础上增加排序功能,这个时候我们就可以创建一个高阶组件SortList。

<!-- SortList -->
<template>
<BaseList v-bind="$props" v-on="$listeners"> <!-- ... --> </BaseList>
</template>
<script>
import BaseList from "./BaseList";
// 包含了基础的属性定义
import BaseListMixin from "./BaseListMixin";
// 封装了排序的逻辑
import sort from "./sort.js";
export default {
props: BaseListMixin.props,
components: {
BaseList
}
};
</script>

可以看到传递属性和事件的方便性,而不用一个个去传递

6 函数式组件

函数式组件,即无状态,无法实例化,内部没有任何生命周期处理方法,非常轻量,因而渲染性能高,特别适合用来只依赖外部数据传递而变化的组件。

写法如下:

1.在template标签里面标明functional

2.只接受props值

3.不需要script标签

<!-- App.vue -->
<template>
<div id="app">
<List
:items="['Wonderwoman', 'Ironman']"
:item-click="item => (clicked = item)"
/>
<p>Clicked hero: {{ clicked }}</p>
</div>
</template>
<script>
import List from "./List";
export default {
name: "App",
data: () => ({ clicked: "" }),
components: { List }
};
</script>
<!-- List.vue 函数式组件 -->
<template functional>
<div>
<p v-for="item in props.items" @click="props.itemClick(item);">
{{ item }}
</p>
</div>
</template>

7 监听组件的生命周期

比如有父组件Parent和子组件Child,如果父组件监听到子组件挂载mounted就做一些逻辑处理,常规的写法可能如下:

// Parent.vue
<Child @mounted="doSomething"/>
// Child.vue
mounted() {
this.$emit("mounted");
}

这里提供一种特别简单的方式,子组件不需要任何处理,只需要在父组件引用的时候通过@hook来监听即可,代码重写如下:

<Child @hook:mounted="doSomething"/>

当然这里不仅仅是可以监听mounted,其它的生命周期事件,例如:created,updated等都可以,是不是特别方便~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • vue的传参方式汇总和router使用技巧

    vue传参方法一 1,路由配置 { path: '/describe/:id', name: 'Describe', component: Describe } 2,使用方法 // 直接调用$router.push 实现携带参数的跳转 this.$router.push({ // 这个id是一个变量,随便是什么值都可以 path: /describe/${id}`, }) 3,获取方法(在describe页面) $route.params.id 使用以上方法可以拿到上个页面传过来的id值 vue

  • 详解vuex commit保存数据技巧

    vuex 单向数据流,推荐的commit 改变state数据,写起来非常繁琐,因为改数据可能要写很多commit函数. 依据我的理解,单向数据流主要是为了避免数据混乱,便于调试. 说白了,就是一个数据改变了,是什么促使他改变的. 数据流向永远都是一个方向,下游是没有权利改变数据的,所以需要数据发放中心同一级的方法来改变数据. 单项数据流,对于react来说,的确是必要的,但对于vue来说,是那么有必要吗? vue采用数据依赖更新,必要的数据都采用Object.defineProperty处理.给

  • Vue项目中最新用到的一些实用小技巧

    写在前面 在最近的 Vue 项目中,为了完成需求使用了一些小技巧,做个笔记,或许也能帮到道友. 阅读重点 需求一:为路径配置别名 在开发过程中,我们经常需要引入各种文件,如图片.CSS.JS等,为了避免写很长的相对路径(../),我们可以为不同的目录配置一个别名. 找到 webpack.base.config.js 中的 resolve 配置项,在其 alias 中增加别名,如下: 创建一个 CSS 文件,随便写点样式: .avatar display: flex; justify-conten

  • vue使用技巧及vue项目中遇到的问题

    这里给大家分享一下vue中的一些技巧,希望对大家有用处.(话不多说上代码) 1,vue路由拦截浏览器后退实现表单保存类似需求(为了防止用户突然离开,没有保存已输入的信息.) //在路由组件中: mounted(){ }, beforeRouteLeave (to, from, next) { if(用户已经输入信息){ //出现弹窗提醒保存表单,或者自动后台为其保存 }else{ next(true);//用户离开 } 请参考vue文档全局钩子和组件钩子 2,路由懒加载写法: // 我所采用的方

  • 你不知道的Vue技巧之--开发一个可以通过方法调用的组件(推荐)

    Vue作为最近最炙手可热的前端框架,其简单的入门方式和功能强大的API是其优点.而同时因为其API的多样性和丰富性,所以他的很多开发方式就和一切基于组件的React不同,如果没有对Vue的API(有一些甚至文档都没提到)有一个全面的了解,那么在开发和设计一个组件的时候有可能就会绕一个大圈子,所以我非常推荐各位在学习Vue的时候先要对Vue核心的所有API都有一个了解. 举个例子,通知组件notification基本是现代web开发标配,在很多地方都能用到.而在以Vue作为核心框架的前端项目中,因

  • 实用的Vue开发技巧

    1 状态共享 随着组件的细化,就会遇到多组件状态共享的情况,Vuex当然可以解决这类问题,不过就像Vuex官方文档所说的,如果应用不够大,为避免代码繁琐冗余,最好不要使用它,今天我们介绍的是vue.js 2.6新增加的Observable API,通过使用这个api我们可以应对一些简单的跨组件数据状态共享的情况. 如下这个例子,我们将在组件外创建一个store,然后在App.vue组件里面使用store.js提供的store和mutation方法,同理其它组件也可以这样使用,从而实现多个组件共享

  • 八个一看就觉得很棒的Vue开发技巧分享

    目录 1.路由参数解耦 2.功能组件 3.样式范围 4.watch的高级使用 5.watch监听多个变量 6.事件参数$event 7.程序化事件监听器 8.监听组件生命周期 总结 1.路由参数解耦 通常在组件中使用路由参数,大多数人会做以下事情. export default { methods: { getParamsId() { return this.$route.params.id } } } 在组件中使用 $route 会导致与其相应路由的高度耦合,通过将其限制为某些 URL 来限制

  • 7个很棒的Vue开发技巧分享

    目录 1.路由参数解耦 2.功能组件 3.样式范围 4.watch的高级使用 5.watch监听多个变量 6.事件参数$event 7.程序化事件监听器 1.路由参数解耦 通常在组件中使用路由参数,大多数人会做以下事情. export default { methods: { getParamsId() { return this.$route.params.id } } } 在组件中使用 $route 会导致与其相应路由的高度耦合,通过将其限制为某些 URL 来限制组件的灵活性.正确的做法是通

  • Vue 开发必须知道的36个技巧(小结)

    前言 Vue 3.x 的Pre-Alpha 版本.后面应该还会有 Alpha.Beta 等版本,预计至少要等到 2020 年第一季度才有可能发布 3.0 正式版; 所以应该趁还没出来加紧打好 Vue2.x 的基础; Vue基本用法很容易上手,但是有很多优化的写法你就不一定知道了,本文从列举了 36 个 vue 开发技巧; 后续 Vue 3.x 出来后持续更新. 1.require.context() 1.场景:如页面需要导入多个组件,原始写法: import titleCom from '@/c

  • 分享12个Vue开发中的性能优化小技巧(实用!)

    目录 前言 1.长列表性能优化 1.不做响应式 2.虚拟滚动 2.v-for遍历避免同时使用v-if 3.列表使用唯一key 4.使用v-show复用DOM 5.无状态的组件用函数式组件 6.子组件分割 7.变量本地化 8.第三方插件按需引入 9.路由懒加载 10.keep-alive缓存页面 11.事件的销毁 12.图片懒加载 总结 前言 性能优化,是每一个开发者都会遇到的问题,特别是现在越来越重视体验,以及竞争越来越激烈的环境下,对于我们开发者来说,只完成迭代,把功能做好是远远不够的,最重要

  • vue开发心得和技巧分享

    这个系列记录我在一年vue开发中总结的一些经验和技巧. 利用Object.freeze()提升性能 Object.freeze()是ES5新增的特性,可以冻结一个对象,防止对象被修改. vue 1.0.18+对其提供了支持,对于data或vuex里使用freeze冻结了的对象,vue不会做getter和setter的转换. 如果你有一个巨大的数组或Object,并且确信数据不会修改,使用Object.freeze()可以让性能大幅提升.在我的实际开发中,这种提升大约有5~10倍,倍数随着数据量递

  • Vue开发中常见的套路和技巧总结

    属性排放 export default { name: '名称', components: { // 组件挂载a}, created(){} // 数据获取 beforeMount() {}, // 数据获取 data: () => ({}), //响应式数据 computed: {} // 计算属性集合 methods: {} // 方法集合 ... // 销毁页面不要的资源 } 管理请求加载状态 async beforeMount(){ // 开始加载 this.loading = true

  • 22个Vue优化技巧(项目实用)

    目录 代码优化 v-for 中使用 key v-if/v-else-if/v-else 中使用 key 合理的选择 v-if 和 v-show 使用简单的 计算属性 functional 函数式组件(Vue2) 拆分组件 使用局部变量 使用 KeepAlive 事件的销毁 图片加载 采用合理的数据处理算法 其他 首屏/体积优化 体积优化 代码分割 网络 演示代码使用 Vue3 + ts + Vite 编写,但是也会列出适用于 Vue2 的优化技巧,如果某个优化只适用于 Vue3 或者 Vue2,

  • AngularJS实用开发技巧(推荐)

    一.开端 Angular JS 是一组用来开发Web页面的框架.模板以及数据绑定和丰富UI组件.它提供web应用的架构,无需进行手工DOM操作. AngularJS很小,只有60K,兼容主流浏览器,与jQuery 配合良好. 二.基础原则了解 ①angular的一些入门了解 一.基础知识 1.angular放弃了IE8 2.四大核心分别是mvc.模块化.指令系统.双向数据绑定 二.一些原则 1.不要复用controller,一个控制器一般只负责一小块视图. 2.不要在controller里面操作

  • 60个很实用的jQuery代码开发技巧收集

    由于内容比较多建议用CTRL+F搜索 偶然在网上看到这些不错的jQuery代码开发技巧.原文收集了30个,另外查找的时候发现了还有20个.加上另外十个实用的jQuery代码片段,共60个代码技巧,收集在一起分享给大家. 1. 创建一个嵌套的过滤器 .filter(":not(:has(.selected))") //去掉所有不包含class为.selected的元素 2. 重用你的元素查询 var allItems = $("div.item"); var keep

随机推荐