文章82
标签28
分类8

Vue组件使用过程中的小坑

模板组件渲染出错

在使用组件的过程中,会碰到耦合性特别强的标签,比如 ul,liol,liselect,optiontable tr, td 标签等。

如果我们直接用里面的子标签做为组件使用,就可能会出现问题。

例如下面这个表格

<!--html-->
<table>
    <tr><td>123</td></tr>
    <tr><td>123</td></tr>
    <tr><td>123</td></tr>
</table>

在网页上展示的 DOM 结构为如下图所示,这样是没有问题的。

vue组件小坑-01

当我们把 td 当做一个子组件去使用时,就可能会出现下面这种情况。

<!--html-->
<table>
  <tr><my-td></my-td></tr>
  <tr><my-td></my-td></tr>
  <tr><my-td></my-td></tr>
</table>
//注册全局组件
Vue.component("my-td",{
    "template": "<td>123</td>"
});

//创建 Vue 实例
var vm = new Vue({
    el: "#app",
    data: {}
});

我们注册了一个全局组件,组件内容就是 td 标签,然后放入到页面中去使用它,然后我们到页面上查看 DOM 结构,发现有问题。
vue组件小坑-02

在 H5的规范里面,我们需要遵循标签的嵌套,table > tr >tr 。但是现在table tr 并没有包裹住 td 标签。

那么如果解决这种情况呢?

Vue 给我们提供了解决方法,既然对于某些标签有严格的嵌套标准,那么我们便去遵守它,还是和原来的代码一样。只不过 DOM 结构有些不同。

<table>
  <tr><td is="my-td"></td></tr>
  <tr><td is="my-td"></td></tr>
  <tr><td is="my-td"></td></tr>
</table>

is 表示指向这个组件,这样符合H5的代码标准,又能保证我们能正常使用组件。

同理,对于其他耦合性较强的标签,都可以使用 is 属性进行模板组件的使用。

子组件数据渲染出错

在子组件中定义 data 时,data 必须是个函数。

还是刚刚那个例子,这时我们在 data 中定义一个content 参数,然后在模板中调用它。

//注册全局组件
Vue.component("my-td",{
    data: {
      content: '123'
    },
    "template": "<td>{{ content }}</td>"
});

运行到浏览器中,我们会发现控制台报错了。

vue:6 ReferenceError: content is not defined

提示我们 content 没有定义,这是因为在子组件中定义 data 时,data 必须是个函数。

所以,我们应该这样把 data 改为一个函数,这样就能正常渲染出数据了。

//注册全局组件
Vue.component("my-td",{
    data(){
      return {
        content: '123'
      }
    },
    "template": "<td>{{ content }}</td>"
});

操作 DOM

vue 官方不推荐我们去操作 DOM,取而代之的是数据绑定,但是在处理某些极为复杂的情况时,又必须得去操作 DOM ,所以 vue 给我们提供了 ref 属性。

<!--html-->
<div @click="handleClickMe" ref="hello">Click Me</div>
//JS
methods:{
  handleClickMe() {
    console.log(this.$refs.hello);
  }
}

打印结果如下,它会把这个 DOM 节点都打印输出。

<div>Click Me</div>