什么是组件

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title></title>
  5. <meta charset="utf-8"/>
  6. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  7. </head>
  8. <body>
  9. <div id="components-demo">
  10. <button-counter></button-counter>
  11. <button-counter></button-counter>
  12. </div>
  13. <script>
  14. // 定义一个名为 button-counter 的新组件
  15. Vue.component('button-counter', {
  16. data: function () {
  17. return {
  18. count: 0
  19. }
  20. },
  21. template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
  22. })
  23. new Vue({ el: '#components-demo' })
  24. </script>
  25. </body>
  26. </html>

这些类似于没见过的标签就是组件,每个标签代表一个组件,这样我们 就可以将组件进行任意次数的复用。
使用组件的好处:
提高开发效率
方便重复使用
简化调试步骤
提升整个项目的课维护性
便于协同开发

组件系统让我们可以用独立可复用的小组件来构建大型应用,
几乎任意类型的应用的界面都可以抽象为一个组件树,如图5-1所示

全局注册

全局注册有三种方式。
要注册一个全局组件,我们可以使用 Vue.component(tagName,options),代码如下:

  1. Vue.component('my-component', {
  2. // 选项
  3. })
  1. <div id="app">
  2. <my-component></my-component>
  3. </div>
  4. <script>
  5. Vue.component('my-component', {
  6. template: '<h1>注册</h1>'
  7. });
  8. var vm=new Vue({
  9. el:'#app'
  10. })
  11. </script>

使用 Vue.extend 配合 Vue.component 方法

  1. <div id="app">
  2. <my-list></my-list>
  3. </div>
  4. <script>
  5. var list=Vue.extend({
  6. template:'<h1>this is a list</h1>',
  7. });
  8. Vue.component("my-list",list);
  9. //根实例
  10. new Vue({
  11. el:"#app",
  12. })
  13. </script>

将模板字符串,定义到 script 标签中

  1. <div id="app">
  2. <account></account>
  3. </div>
  4. <template id="tmpl">
  5. <div><a href="#">登录</a> | <a href="#">注册</a></div>
  6. </template>
  7. <script>
  8. Vue.component('account', {
  9. template: '#tmpl'
  10. });
  11. new Vue({
  12. el:"#app",
  13. })
  14. </script>

局部注册

如果不需要全局注册,或者是让组件使用在其它组件内,可以用选项对象的 components 属性实现局部注册

  1. <div id="app">
  2. <account></account>
  3. </div>
  4. <script>
  5. // 创建 Vue 实例,得到 ViewModel
  6. var vm = new Vue({
  7. el: '#app',
  8. data: {},
  9. methods: {},
  10. components: { // 定义子组件
  11. account: { // account 组件
  12. template: '<div><h1>这是Account组</h1><login></login></div>', // 在这里使用定义的子组件
  13. components: { // 定义子组件的子组件
  14. login: { // login 组件
  15. template: "<h3>这是登录组件</h3>"
  16. }
  17. }
  18. }
  19. }
  20. });
  21. </script>

组件的基本使用

可以使用“flag”标识符结合“v-if”和“v-else”切换组件

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title></title>
  5. <meta charset="utf-8"/>
  6. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  7. </head>
  8. <body>
  9. <div id="app">
  10. <input type="button" value="toggle" @click="flag=!flag">
  11. <account v-if="flag"></account>
  12. <login v-else="flag"></login>
  13. </div>
  14. <script>
  15. // 创建 Vue 实例,得到 ViewModel
  16. var vm = new Vue({
  17. el: '#app',
  18. data: {
  19. flag: true
  20. },
  21. methods: {},
  22. components: { // 定义子组件
  23. account: { // account 组件
  24. template: '<div><h1>这是Account组件</h1></div>', // 在这里使用定义的子组件
  25. },
  26. login: { // login 组件
  27. template: "<h3>这是登录组件</h3>"
  28. }
  29. }
  30. });
  31. </script>
  32. </body>
  33. </html>

DOM模板解析说明

在自定义组件中使用这些受限制的元素时会导致一些问题

  1. <table>
  2. <my-row>...</my-row>
  3. </table>

自定义组件被认为是无效的内容,因此在渲染的时候会导致错误。这时要使用特殊的 is 属性来挂载组件

  1. <table>
  2. <tr is="my-row"></tr>
  3. </table>
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title></title>
  5. <meta charset="utf-8"/>
  6. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  7. </head>
  8. <body>
  9. <div id="app">
  10. <table border="1" cellpadding="5" cellspacing="0">
  11. <my-row></my-row>
  12. <tr is="my-row"></tr>
  13. </table>
  14. </div>
  15. <script type="text/javascript">
  16. new Vue({
  17. el:'#app',
  18. components:{
  19. myRow:{
  20. template:'<tr><td>123456</td></tr>'
  21. }
  22. }
  23. });
  24. </script>
  25. </body>
  26. </html>

组件选项

Vue 的组件最核心的选项有以下几个:
模板(template)
初始数据(data)
接受的外部参数(props)
方法(methods)
生命周期钩子函数(lifecycle hooks)

组件接受的选项大部分与 Vue 实例一样,相同的部分就不再赘述了。我们重点说一下 二者不同的选项 data 和 props,data 在 5.2.1 中已经讲解过了,所以本小节主要讲解 props, 它用于接收父组件传递的参数。

组件 props

组件中更重要的是组件间进行通信,选项props是组件中非常重要的一个选项,起到父子组件间桥梁的作用。

静态props

子组件使用父组件的数据

  1. <div id="app">
  2. <my-componet message="来至父组件的数据!!"></my-componet>
  3. </div>
  4. <script type="text/javascript">
  5. Vue.component('my-componet', {
  6. // 声明 props
  7. props: ['message'],
  8. // 就像 data 一样,prop 可以用在模板内
  9. // 同样也可以在 vm 实例中像 “this.message” 这样使用
  10. template: '<span>{{ message }}</span>'
  11. })
  12. new Vue({
  13. el:'#app'
  14. });
  15. </script>

动态 props

动态接收父组件数据到子组件

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title></title>
  5. <meta charset="utf-8"/>
  6. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  7. </head>
  8. <body>
  9. <div id="app">
  10. <input type="text" v-model="parentMessage">
  11. <my-componet :message="parentMessage"></my-componet>
  12. </div>
  13. <script type="text/javascript">
  14. Vue.component('my-componet', {
  15. props: ['message'],
  16. template: '<span>{{ message }}</span>'
  17. })
  18. new Vue({
  19. el:'#app',
  20. data:{
  21. parentMessage:''
  22. }
  23. });
  24. </script>
  25. </body>
  26. </html>

这里使用 v-model 绑定了父组件数据 parentMessage,当在输入框中输入数据时,子组件接收到的 props“’message’”也会实时响应,并更新组件模板。
对于初学者常犯的一个错误,如果你在父组件中直接传递数字、布尔值、数组、对象时, 它所传递默认值字符串。如果想传递一个实际的数值,需要使用 v-bind ,从而让它的值被当作 JavaScript 表达式计算

  1. <div id="app">
  2. <my-componet message="1+1"></my-componet><br>
  3. <my-componet :message="1+1"></my-componet>
  4. </div>
  5. <script type="text/javascript">
  6. Vue.component('my-componet', {
  7. props: ['message'],
  8. template: '<span>{{ message }}</span>'
  9. })
  10. new Vue({
  11. el:'#app'
  12. });
  13. </script>

props 验证

当组件给其他人使用时,推荐进行数据验证。
验证的type类型可以是:String、Number、Boolean、Function、Object、Array等

如果传入子组件的 message 不是数字,则抛出警告

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title></title>
  5. <meta charset="utf-8"/>
  6. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  7. </head>
  8. <body>
  9. <div id="example">
  10. <parent></parent>
  11. </div>
  12. <script>
  13. var childNode = {
  14. template: '<div>{{message}}</div>',
  15. props:{
  16. 'message':Number
  17. }
  18. }
  19. var parentNode = {
  20. template:'<div class="parent"><child :message="msg"></child></div>',
  21. components: {
  22. 'child': childNode
  23. },
  24. data(){
  25. return{
  26. msg: '123'
  27. }
  28. }
  29. };
  30. new Vue({ // 创建根实例
  31. el: '#example',
  32. components: {
  33. 'parent': parentNode
  34. }
  35. })
  36. </script></body></html>

单项数据流

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。之所以这样设计,是尽可能将父子组件解耦,避免子组件无意中修改了父组件的状态

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title></title>
  5. <meta charset="utf-8"/>
  6. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  7. </head>
  8. <body>
  9. <div id="example">
  10. <parent></parent>
  11. </div>
  12. <script>
  13. var childNode = {
  14. template:
  15. '<div class="child"><div><span>子组件数据</span>' +
  16. '<input v-model="childMsg"> </div> <p>{{childMsg}}</p></div>' ,
  17. props:['childMsg']
  18. }
  19. var parentNode = {
  20. template:
  21. '<div class="parent"><div><span>父组件数据</span>' +
  22. '<input v-model="msg"></div><p>{{msg}}</p> <child :child-msg="msg"></child></div>',
  23. components: {
  24. 'child': childNode
  25. },
  26. data(){
  27. return {
  28. 'msg':'match'
  29. }
  30. }
  31. };
  32. new Vue({// 创建根实例
  33. el: '#example',
  34. components: {
  35. 'parent': parentNode
  36. }
  37. })
  38. </script>
  39. </body>
  40. </html>

运行结果:父组件数据变化时,子组件数据会相应变化;而子组件数据变化时,父组件数据不变,并在控制台显示警告

组件通信

003组件 - 图2

组件关系有下面三种:父—>子、子—>父、非父子。

自定义事件
当子组件需要向父组件传递数据时,就要用到自定义事件

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title></title>
  5. <meta charset="utf-8"/>
  6. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  7. </head>
  8. <body>
  9. <div id="app">
  10. <my-component v-on:myclick="onClick"></my-component>
  11. </div>
  12. <script>
  13. Vue.component('my-component', {
  14. template:'<div>' +
  15. '<button type="button" @click="childClick">点击我触发自定义事件</button></div>' ,
  16. methods: {
  17. childClick () {
  18. this.$emit('myclick', '这是我暴露出去的数据', '这是我暴露出去的数据2')
  19. }
  20. }
  21. })
  22. new Vue({
  23. el: '#app',
  24. methods: {
  25. onClick () {
  26. console.log(arguments)
  27. }
  28. }
  29. })
  30. </script>
  31. </body>
  32. </html>

003组件 - 图3on

这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。当我们的项目比较大时,可以选择更好的状态管理解决方案vuex

  1. var Event=new Vue();
  2. Event.$emit(事件名,数据);
  3. Event.$on(事件名,data => {});

基础用法

标签会把组件使用上下文的内容注入到此标签所占据的位置上。组件分发的概念简单而强大,因为它意味着对一个隔离的组件除了通过属性、事件交互之外,还可以注入内容。

  1. //部分代码省略
  2. <div class="" id="app">
  3. <my-component>
  4. <p>hislots</p>
  5. </my-component>
  6. </div>
  7. <script>
  8. Vue.component('my-component', {
  9. template:'<div><slot></slot><div>'
  10. });
  11. new Vue({
  12. el: "#app"
  13. });
  14. </script>

尽管内容分发这个概念看起来极为复杂,而实际上可以简单了解为把HTML标签传入组件的一种方法。所以归根结底,内容分发是一种为组件传递参数的方法。

编译作用域

组件作用域简单地说是:父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title></title>
  5. <meta charset="utf-8"/>
  6. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  7. </head>
  8. <body>
  9. <div id="app">
  10.   <child-component v-show="someChildProperty"></child-component>
  11. </div>
  12. <script>
  13. Vue.component('child-component', {
  14. template: '<div>这是子组件内容</div>',
  15. data: function () {
  16. return {
  17. someChildProperty: true
  18. }
  19. }
  20. })
  21. new Vue({
  22. el:'#app'
  23. })
  24. </script>
  25. </body>
  26. </html>

这里someChildProperty绑定的是父组件的数据,所以是无效的,获取不到数据。如果想在子组件上绑定,可以是如下代码

  1. <div id="app">
  2.   <child-component ></child-component>
  3. </div>
  4. <script>
  5. Vue.component('child-component', {
  6. // 有效,因为是在正确的作用域内
  7. template: '<div v-show="someChildProperty">这是子组件内容</div>'
  8. data: function () {
  9. return {
  10. someChildProperty: true
  11. }
  12. }
  13. })
  14. new Vue({
  15. el:'#app'
  16. })
  17. </script>

默认 slot

如果要父组件在子组件中插入内容 ,必须要在子组件中声明slot 标签 ,如果子组件模板不包含插口,父组件的内容将会被丢弃

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title></title>
  5. <meta charset="utf-8"/>
  6. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  7. </head>
  8. <body>
  9. <div id="app">
  10. <!-- 1.2 那组件innerHTML位置以后不管有任何代码,都会被放进插槽那个坑里面去 -->
  11. <index>
  12. <span>首页</span>
  13. <span>首页</span>
  14. <span>首页</span>
  15. <h1>手机</h1>
  16. </index>
  17. </div>
  18. <script>
  19. // 插槽的作用就是组件外部取代码片段放到组件内部来
  20. // 定义默认插槽通过slot组件定义,定义好了之后,就相当于一个坑,你可以把它理解为电脑上usb插口
  21. Vue.component('index', {
  22. template:' <div>index</div>'
  23. })
  24. var vm = new Vue({
  25. el: '#app',
  26. })
  27. </script>
  28. </body>
  29. </html>

页面显示结果为:index。所有子组件中的内容都不会被显示,被丢弃。
要想父组件在 子组件中插入内容,必须要在子组件中声明 slot 标签,

  1. <script>
  2. vue. component ( 'index', {
  3. template : '<div><slot></slot>index </div>'
  4. })
  5. var vm=new vue ( {
  6. el : '#app ' ,
  7. })
  8. </script>

具名 slot

slot 元素可以用一个特殊的属性 name 来配置如何分发内容。多个 slot 标签可以有不同的名字。
使用方法。
父组件要在分发的标签中添加属性”slot=name 名”。
子组件在对应分发位置上的 slot 标签添加属性”name=name 名”

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title></title>
  5. <meta charset="utf-8"/>
  6. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  7. </head>
  8. <body>
  9.   <div id="app">
  10.     <child>
  11.       <span slot="one">123456</span>
  12.       <span slot="two">abcdef</span>
  13.     </child>
  14.   </div>
  15.  
  16.  <script>
  17. new Vue({
  18. el:'#app',
  19. components:{
  20. child:{
  21. template:"<div><slot name='two'></slot>我是子组件<slot name='one'></slot></div>"
  22. }
  23. }
  24. });
  25. </script>
  26. </body>
  27. </html>

作用域插槽

作用域插槽更具代表性的应用是列表组件,允许组件自定义应该如何渲染列表每一项

  1. <div id="app">
  2. <child></child>
  3. </div>
  4. <script>
  5. Vue.component('child', {
  6. data(){
  7. return {
  8. list:[1,2,3,4]
  9. }
  10. },
  11. template: '<div> <ul>' +
  12. '<li v-for="item of list">{{item}}</li></ul></div>',
  13. })
  14. var vm = new Vue({
  15. el: '#app'
  16. })
  17. </script>

如果需要child组件在很多地方会被调用,我希望在不同的地方调用child的组件时,这个列表到底怎么循环,列表的样式不是child组件控制的,而是外部child模版占位符告诉我们组件的每一项该如何渲染,也就是说这里不用li标签,而是要用slot标签

  1. <div id="app">
  2. <child>
  3. <template slot-scope="props"> <!--固定写法,属性值可以自定义-->
  4. <li>{{props.item}}</li> <!--用插值表达式就可以直接使用-->
  5. </template>
  6. </child>
  7. </div>
  8. <script>
  9. Vue.component('child', {
  10. data(){
  11. return {
  12. list:[1,2,3,4]
  13. }
  14. },
  15. template: '<div> <ul>' +
  16. '<slot v-for="item of list" :item=item></slot> </ul></div>',
  17. })
  18. var vm = new Vue({
  19. el: '#app'
  20. })
  21. </script>

动态组件

让多个组件使用同一个挂载点,并动态切换,这就是动态组件。通过使用保留的 元素,动态地绑定到它的 is 特性,可以实现动态组件。它的应用场景往往应用在路由控制或者 tab 切换中

  1. <!---省略部分代码-->
  2. <div id="app">
  3. <button @click="change">切换页面</button>
  4. <component :is="currentView"></component>
  5. </div>
  6. <script>
  7. new Vue({
  8. el: '#app',
  9. data:{
  10. index:0,
  11. arr:[
  12. {template:'<div>我是主页</div>'},
  13. {template:'<div>我是提交页</div>'},
  14. {template:'<div>我是存档页</div>'}
  15. ],
  16. },
  17. computed:{
  18. currentView(){
  19. return this.arr[this.index];
  20. }
  21. },
  22. methods:{
  23. change(){
  24. this.index = (++this.index)%3;
  25. }
  26. }
  27. })
  28. </script>
  29. </body>
  30. </html>

component 标签中 is 属性决定了当前采用的子组件,:is 是 v-bind 的简写,绑定了父组 件中 data 的 currentView 属性。点击按钮时,会更改数组 arr 的索引值,同时也修改了子组 件的内容。

keep-alive

包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们,以便提高提取效率。和 相似, 是一个抽象组件,它自身不会渲染一个 DOM 元素,也不会出现在父组件链中

  1. <!--省略部分代码-->
  2. <div id="app">
  3. <button @click="change">切换页面</button>
  4. <keep-alive>
  5. <component :is="currentView"></component>
  6. </keep-alive>
  7. </div>
  8. <script>
  9. new Vue({
  10. el: '#app',
  11. data:{
  12. index:0,
  13. arr:[
  14. {template:'<div>我是主页</div>'},
  15. {template:'<div>我是提交页</div>'},
  16. {template:'<div>我是存档页</div>'}
  17. ],
  18. },
  19. computed:{
  20. currentView(){
  21. return this.arr[this.index];
  22. }
  23. },
  24. methods:{
  25. change(){
  26. /*es6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。*/
  27. let len = this.arr.length;
  28. this.index = (++this.index)% len;
  29. }
  30. }
  31. })
  32. </script>
  33. </body>
  34. </html>

activated 钩子函数

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title></title>
  5. <meta charset="utf-8"/>
  6. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  7. </head>
  8. <body>
  9. <div id="app">
  10. <button @click='toShow'>点击显示子组件</button>
  11. <!----或者<component v-bind:is="which_to_show" keep-alive></component>也行----->
  12. <keep-alive>
  13. <component v-bind:is="which_to_show" ></component>
  14. </keep-alive>
  15. </div>
  16. <script>
  17. // 创建根实例
  18. var vm = new Vue({
  19. el: '#app',
  20. data: {
  21. which_to_show: "first"
  22. },
  23. methods: {
  24. toShow: function () { //切换组件显示
  25. var arr = ["first", "second", "third", ""];
  26. var index = arr.indexOf(this.which_to_show);
  27. if (index < 2) {
  28. this.which_to_show = arr[index + 1];
  29. } else {
  30. this.which_to_show = arr[0];
  31. }
  32. console.log(this.$children);
  33. }
  34. },
  35. components: {
  36. first: { //第一个子组件
  37. template: "<div>这里是子组件1</div>"
  38. },
  39. second: { //第二个子组件
  40. template: "<div>这里是子组件2,这里是延迟后的内容:{{hello}}</div>",
  41. data: function () {
  42. return {
  43. hello: ""
  44. }
  45. },
  46. activated: function (done) { //执行这个参数时,才会切换组件
  47. console.log('beixi')
  48. var self = this;
  49. var startTime = new Date().getTime(); // get the current time
  50. //两秒后执行
  51. while (new Date().getTime() < startTime + 2000){
  52. self.hello='我是延迟后的内容';
  53. }
  54. }
  55. },
  56. third: { //第三个子组件
  57. template: "<div>这里是子组件3</div>"
  58. }
  59. }
  60. });
  61. </script>
  62. </body>
  63. </html>

异步组件

在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从 服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个 工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染

  1. <div id="app">
  2. <async-example></async-example>
  3. </div>
  4. <script>
  5. Vue.component ( 'async-example ', function (resolve, reject){
  6. setTimeout (function (){
  7. //向resolve 回调传递组件定义
  8. resolve ( {
  9. template: '<div>这是异步渲染的内容!</div>'
  10. })
  11. },1000)
  12. })
  13. new vue ( {
  14. el : '#app'
  15. })
  16. </script>

如你所见,这个工厂函数会收到一个 resolve 回调,这个回调函数会在你从服务器得到 组件定义的时候被调用。你也可以调用 reject(reason) 来表示加载失败。这里的 setTimeout 是 为了演示异步,如何获取组件取决于你自己。比如把组件配置成一个对象配置,通过 Ajax 来请求,然后调用 reslove 传入配置选项。
5.6.5 ref 和$refs(了解即可)

在 Vue 中一般很少会用到直接操作 DOM,但不可避免有时候需要用到,这时我们可以 通过 ref 和$refs 来实现:
ref: ref 被用来给元素或子组件注册引用信息, 引用信息将会注册在父组件 的 $refs 对象上,如果是在普通的 DOM 元素上使用,引用指向的就是 DOM 元素,如果是 在子组件上,引用就指向组件的实例。 
003组件 - 图4refs 是一个对象,持有已注册过 ref 的所有的子组件。

普通获取 DOM 的方式

普通获取 DOM 的方式
  1. <div id="app">
  2. <input type="button" value="获取h3的值"@click="getElement"><h3 id="myh3">我是h3</ h3>
  3. </div>
  4. <script>
  5. var vm=new vue ( {
  6. el : "#app" ,
  7. data : { } ,
  8. methods : {
  9. getElement ( ) {
  10. //通过getElementById方式获取DOM对象
  11. console.log (document. getElementById ( "myh3" ) .innerHTML) ;
  12. }
  13. }
  14. })
  15. </script>

ref 使用
  1. <div id="app">
  2. <input type="button" value="获取h3的值"@click="getElement">
  3. <h3 id="myh3" ref="myh3">我是h3</h3>
  4. </div>

3.ref在组件中使用
在子组件中使用 ref属性,会将子组件添加到父组件的$refs对象中,

  1. <div id="app">
  2. <input type="button" value="获取h3的值" @click="getElement">
  3. <h3 id="myh3" ref="myh3">我是h3</h3>
  4. <hr>
  5. <login ref="mylogin"></login>
  6. </div>