你或许不知道Vue的这些小技巧

前言
用Vue开发一个网页并不难,但是也经常会遇到一些问题,其实大部分的问题都在文档中有所提及,再不然我们通过谷歌也能成功搜索到问题的答案,为了帮助小伙伴们提前踩坑,在遇到问题的时候,心里大概有个谱知道该如何去解决问题。这篇文章是将自己知道的一些小技巧,结合查阅资料整理成的一篇文章,如果喜欢的话可以点波赞/关注,支持一下,希望大家看完本文可以有所收获。

前端进阶积累、公众号、GitHub

文章内容总结:
组件style的scoped
Vue 数组/对象更新 视图不更新
vue filters 过滤器的使用
列表渲染相关
深度watch与watch立即触发回调
这些情况下不要使用箭头函数
路由懒加载写法
路由的项目启动页和404页面
Vue调试神器:vue-devtools
组件style的scoped:
问题:在组件中用js动态创建的dom,添加样式不生效。

场景:

<template>
     <div class="test"></div>
</template>
<script>
    let a=document.querySelector(‘.test‘);
    let newDom=document.createElement("div"); // 创建dom
    newDom.setAttribute("class","testAdd" ); // 添加样式
    a.appendChild(newDom); // 插入dom
</script>
<style scoped>
.test{
   background:blue;
    height:100px;
    width:100px;
}
.testAdd{
    background:red;
    height:100px;
    width:100px;
}
</style>

复制代码
结果:

// test生效 testAdd 不生效
<div data-v-1b971ada class="test"><div class="testAdd"></div></div>
.test[data-v-1b971ada]{ // 注意data-v-1b971ada
background:blue;
height:100px;
width:100px;
}
复制代码
原因:

当 <style> 标签有 scoped 属性时,它的 CSS 只作用于当前组件中的元素。

它会为组件中所有的标签和class样式添加一个scoped标识,就像上面结果中的data-v-1b971ada。

所以原因就很清楚了:因为动态添加的dom没有scoped添加的标识,没有跟testAdd的样式匹配起来,导致样式失效。

解决方式

推荐:去掉该组件的scoped
每个组件的css并不会很多,当设计到动态添加dom,并为dom添加样式的时候,就可以去掉scoped,会比下面的方法方便很多。

可以动态添加style

// 上面的栗子可以这样添加样式
newDom.style.height=‘100px‘;
newDom.style.width=‘100px‘;
newDom.style.background=‘red‘;
复制代码
Vue 数组/对象更新 视图不更新
很多时候,我们习惯于这样操作数组和对象:

 data() { // data数据
    return {
      arr: [1,2,3],
      obj:{
          a: 1,
          b: 2
      }
    };
  },

// 数据更新 数组视图不更新
this.arr[0] = ‘OBKoro1‘;
this.arr.length = 1;
console.log(arr);// [‘OBKoro1‘];
// 数据更新 对象视图不更新
this.obj.c = ‘OBKoro1‘;
delete this.obj.a;
console.log(obj); // {b:2,c:‘OBKoro1‘}
复制代码
由于js的限制,Vue 不能检测以上数组的变动,以及对象的添加/删除,很多人会因为像上面这样操作,出现视图没有更新的问题。

解决方式:

this.$set(你要改变的数组/对象,你要改变的位置/key,你要改成什么value)

this.$set(this.arr, 0, "OBKoro1"); // 改变数组
this.$set(this.obj, "c", "OBKoro1"); // 改变对象
复制代码
如果还是不懂的话,可以看看这个codependemo。

数组原生方法触发视图更新:
Vue可以监测到数组变化的,数组原生方法:

splice()、 push()、pop()、shift()、unshift()、sort()、reverse()

复制代码
意思是使用这些方法不用我们再进行额外的操作,视图自动进行更新。

推荐使用splice方法会比较好自定义,因为slice可以在数组的任何位置进行删除/添加操作,这部分可以看看我前几天写的一篇文章:【干货】js 数组详细操作方法及解析合集

替换数组/对象
比方说:你想遍历这个数组/对象,对每个元素进行处理,然后触发视图更新。

// 文档中的栗子: filter遍历数组,返回一个新数组,用新数组替换旧数组
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})
复制代码
举一反三:可以先把这个数组/对象保存在一个变量中,然后对这个变量进行遍历,等遍历结束后再用变量替换对象/数组。

并不会重新渲染整个列表:

Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的、启发式的方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。

如果你还是很困惑,可以看看Vue文档中关于这部分的解释。

vue filters 过滤器的使用:
过滤器,通常用于后台管理系统,或者一些约定类型,过滤。Vue过滤器用法是很简单,但是很多朋友可能都没有用过,这里稍微讲解一下。

在html模板中的两种用法:

<!-- 在双花括号中 -->
{{ message | filterTest }}
<!-- 在 `v-bind` 中 -->
<div :id="message | filterTest"></div>

复制代码
在组件script中的用法:

export default {
data() {
return {
message:1
}
},
filters: {
filterTest(value) {
// value在这里是message的值
if(value===1){
return ‘最后输出这个值‘;
}
}
}
}
复制代码
用法就是上面讲的这样,可以自己在组件中试一试就知道了,很简单很好用的。

如果不想自己试,可以点这个demo里面修改代码就可以了,demo中包括过滤器串联、过滤器传参。

推荐看Vue过滤器文档,你会更了解它的。

列表渲染相关
v-for循环绑定model:

input在v-for中可以像如下这么进行绑定,我敢打赌很多人不知道。

// 数据
  data() {
      return{
       obj: {
          ob: "OB",
          koro1: "Koro1"
        },
        model: {
          ob: "默认ob",
          koro1: "默认koro1"
        }
      }
  },
// html模板
<div v-for="(value,key) in obj">
   <input type="text" v-model="model[key]">
</div>
  // input就跟数据绑定在一起了,那两个默认数据也会在input中显示

复制代码
为此,我做了个demo,你可以点进去试试。

一段取值的v-for

如果我们有一段重复的html模板要渲染,又没有数据关联,我们可以:

<div v-for="n in 5">
    <span>这里会被渲染5次,渲染模板{{n}}</span>
 </div>

复制代码
v-if尽量不要与v-for在同一节点使用:

v-for 的优先级比 v-if 更高,如果它们处于同一节点的话,那么每一个循环都会运行一遍v-if。

如果你想根据循环中的每一项的数据来判断是否渲染,那么你这样做是对的:

<li v-for="todo in todos" v-if="todo.type===1">
  {{ todo }}
</li>

复制代码
如果你想要根据某些条件跳过循环,而又跟将要渲染的每一项数据没有关系的话,你可以将v-if放在v-for的父节点:

// 根据elseData是否为true 来判断是否渲染,跟每个元素没有关系
 <ul v-if="elseData">
  <li v-for="todo in todos">
    {{ todo }}
  </li>
</ul>
// 数组是否有数据 跟每个元素没有关系
<ul v-if="todos.length">
  <li v-for="todo in todos">
    {{ todo }}
  </li>
</ul>
<p v-else>No todos left!</p>

复制代码
如上,正确使用v-for与v-if优先级的关系,可以为你节省大量的性能。

深度watch与watch立即触发回调
watch很多人都在用,但是这watch中的这两个选项deep、immediate,或许不是很多人都知道,我猜。

选项:deep

在选项参数中指定 deep: true,可以监听对象中属性的变化。

选项:immediate

在选项参数中指定 immediate: true, 将立即以表达式的当前值触发回调,也就是立即触发一次。

watch: {
    obj: {
      handler(val, oldVal) {
        console.log(‘属性发生变化触发这个回调‘,val, oldVal);
      },
      deep: true // 监听这个对象中的每一个属性变化
    },
    step: { // 属性
      //watch
      handler(val, oldVal) {
        console.log("默认立即触发一次", val, oldVal);
      },
      immediate: true // 默认立即触发一次
    },
  },

复制代码
这两个选项可以同时使用,另外:是的,又有一个demo。

还有下面这一点需要注意。

这些情况下不要使用箭头函数:
不应该使用箭头函数来定义一个生命周期方法
不应该使用箭头函数来定义 method 函数
不应该使用箭头函数来定义计算属性函数
不应该对 data 属性使用箭头函数
不应该使用箭头函数来定义 watcher 函数
示例:

// 上面watch的栗子:
handler:(val, oldVal)=> { // 可以执行
 console.log("默认触发一次", val, oldVal);

},
// method:
methods: {
plus: () => { // 可以执行
// do something
}
}
// 生命周期:
created:()=>{ // 可以执行
console.log(‘lala‘,this.obj)
},
复制代码
是的,没错,这些都能执行。

but:

箭头函数绑定了父级作用域的上下文,this 将不会按照期望指向 Vue 实例。

也就是说,你不能使用this来访问你组件中的data数据以及method方法了。

this将会指向undefined。

路由懒加载写法:
// 我所采用的方法,个人感觉比较简洁一些,少了一步引入赋值。
const router = new VueRouter({
routes: [
path: ‘/app‘,
component: () => import(‘./app‘), // 引入组件
]
})
// Vue路由文档的写法:
const app = () => import(‘./app.vue‘) // 引入组件
const router = new VueRouter({
routes: [
{ path: ‘/app‘, component: app }
]
})
复制代码
文档的写法在于问题在于:如果我们的路由比较多的话,是不是要在路由上方引入赋值十几行组件?

第一种跟第二种方法相比就是把引入赋值的一步,直接写在component上面,本质上是一样的。两种方式都可以的,大家自由选择哈。

路由的项目启动页和404页面
实际上这也就是一个设置而已:

export default new Router({
  routes: [
    {
      path: ‘/‘, // 项目启动页
      redirect:‘/login‘  // 重定向到下方声明的路由
    },
    {
      path: ‘*‘, // 404 页面
      component: () => import(‘./notFind‘) // 或者使用component也可以的
    },
  ]
})

复制代码
比如你的域名为:www.baidu.com

项目启动页指的是: 当你进入www.baidu.com,会自动跳转到login登录页。

404页面指的是: 当进入一个没有 声明/没有匹配 的路由页面时就会跳转到404页面。

比如进入www.baidu.com/testRouter,就会自动跳转到notFind页面。

当你没有声明一个404页面,进入www.baidu.com/testRouter,显示的页面是一片空白。

Vue调试神器:vue-devtools
每次调试的时候,写一堆console是否很烦?想要更快知道组件/Vuex内数据的变化?

那么这款尤大开发的调试神器:vue-devtools,你真的要了解一下了。

这波稳赚不赔,真的能提高开发效率。

安装方法:

搜索vue-devtools即可安装。
安装之后:

在chrome开发者工具中会看一个vue的一栏,如下对我们网页应用内数据变化,组件层级等信息能够有更准确快速的了解。

前几个月也写过一篇类似的:
Vue 实践过程中的几个问题

结语
本文的内容很多都在Vue文档里面有过说明,推荐大家可以多看看Vue文档,不止看教程篇,还有文档的Api什么的,也都可以看。然后其实还有两三点想写的,因为预计篇幅都会比较长一点,所以准备留到以后的文章里面吧~

文章如有不正确的地方欢迎各位路过的大佬鞭策!希望大家看完可以有所收获,喜欢的话,赶紧点波订阅关注/喜欢。

看完的朋友可以点个喜欢/关注,您的支持是对我最大的鼓励。
前端进阶积累、公众号、GitHub、wx:OBkoro1、邮箱:[email protected]

以上2018.6.3

参考资料:
Vue文档

Vue Api文档

原文地址:https://blog.51cto.com/14516164/2438249

时间: 2024-10-08 10:48:58

你或许不知道Vue的这些小技巧的相关文章

好程序员分享Vue的一些小技巧

好程序员分享Vue的一些小技巧,前言:用Vue开发一个网页并不难,但是也经常会遇到一些问题,其实大部分的问题都在文档中有所提及,再不然我们通过谷歌也能成功搜索到问题的答案,为了帮助小伙伴们提前踩坑,在遇到问题的时候,心里大概有个谱知道该如何去解决问题.这篇文章是将自己知道的一些小技巧分享给大家,希望看完本文可以有所收获. 文章内容总结: 组件style的scoped Vue 数组/对象更新 视图不更新 vue filters 过滤器的使用 列表渲染相关 深度watch与watch立即触发回调 这

Vue 使用中的小技巧

在vue的使用过程中会遇到各种场景,当普通使用时觉得没什么,但是或许优化一下可以更高效更优美的进行开发.下面有一些我在日常开发的时候用到的小技巧,在下将不定期更新~ 1.多图表resize事件去中心化 1.1 一般情况 有时候我们会遇到这样的场景,一个组件中有几个图表,在浏览器resize的时候我们希望图表也进行resize,因此我们会在父容器组件中写: mounted() { setTimeout(() => window.onresize = () => { this.$refs.char

给大家分享12个或许能在实际工作中帮助你解决一些问题的JavaScript的小技巧

使用!!操作符转换布尔值 有时候我们需要对一个变量查检其是否存在或者检查值是否有一个有效值,如果存在就返回true值.为了做这样的验证,我们可以使用!!操作符来实现是非常的方便与简单.对于变量可以使用!!variable做检测,只要变量的值为:0.null." ".undefined或者NaN都将返回的是false,反之返回的是true.比如下面的示例: 01 function Account(cash) { 02 this.cash = cash; 03 this.hasMoney

教你一个vue小技巧,一般人我不说的

本文由云+社区发表 1. 需求 最近的项目中,需要实现在vue框架中动态渲染带提示框的单选/多选文本框,具体的效果如下图所示,在输入框聚焦时,前端组件通过接收的kv参数渲染出选项,用户点击选项,可以将选择的选项的key拼装到输入框中,同时允许用户自由输入. 由于项目中使用的element-ui,首选考虑使用组件的input和select组件,然而实际使用中发现框架提供的组件不能很好满足此需求.例如,使用带输入建议的input组件,能够实现提示框和单选,但并不能方便地实现多选(重复选择会覆盖输入框

vue使用小技巧

1.多图表resize事件去中心化 1.1 一般情况 有时候我们会遇到这样的场景,一个组件中有几个图表,在浏览器resize的时候我们希望图表也进行resize,因此我们会在父容器组件中写: mounted() { setTimeout(() => window.onresize = () => { this.$refs.chart1.chartWrapperDom.resize() this.$refs.chart2.chartWrapperDom.resize() // ... }, 20

我不知道你知不知道我知道的伪元素小技巧

伪元素 伪元素能做什么?我们要他有何用?它能为我们解决什么问题?和其他的方法相比她有什么有点?我们为什么要使用它? 伪元素和伪类一样,添加到选择器,但是不是描述状态,他允许我们为元素某些部分设置样式:利用伪元素,我们可以简化页面的html标签,同时用起来也很方便,善于使用伪元素可以让你的页面更加地简洁优雅.之所以叫伪元素,是因为他修饰不在文档树中的部分:不是真实存在的: 伪元素实用小技巧 1.清除浮动 何谓清除浮动-?一个父元素的所有子元素如果都是浮动的,那么这个父元素是没有高度的;父元素并没有

代码手写UI,xib和StoryBoard间的博弈,以及Interface Builder的一些小技巧

代码手写UI,xib和StoryBoard间的博弈,以及Interface Builder的一些小技巧 最近接触了几个刚入门的iOS学习者,他们之中存在一个普遍和困惑和疑问,就是应该如何制作UI界面.iOS应用是非常重视用户体验的,可以说绝大多数的应用成功与否与交互设计以及UI是否漂亮易用有着非常大的关系.而随着iOS开发发展至今,可以说在UI制作上大家逐渐分化为了三种主要流派:使用代码手写UI及布局:使用单个xib文件组织viewController或者view:使用StoryBoard来通过

mysql写Shell小技巧

今天终于在表哥的帮助下解决了文件导入/出这个问题了.(很菜逼的一个问题),然后将最近看到的文章都自己测试了下,顺便奉上记录.1.Mysql数据库支持union的时候写文件小技巧: 采用常规的union写入,可以看到前面的字段占位数肯定也会被写入,替换成null也是一样的结果,这个对于写shell没啥大碍,但是如果用来写bat,mof,vbs等文件就会出问题了,那么怎么去掉这个只写入我们需要的内容呢?采用hex编码就好了. 将我们要写入的内容使用hex编码在分段写在每个字段位上,这样就可以只写入我

VS经常使用的一些小技巧

相信做开发的没有不重视效率的.开发C#,VB的都知道,我们很依赖VS,或者说,我们很感谢VS.能够对一个IDE产生依赖,说明这个IDE确实 有它的独特之处.无容置疑,VS是一个非常强大的IDE,它支持多语言编辑.支持C#,VB,C/C++,HTML......它拥有强大的调试编译功 能.它让我们不用去记住那些安装,环境变量设置,服务器设置,编译的繁琐过程.高度集成化.凡事有利有弊,在敏捷开发盛行的时代,VS是否值得我们使用是 无容置疑的.但是强大的VS也拥有众多的设置,众多的技巧.记住某些小技巧