• 8Vue组件使用细节


    1.table中使用组件

    我们写一个表格table代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <script src="./vue.js"></script>
      <title>Document</title>
    </head>
    <body>
      <div id="app">
        <table>
          <tbody>
            <row></row>
            <row></row>
            <row></row>
          </tbody>
        </table>
      </div>
    </body>
    <script>
      Vue.component('row',{
        template:"<tr><td>this is a row</td></tr>"
      })
      var vm=new Vue({
        el:"#app",
       
      })
    </script>
    </html>

    渲染效果如下:

     看似没有问题,但是当我们将控制台打开,就能发现有不对的地方了

     tr和table居然在同级,这违反了HTML5的规范。要解决这个问题,我们可以使用“is”,来指定组件。

    如下修改:

    <table>
          <tbody>
            <tr is="row"></tr>
            <tr is="row"></tr>
            <tr is="row"></tr>
          </tbody>
        </table>

    意思是tobody中的tr是row组件,这样既可以使用我们的组件,又可以符合HTML5的规范。控制台中的结构也是正确的。

     同理,ul、ol、select这些元素在直接嵌入组件也可能会出现上面的Bug。

    2.组子件中的data

    在前面代码的基础上,我们将row组件内容修改一下,如下:

    Vue.component('row',{
        data:{
          content:"this is row"
        },
        template:"<tr><td>{{content}}</td></tr>"
      })
      var vm=new Vue({
        el:"#app",
       
      })

    主要就是将文本内容抽出来做数据。

    然后发现这种做法会报错,内容如下图:

     这是因为,在非根组件的组件中使用data,需要用一个函数来返回data的内容,内容是一个对象,修改如下:

    Vue.component('row',{
        data:function(){//一个函数
          return {
            content:'this is content'
          }
        },
        template:"<tr><td>{{content}}</td></tr>"
      })

    这样设计的目的就是为了子组件在复用的时候,data内的数据不会相互影响,所以通过函数返回的方式,保证每一个子组件有独立的数据存储。

    完整代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <script src="./vue.js"></script>
      <title>Document</title>
    </head>
    <body>
      <div id="app">
        <table>
          <tbody>
            <tr is="row"></tr>
            <tr is="row"></tr>
            <tr is="row"></tr>
          </tbody>
        </table>
      </div>
    </body>
    <script>
      Vue.component('row',{
        data:function(){
          return {
            content:'this is content'
          }
        },
        template:"<tr><td>{{content}}</td></tr>"
      })
      var vm=new Vue({
        el:"#app",
       
      })
    </script>
    </html>

    3.组件使用ref

    有些时候我们会写比较复杂的动画,操作DOM的行为就可能无法避免了,我们可以使用ref来获取dom,如下:

    <div id="app">
        <div
          ref='hello'
          @click="handleClick"
        >
          hello!
        </div>
    var vm=new Vue({
        el:"#app",
        methods:{
          handleClick:function(){
            //this.$ref是所有ref的集合
            console.log(this.$refs.hello)
            alert('hello')
          }
        }
      })

    我们通过给div标签设置ref,并取名为hello,然后通过this.$refs.hello就可以获取到这个div的dom

     但是如果ref设置在一个组件上呢?

    比如我们现在需要做两个计数器,点击一下就会加1,然后还有一个求和,如下:

    <body>
      <div id="app">
        <counter></counter>
        <counter></counter>
        <div>{{total}}</div>
      </div>
    </body>
      Vue.component('counter',{
        template:'<div @click="handleClick">{{number}}</div>',
        data:function(){
          return {
            number:0
          }
        },
        methods:{
          handleClick:function(){
            this.number++;
          }
        }
      })
      var vm=new Vue({
        el:"#app",
        data:{
          total:0
        }
      })

     现在实现的功能还只能计数,不能求和。我们也可以使用ref来获取组件中的值

     <div id="app">
        <!-- 子组件触发change,父组件监听,触发handleChange方法 -->
        <counter ref="one" @change="handleChange"></counter>
        <counter ref="two" @change="handleChange"></counter>
        <div>{{total}}</div>
      </div>
      Vue.component('counter',{
        template:'<div @click="handleClick">{{number}}</div>',
        data:function(){
          return {
            number:0
          }
        },
        methods:{
          handleClick:function(){
            this.number++;
            //触发change方法
            this.$emit('change')
          }
        }
      })
      var vm=new Vue({
        el:"#app",
        data:{
          total:0
        },
        methods:{
          handleChange:function(){
            //this.$refs.one、this.$refs.two获取到的是组件的引用
            console.log(this.$refs.one);
            console.log(this.$refs.two);
            this.total=this.$refs.one.number+this.$refs.two.number;
          }
        }
      })

    打印结果如下

    this.$refs.one、this.$refs.two获取到的是组件的引用,而不是dom

    渲染出来的结果:

     完整代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <script src="./vue.js"></script>
      <title>Document</title>
    </head>
    <body>
      <div id="app">
        <!-- 子组件触发change,父组件监听,触发handleChange方法 -->
        <counter ref="one" @change="handleChange"></counter>
        <counter ref="two" @change="handleChange"></counter>
        <div>{{total}}</div>
      </div>
    </body>
    <script>
      Vue.component('counter',{
        template:'<div @click="handleClick">{{number}}</div>',
        data:function(){
          return {
            number:0
          }
        },
        methods:{
          handleClick:function(){
            this.number++;
            //触发change方法
            this.$emit('change')
          }
        }
      })
      var vm=new Vue({
        el:"#app",
        data:{
          total:0
        },
        methods:{
          handleChange:function(){
            //this.$refs.one、this.$refs.two获取到的是组件的引用
            console.log(this.$refs.one);
            console.log(this.$refs.two);
            this.total=this.$refs.one.number+this.$refs.two.number;
          }
        }
      })
    </script>
    </html>
  • 相关阅读:
    使用 CSS 强制内容不换行
    奇怪的 Object reference not set to an instance of an object
    (String) 和 String.valueOf() 两种字符串转换的区别
    SQL 里面的 UNION 说明
    Flex/AIR 中 Embed 标签的使用
    把 doc、xls、pdf 转换为 swf 的相关工具
    把指定的站点加到 IE 可信站点中
    在 VS 中快速打开文件或类型
    linux配置网卡
    linux配置本地源
  • 原文地址:https://www.cnblogs.com/ellen-mylife/p/14103477.html
Copyright © 2020-2023  润新知