天天看点

Vue - attribute is & ref

推荐:​​Vue汇总​​

Vue - attribute is & ref

attribute is

用于动态组件且基于 DOM 内模板的限制来工作。

动态组件

有的时候,在不同组件之间进行动态切换是非常有用的。

可以通过 Vue的 ​

​<component>​

​​ 元素加一个特殊的 ​

​is attribute​

​ 来实现:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>count</title>
  <script src="./js/vue.js"></script>
</head>
<body>
<div id="div">
  <component v-bind:is="currentComponent">kaven</component>
  <button @click="click">切换</button>
</div>
</body>
</html>
<script>

  Vue.component("slot-welcome" , {
    template: `
           <div>
              <p>welcome </p>
              <slot></slot>
           </div>
        `
  });

  Vue.component("slot-hello" , {
    template: `
           <div>
              <p>hello </p>
              <slot></slot>
           </div>
        `
  });

  var vue = new Vue({
    el: '#div',
    data: {
      currentComponent: 'slot-hello'
    },
    methods: {
      click(){
        if(this.currentComponent === 'slot-hello'){
          this.currentComponent = 'slot-welcome'
        }
        else{
          this.currentComponent = 'slot-hello'
        }
      }
    }
  })
</script>      

效果:

Vue - attribute is &amp; ref

点击按钮。

Vue - attribute is &amp; ref

解析 DOM 模板时的注意事项

有些 HTML 元素,诸如 ​

​<ul>​

​​、​

​<ol>​

​​、​

​<table>​

​​ 和 ​

​<select>​

​​,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 ​

​<li>​

​​、​

​<tr>​

​​ 和 ​

​<option>​

​,只能出现在其它某些特定的元素内部。

这会导致我们使用这些有约束条件的元素时遇到一些问题。例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>if & ref</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="div">
        <table>
            <row></row>
            <row></row>
            <row></row>
        </table>
    </div>
</body>
</html>
<script>
    Vue.component('row' , {
        template: '<tr>Hello Kaven</tr>'
    })
    var vue = new Vue({
        el: '#div'
    })
</script>      

效果:

Vue - attribute is &amp; ref

​<tr>​

​​出现在​

​<table>​

​的外面,很显然有问题。

这个自定义组件 ​

​<row>​

​​ 会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的 ​

​is attribute​

​ 给了我们一个变通的办法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>if & ref</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="div">
        <table>
            <tr is="row"></tr>
            <tr is="row"></tr>
            <tr is="row"></tr>
        </table>
    </div>
</body>
</html>
<script>
    Vue.component('row' , {
        template: '<tr>Hello Kaven</tr>'
    })
    var vue = new Vue({
        el: '#div'
    })
</script>      

效果:

Vue - attribute is &amp; ref

还自动创建了​

​<tbody>​

​,这样就没问题了。

attribute ref

​ref​

​​ 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 ​

​$refs​

​ 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例。

DOM 元素:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>if & ref</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="div" ref="div" @click="click">
        <p>Hello Kaven</p>
    </div>
</body>
</html>
<script>
    var vue = new Vue({
        el: '#div',
        methods: {
            click(){
                console.log(this.$refs.div.innerHTML);
            }
        }
    })
</script>      

效果:

Vue - attribute is &amp; ref

对​

​this.$refs.div​

​的操作,其实就是对DOM的操作。

子组件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>if & ref</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="div" @click="click">
        <child ref="child"></child>
    </div>
</body>
</html>
<script>
    Vue.component('child' , {
        data: function(){
            return {
                message: 'Hello Kaven'
            }
        },
        template: '<p>{{message}}</p>'
    });
    var vue = new Vue({
        el: '#div',
        methods: {
            click(){
                console.log(this.$refs.child.message);
            }
        }
    })
</script>      

效果:

Vue - attribute is &amp; ref

对​

​this.$refs.child​

​的操作,其实就是对子组件的操作。

当 ​

​v-for​

​ 用于元素或组件的时候,引用信息将是包含 DOM 节点或组件实例的数组。

关于 ​

​ref​

​​ 注册时间的重要说明:因为 ​

​ref​

​​ 本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们 - 它们还不存在!​

​$refs​

​ 也不是响应式的,因此你不应该试图用它在模板中做数据绑定。

​$refs​

​​ 只会在组件渲染完成之后生效,并且它们不是响应式的。这仅作为一个用于直接操作子组件的“逃生舱”——你应该避免在模板或计算属性中访问 ​

​$refs​

​。

  • ​​ref​​
  • ​​is​​

继续阅读