Vue是目前最流行的MVVM框架,在Vue的使用中多多少少会遇到一些坑,这里将讲述一些常见的问题及解决方案来帮助Vue初学者避免踩坑。

问题1:在组件中JS动态创建的DOM,添加样式不生效

场景

<template>
	<div class="test"></div>
</template>

<script>
	let testDom = document.querySelector(".test");
	let newDom = document.createElement("div");
	newDom.setAttribute("class", "testCreate");
	testDom.appendChild(newDom);
</script>

<style scoped>
.test {
	width:20px;
	height:20px;
	background-color: red;
}
.testCreate {
	width:10px;
	height:10px;
	background-color: blue;
}
</style>

结果

<div data-v-2c69b3db class="test"><div class="testAdd"></div>

<style>
.test[data-v-2c69b3db]{
	width: 20px;
	height: 20px;
	background-color: red;
}
</style>

.testAdd的样式没有生效

原因

解决

1、style标签中去掉scoped。

2、给动态创建的DOM,动态的添加样式。例如:newDom.style.width=’10px’;

问题2:Vue数组/对象更新,但视图不更新

场景

new Vue({
  data() {
    return {
      arr: [1,2,3],
      obj: {
        a:1,
        b:2
      }
    }
  },
  mounted() {
    // 数据更新 数组视图不更新
    this.arr[0] = '0';
    this.arr.length = 1;
    console.log(arr); // ['0']
    
    // 数据更新 对象视图不更新
    this.obj.c = '3';
    delete this.obj.a;
    console.log(obj); // {b:2, c:'3'}
  }
})

原因

由于JavaScript的限制,Vue不能检测以上数组的变动,以及对象的添加/删除,导致出现操作后视图未更新的问题。

解决

使用this.$set()来更新数组/对象。语法:

this.$set(originArr, index, value);

this.$set(originObj, key, value);

问题3:如何使用watch监听对象的属性变化

场景

我们经常会使用watch来监听数据的变化,然后进行相应的处理。那如果我们需要监听的是一个对象的某个属性的变化呢?我们可以使用watch中的deep选项。

deep选项

可以使用watch中的deep选项,对一个对象的属性进行监听

new Vue({
  watch: {
    obj: {
      handler(val, oldVal){
        console.log(`原数据${oldVal}已更新为${val}`)
      },
      deep: true
    }
  }
})

问题4:如何对404的文件展示特定的页面样式

场景

当我们在访问一个文章类的网站下,一个不存在的文章时,如何能够友好的提示一个404的页面?方法有两种:服务端进行判断然后重定向到一个特定的网址,前端路由做兜底展示特定的组件。

Vue-router解决方案

可以在路由设置中,写一个path:*来对所有没匹配到规则的请求加载一个特定的组件。

const router = new VueRouter({
  routes: [
    {
      path:'/',
      component: index,
    },
    {
      path:'/search',
      component: search
    },
    {
      path:'*', // 上面的router均未匹配的情况下进入
      component: index // 默认展示index的组件视图
    }
  ]
})