8Vue组件使用细节

Posted ellen-mylife

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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>

 


以上是关于8Vue组件使用细节的主要内容,如果未能解决你的问题,请参考以下文章

8vue中得监听属性:watch--- /////watchcomputedmethods得区别

Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段

单个活动:带有 AppBarLayout 的片段

很多导航组件都可以吗?

Android TV - 在细节片段中失去焦点

VsCode 代码片段-提升研发效率