zoukankan      html  css  js  c++  java
  • 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>
  • 相关阅读:
    【Swing】简单的计算器
    【SQL】嵌套查询与子查询
    【网络协议抓包分析】TCP传输控制协议(连接建立、释放)
    【网络协议抓包分析】IP互联网协议
    ******常见数据库笔试题*****
    OSI参考模型 VS TCP/IP参考模
    TCP/IP四层模型
    数组实现栈的功能
    子网掩码怎么计算
    C# 启动和结束一个线程
  • 原文地址:https://www.cnblogs.com/ellen-mylife/p/14103477.html
Copyright © 2011-2022 走看看