vue组件中使用的一些细节点

1. 在table/ul/ol/select中显示子组件

  • bug
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件使用中的细节点1</title>
  <script src="../node_modules/vue/dist/vue.js"></script>
</head>
<body>
  <div id="root">
    <table>
      <tbody>
        <row></row>
        <row></row>
        <row></row>
      </tbody>
    </table>
  </div>
  <script>
    /*希望每一行的数据都是一个子组件的时候*/
    Vue.component('row', {
      template:'<tr><td>this is a row</td></tr>'
    })

    var vm=new Vue({
      el:"#root",
      data:{

      }
    })
  </script>
</body>
</html>

效果如下,我们会发现出现了…跑到tbody外面和table同级的情况,违反了H5的要求,即tr必须在tbody中,tbody必须在table中。:
在这里插入图片描述

  • 解决
<div id="root">
    <table>
      <tbody>
        <tr is="row"></tr>
        <tr is="row"></tr>
        <tr is="row"></tr>
      </tbody>
    </table>
  </div>

在这里插入图片描述

2. 子组件中的data函数

在子组件中data应该是一个函数,而不是一个对象;在根组件里data定义为一个对象;

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>组件使用中的细节点2</title>
  <script src="../node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
  <table>
    <tbody>
    <tr is="row"></tr>
    </tbody>
  </table>
</div>
<script>
  Vue.component('row',{
    /*data:{
      content:'this is a row'
    },这样会出现问题,data必须是一个函数*/
    data:function() {
      return {
        content:'this is a row'
      }
    },
    template:'<tr><td>{{content}}</td></tr>'
  })

  var vm=new Vue({
    el:"#root",
    data:{

    }
  })
</script>
</body>
</html>

是因为子组件也许会被调用多次,这样定义使每一个子组件都拥有一个独立的数据存储,互相之间不会影响。

3. ref引用

Vue虽然不建议我们操作 dom ,但是在一些情况下必须要操作dom,这时通过我们要通过 ref引用 来获取dom。通过下面的这个例子来打印div中的内容:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>组件使用中的细节点3-ref</title>
  <script src=".././node_modules/vue/dist/vue.js"></script>
</head>
<body>
<!--在vue中操作dom通过ref引用的方式-->
<div id="root">
  <div
    ref="hello"
    @click="handleClick"
  >
    hello world
  </div>
</div>
<script>
  var vm=new Vue({
    el:"#root",
    data:{
    },
    methods:{
      handleClick:function () {
        /*this.refs.ref指的是vue实例中的所有引用refs,其中一个引用叫ref*/
        /*console.log(this.$refs.hello)打印出来的是div这个dom节点*/
        alert(this.$refs.hello.innerHTML)
      }
    }
  })
</script>
</body>
</html>

4. 单向数据流

首先来看一个例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>父子组件传值2</title>
  <script src="../node_modules/vue/dist/vue.js"></script>
</head>
<body>
  <div id="root">
    <counter :count="1" @inc="handleChange"></counter>
    <counter :count="2" @inc="handleChange"></counter>
    <div>{{total}}</div>
  </div>
  <script>
    var counter={
      props:['count'],
      data:function() {
        return{
          step:2
        }
      },
      template:'<div @click="handleClick">{{count}}</div>',
      methods:{
        handleClick:function () {
          this.count++;   //会发出警告,子组件不能改变从父组件传递过来的数据
          this.$emit('inc',2)  /*触发这个事件,每次新增2*/
        }
      }
    }

    var vm=new Vue({
      el:"#root",
      data:{
        total:3
      },
      components:{
        counter:counter
      },
      methods:{
        handleChange:function (step) {
          this.total+=step
        }
      }
    })
  </script>
</body>
</html>

在这段代码中,我们实现了子组件向父组件传值:

this.$emit('inc',2)

父组件通过属性向子组件传值:

<counter :count="1" @inc="handleChange"></counter>
    <counter :count="2" @inc="handleChange"></counter>

理想的情况是点击子组件渲染的元素,实现数字加一;点击父组件渲染的元素,实现数字加二,但是点击子组件渲染出的元素时发现并不能实现加一的效果,打开控制台,报错信息:
在这里插入图片描述
告诉我们说要避免直接修改从父组件接收的参数count,所以可以定义count的副本number:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>父子组件传值2</title>
  <script src="../node_modules/vue/dist/vue.js"></script>
</head>
<body>
  <div id="root">
    <counter :count="1" @inc="handleChange"></counter>
    <counter :count="2" @inc="handleChange"></counter>
    <div>{{total}}</div>
  </div>
  <script>
    var counter={
      props:['count'],
      data:function() {
        return{
          number:this.count,
          step:2
        }
      },
      template:'<div @click="handleClick">{{number}}</div>',
      methods:{
        handleClick:function () {
          /*this.count++会发出警告,子组件不能改变从父组件传递过来的数据*/
          this.number=this.number+2
          this.$emit('inc',2)  /*触发这个事件,每次新增2*/
        }
      }
    }

    var vm=new Vue({
      el:"#root",
      data:{
        total:3
      },
      components:{
        counter:counter
      },
      methods:{
        handleChange:function (step) {
          this.total+=step
        }
      }
    })
  </script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/zl13015214442/article/details/87875461
今日推荐