Vue框架入门(一)

一、概述

1.1 关于Vue的说法

  • vue 是一套构建用户界面的流行的渐进式前端框架。
  • vue 只关注视图层, 采用自底向上增量开发的设计。
  • vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
  • vue是基于MVVM模式的具体实现。
  • vue 的核心库只关注视图层。
  • 便于与第三方库或既有项目整合。
  • vue的其他扩展库可以高效的进行前后台分离的开发模式,常用的开发库又称为vue全家桶。

Vue在线教程:https://cn.vuejs.org/v2/guide/index.html

1.2 下载和安装

  • 运行环境:nodejs

下载地址:https://nodejs.org/en/download/

  • 开发工具:visual code studio

下载地址:https://visual-studio-code.en.softonic.com/

  • vue核心库

下载地址:https://cn.vuejs.org/v2/guide/installation.html

1.3 Hello World

第一步:新建一个html页面,引入vue核心库。

<script src="js/vue.js" type="text/javascript"></script>

第二步:编写vue代码。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
        <title></title>
        <!-- <script src="https://cdn.jsdelivr.net/npm/vue" type="text/javascript"></script> -->
        <script src="js/vue.js" type="text/javascript"></script>
	</head>
	<body>
        <h4>1-基本绑定</h4>
        <div id="app">
            {{ message }}
        </div>
        <script>
            let vue = new Vue({
                el: '#app',
                data: {
                    message: 'Hello Vue'
                }
            })
        </script>
	</body>
</html>

第三步:在浏览器上打开该html页面即可看到下面效果。
在这里插入图片描述

二、Vue对象详解

2.1 创建Vue对象

每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的。一个vue应用至少包含一个vue实例对象。

基本语法:

new Vue({
	// 选项
}) 

2.2 选项详解

Vue实例可以包含以下选项:

  • 数据属性与方法:当前实例闭包内的全局变量以及全局方法。
  • 操作dom:用于生成dom或绑定dom。
  • 生命周期钩子函数:用于在vue组件或vue实例在创建以及渲染的过程中植入用户的可执行程序。
  • 资源:引入组件或实例所引用的指令、组件、过滤器等。
  • 其他:name属性、minxin混合等。

常用的数据属性与方法:

  • data:Vue 实例的数据对象, Vue 将会递归将 data 的属性转换为 getter/setter方法,从而对data进行赋值。
  • props:props 可以是数组或对象,用于接收来自父组件的数据,访问时与data基本一致,只有组件具备,vue实例对象不具备。
  • computed:计算属性,内容为返回计算结果的函数。
  • methods:实例或组件的内置函数。
  • watch:观察对象,当数据变化时可触发watch中的内置函数。

操作dom:

  • el:只在vue实例中生效,用于绑定实例对象对应的dom对象的id属性。
  • template:vue实例对象或组件的模板语法,模板中除标准的html语法还包括vue的自定义指令以及表达式等。
  • render:以创建dom对象的方式声明dom结构,在vue中不常用。

声明周期钩子函数:在vue对象以及组件从创建、渲染、数据改变等周期内,提供给用户的对外函数接口。

  • created:function() {} 在vue对象创建时被调用。

资源类属性:

  • directives:本组件包含的用户自定义指令集合。
  • filters:本组件包含的过滤器。
  • components:本组件或本实例包含的组件。

其他属性:

  • Name:标注当前组件名称
  • minxin:用于将当前数据属性混入到组件配置属性中。
  • parent:指定当前组件的父实例(组件)。

2.3 data属性

2.3.1 data属性用法

实例中的data对应的是一个对象。例如:

new Vue({
	data: {
		message: 'hello vue'
	}
})

组件中的data对应的是一个函数,需要在函数中声明当前组件的数据属性。

Vue.component({
	data: function() {
		return {
			message: 'hello vue component'
		}
	}
})

2.3.2 data属性的使用方式

可以使用this关键字访问vue实例属性,也可以使用实例变量访问。例如:

let app = new Vue({
	el: '#app',
	data: {
		message: 'hello vue'
	},
	methods: function() {
		setMessage: function() {
			this.message = 'hello java'
			console.log(app.message)
			
			// 在methods中扩展vue实例属性,vue无法识别
			// this.newMessage = 'hello react'  
		}
	}
})

2.3.3 vue实例对外暴露的属性和方法

$el :获取vue实例对应的dom对象;
$data :获取vue实例的data对象;

例如:

new Vue({
	el: '#app',
	data: {
		message: 'hello vue'
	},
	methods: {
		getAttribute: function() {
			console.log(this.$el === document.getElementById('app')) // true
			this.$data.message = "新数据";
		}
	}
})

三、基本功能介绍

3.1 基本数据绑定

vue实现了mvvm模式,用户只需要配置view、model,vue则直接实现了viewmodel,并直接展现视图。

基本语法:

{{js表达式}}

在这里插入图片描述
js表达式的特点:

  • 内容为单句js语句。
  • 表达式不支持赋值(如 var I = 1);
  • 表达式支持三目运算符。
  • 在表达式中可以访问组件的属性与方法,省略this调用。
  • 表达式支持使用原生js对象(如Date等)。

3.2 元素属性绑定

通过vue可以将model层的数据与元素的基本属性绑定,从而对元素属性赋值。

基本语法:

<标签名 v-bind:属性名="js表达式">
	标签内容...
</标签名>

例如:

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
	</head>
	<body>
        <h4>2-元素属性绑定</h4>
        <div id="app">
            <span v-bind:title="message">
                鼠标悬停几秒钟查看此处动态绑定的提示信息!
            </span>
        </div>
        <script>
            let vue = new Vue({
                el: '#app',
                data: {
                    message: '页面加载于' + new Date().toLocaleString()
                }
            })
        </script>
	</body>
</html>

v-bind指令缩写为:

<span :title="message">
    鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>

3.3 条件判断

vue中提供了类似于if、else的语法来实现逻辑判断。

基本语法:

<标签名 v-if="实例对象属性">
	标签内容...
</标签名>

如果v-if取值为true,则加载v-if标签内容;如果如v-if取值为false,则无需加载。

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
	</head>
	<body>
        <h4>3-条件判断</h4>
        <div id="app">
            <p v-if="seen">现在您看到我了</p>
        </div>
        <script>
            let vue = new Vue({
                el: '#app',
                data: {
                   seen: true
                }
            })
        </script>
	</body>
</html>

3.4 循环

v-for模板指令来循环vue实例中的属性。

基本语法:

<标签名 v-for="变量名 in 实例对象属性">
	标签内容...
</标签名>

实例对象属性应该是数组或集合类型。

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
	</head>
	<body>
        <h4>4-循环</h4>
        <div id="app">
           <ul>
               <li v-for="todo in todoList">
                    {{todo.text}}
               </li>
           </ul>
        </div>
        <script>
            let vue = new Vue({
                el: '#app',
                data: {
                   todoList: [
                       {text: 'java'},
                       {text: 'php'},
                       {text: 'android'},
                       {text: 'ios'},
                   ]
                }
            })
        </script>
	</body>
</html>

3.5 数据双向绑定

单向绑定:view中的显示数据与vue实例中的属性绑定即使单项绑定,此时vue实例中的属性变化会同步到view的显示数据中。
双向绑定:用于表单标签(例如:文本框),表单标签的内容与绑定的vue实例中的属性双向同步。双向绑定意味着任意一方改变都会影响另一方的取值。

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
	</head>
	<body>
        <h4>5-数据双向绑定</h4>
        <div id="app">
            <input v-model="message" />
            <button v-on:click="setValue">设置值</button>
            <button v-on:click="getValue">获取值</button>
        </div>
        <script>
            let vue = new Vue({
                el: '#app',
                data: {
                    message: ''
                },
                methods: {
                    setValue() {
                        this.message = '呵呵'
                    }, 
                    getValue() {
                        alert(this.message);
                    }
                }
            })
        </script>
	</body>
</html>

3.6 计算属性

计算属性函数用于返回计算结果。在此函数内可以访问vue组件的属性与方法。
计算函数一般在组件或实例对象的computed中声明,然后在模板中直接访问该函数即可。

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
	</head>
	<body>
        <h4>7-计算属性</h4>
        <div id="app">
            出生日期:<input type="date" v-model="birthday"/><br/>
            <!-- v-model属性绑定了age函数,该input的内容会根据age函数返回值发生变化 -->
            年龄:<input type="number" v-model="age"/><br/>
        </div>
        <script>            
            let vue = new Vue({
                el: '#app',
                data: {
                    birthday: '2012-12-12'
                },
                computed: {
                    // 只要data中任意属性发生变化,都会触发该函数
                    // 该函数的返回值作为v-model="age"文本框的内容
                    age: function() { 
                        return new Date().getFullYear() - new Date(this.birthday).getFullYear()
                    }
                }
            })
        </script>
	</body>
</html>

计算属性与函数的区别?

  • 相同点:

在模板中使用的方式相同,传递参数的方式相同。

  • 不同点:

1)函数在methods中声明,计算属性在computed中声明;
2)计算属性需要返回结果,而函数非必须返回结果;
3)计算属性是基于依赖进行缓存的,意味着只有影响计算结果的属性发生改变的时候才会重新计算,而函数每次调用都会运算;

3.7 观察属性

观察属性:当data发生变化时,vue会调用观察属性绑定的函数,因此也叫监听器。

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
	</head>
	<body>
        <h4>8-观察属性</h4>
        <div id="app">
            出生日期:<input type="date" v-model="birthday"/><br/>
        </div>
        <script>            
            let vue = new Vue({
                el: '#app',
                data: {
                    birthday: '2012-12-12'
                },
                watch: {
                	// 监听属性名字与data属性名字相同
                    // 当data发生变化时,该函数会自动触发
                    birthday: function() {
                        alert(vue.birthday)
                    }
                }
            })
        </script>
	</body>
</html>

监听器函数封装在watch属性中,函数名与监听的数据属性名必须相同。只有在数据属性变化时,监听器函数将会被调用。

3.8 设置样式

3.8.1 通过数据属性设置样式

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
        <style>
            .ba {
                color: red;
            }

            .cr {
                background: aqua;
            }
        </style>
	</head>
	<body>
        <h4>9-设置样式</h4>
        <div id="app">
            <!-- 如果error或warn属性为true,那么就设置class属性为ba或cr -->
            <!-- <div v-bind:class="{ba:error, cr:warn}">样式</div> -->
            
            <div v-bind:class="bb">样式</div>
        </div>
        <script>            
            let vue = new Vue({
                el: '#app',
                data: {
                    error: true,
                    warn: true,
                    // 如果ba为true,则返回ba;如果ba为false则不返回
                    // 如果cr为true,则返回cr;如果cr为false则不返回
                    bb: {ba:false, cr:true}
                }
            })
        </script>
	</body>
</html>

3.8.2 通过函数设置样式

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
        <style>
            .ba {
                color: red;
            }

            .cr {
                background: aqua;
            }
        </style>
	</head>
	<body>
        <h4>10-通过函数计算样式</h4>
        <div id="app">
            <span v-bind:class="getClass">样式1</span>
            <span v-bind:style="getStyle">样式2</span>
        </div>
        <script>        
            let st = {
                name: 'jacky',
                sex: 0
            }
            
            let vue = new Vue({
                el: '#app',
                computed: {
                    getClass: function() {
                        // 返回class名字(ba或cr)
                        return {ba:st.sex == 1, cr:st.sex == 0}
                    },
                    getStyle: function() {
                        // 返回样式单
                        return "color:blue;font-size:30px;"
                    }
                }
            })
        </script>
	</body>
</html>

3.9 事件处理

v-on指令:监听 DOM 事件,并在触发时运行用户编写的js代码。v-on可以绑定几乎全部的事件类型。

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
	</head>
	<body>
        <h4>11-事件处理</h4>
        <div id="app">
            <button v-on:click="minus">-</button>
            {{count}}
            <button v-on:click="add">+</button>
        </div>
        <script>
            let vue = new Vue({
                el: '#app',
                data: {
                    count: 0
                },
                methods: {
                    add: function() {
                        this.count++
                    },
                    minus: function() {
                        if (this.count > 0) {
                            this.count--
                        }
                    }
                }
            })
        </script>
	</body>
</html>

v-on指令缩写为@

<button @click="minus">-</button>
{{count}}
<button @click="add">+</button>

3.10 函数传参

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
        
	</head>
	<body>
        <h4>11-参数传递</h4>
        <div id="app">
            <button v-on:click="add(2, $event)">+2</button>
            {{count}}
        </div>
        <script>        
                    
            let vue = new Vue({
                el: '#app',
                data: {
                    count: 0
                },
                methods: {
                    // e是dom的event对象
                    add: function(num, e) {
                        this.count = num + this.count;
                    }
                }
            })
        </script>
	</body>
</html>

上面v-on指令的取值处直接调用add函数并传递参数,在模板中可以使用$event获取到event对象,并传递给响应函数。

3.11 表单

vue通过v-model指令将dom元素与数据属性双向绑定,其工作原理:
1)监听用户的输入事件以更新数据;
2)监听数据更新dom元素取值;

vue通过以下监听事件来监控dom元素的属性变化。

dom元素 监听属性 监听事件
text\textarea value input
checkbox\radio checked change
select value change

示例代码:

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
        
	</head>
	<body>
        <h4>13-表单</h4>
        <div id="app">
            <form>
                <!-- 如果没有lazy,那么修改输入框内容,span标签内容也会发生变化 -->
                <!-- 如果指定了lazy,那么修改输入框内容,span标签内容不会马上发生变化,只有输入框失去焦点后,span标签内容才会发生变化 -->
                <input v-model.lazy="msg" v-on:change="getLength"/>
                <span>{{msg}}</span>
                <br/>
                <input v-model.number="age" type="number" />
                <br/>
            </form>
        </div>
        <script>        
                    
            let vue = new Vue({
                el: '#app',
                data: {
                    msg: 'hello',
                    age: 0
                },
                methods: {
                    getLength: function() {
                        console.log("msg length is " + this.msg.length)
                    }
                }
            })
        </script>
	</body>
</html>

我们可以在vmodel后面指定修饰符:
vmodel.lazy:一般适用于text,将数据属性更新的事件由input转变为使用 change 事件进行同步。
vmodel.number:将用户的输入值转为数值类型。
vmodel.trim:自动过滤用户输入的首尾空白字符。

例如:

<input vmodel.lazy="message" />
<input vmodel.number="age" />
<input vmodel.trim="msg" />

它们也可以组合在一起使用:

<input vmodel.lazy.trim="message" />

3.12 组件

组件是可复用的 Vue 实例,一个组件映射着一个MVVM模型,声明一个组件后,在其他实例或组件中使用组件标签直接调用即可完成组件的显示。一个大型的工程由多个可视化可视化界面,每个界面都是由多个组件组成。
在这里插入图片描述

3.12.1 组件注册

组件的注册:声明组件模板内置函数。

基本语法:

Vue.component('组件名', { 
	data: function() {
		return {
			// 组件全局变量
		}
	},
	template: 'html模板',
	methods: {
		// 方法属性
	},
	computed: {
		// 计算属性
	}
})

与实例对象不同,组件中的data是一个函数,函数的返回值为全局变量。
与实例对象不同,组件中很少使用el,都是用template声明模板,在模板中要包含根节点。

// 注册组件        
Vue.component('button-counter', {
    // 定义组件中的全局变量
    // 该变量在组件中可以访问
    data: function() {
        return {
            count: 0
        }
    },
    // 定义组件模板
    template: '<button v-on:click="count++">{{count}}</button>'
}) 

组件引用:

<div id="app">
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
</div>

注意:如果组件名是多个英文组成的字符串,那么引入组件时候多个英文之间使用横杠分割。

示例代码:

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
        <script>
                      
        </script>
	</head>
	<body>
        <h4>14-组件</h4>
        <div id="app">
            <!-- 使用组件 -->
            <button-counter></button-counter>
            <button-counter></button-counter>
            <button-counter></button-counter>
        </div>
        <script>
            // 注册组件        
            Vue.component('button-counter', {
                // 定义组件中的全局变量
                // 该变量在组件中可以访问
                data: function() {
                    return {
                        count: 0
                    }
                },
                // 定义组件模板
                template: '<button v-on:click="count++">{{count}}</button>'
            }) 
            
            // 在实例中应用组件
            let vue = new Vue({ 
                el: '#app',
                data: {

                }
            })
        </script>
	</body>
</html>

3.12.2 props属性

props属性主要用于父组件向子组件中传递参数。props中声明的属性是全局属性,可以在方法、计算属性中访问。

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
        <script>
                      
        </script>
	</head>
	<body>
        <h4>15-props属性</h4>
        <div id="app">
            <!-- 普通属性传递 -->
            <blog-component blog-title="测试"></blog-component>
            <!-- 组件属性传递 -->
            <blog-component v-bind:blog-title="posts[0].title"></blog-component>
        </div>
        <script>
            // 定义一个组件        
            Vue.component('blog-component', {
                props: ['blogTitle'],
                template: '<h3>{{blogTitle}}</h3>'
            }) 
            
            // 在实例中应用组件
            let vue = new Vue({ 
                el: '#app',
                data: {
                    posts: [
                        { id: 1, title: 'My journey with Vue' },
                        { id: 2, title: 'Blogging with Vue' },
                        { id: 3, title: 'Why Vue is so fun' }
                    ]
                }
            })
        </script>
	</body>
</html>

Post的命名规则 :在定义prop时可以使用camelCase和kebab-case两种方式。但在模板中引入组件时,由于html是忽略大小写的,因此只能使用kebab-case方式引入。

在声明属性时可以设定属性的数据类型,如果传入的属性与类型不符合,将会提示相关的错误信息。

Vue.component('blog-component', {
   props: {
        blogTitle: String
    }, 
    template: '<h3>{{blogTitle}}</h3>'
}) 

上面程序指定blogTitle的类型为String,那么传入属性必须是字符串类型,否则报错。

下面是常见的数据类型:
在这里插入图片描述

3.12.3 子组件捕获事件

当触发子组件的事件处理函数后,需要调用父组件的响应函数进行响应。

在父组件中通过v-on:method方式注册自定义处理函数,例如:

<blog-post v-on:enlarge-text="处理函数"></blog-post>

在子组件中使用 e m i t emit方法通知父组件“处理函数”执行。 emit方法的参数名对应着v-on事件名。

Vue.component('blog-post', {
     props: ['post'],
     template:  // $emit方法传入事件名称来触发一个事件
         `<div class="blog-post">
             <h3>{{post.title}}</h3>
             <button @click="$emit('enlarge-text')">Enlarge text</button>
             <div v-html="post.content"></div>
         </div>`
}) 

示例代码:

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
        <script>
                      
        </script>
	</head>
	<body>
        <h4>16-子组件事件捕获</h4>
        <div id="app">
            <div :style="{fontSize: postFontSize + 'em'}">
                <!-- 
                    参数说明:
                        v-for:循环父组件的posts属性
                        key: 唯一表示每个item
                        post:父组件传递给子组件的参数,该名字与子组件的post属性相同
                        v-on:定义一个监听器,该监听器用来监听enLarge-text事件。
                            有了该事件,父组件就会接收该事件并更新postFontSize属性
                -->
                <blog-post v-for="post in posts" v-bind:key="post.id" v-bind:post="post"
                    v-on:enlarge-text="postFontSize += 0.1"></blog-post>
            </div>
        </div>
        <script>
            // 子组件        
            Vue.component('blog-post', {
                props: ['post'],
                template:  // $emit方法传入事件名称来触发一个事件
                    `<div class="blog-post">
                        <h3>{{post.title}}</h3>
                        <button @click="$emit('enlarge-text')">Enlarge text</button>
                        <div v-html="post.content"></div>
                    </div>`
            }) 

            // 父组件
            let vue = new Vue({ 
                el: '#app',
                data: {
                    posts: [
                        { id: 1, title: 'My journey with Vue', content: 'this is content' },
                        { id: 2, title: 'Blogging with Vue', content: 'this is content' },
                        { id: 3, title: 'Why Vue is so fun', content: 'this is content' }
                    ],
                    postFontSize: 1
                }
            })
        </script>
	</body>
</html>

3.12.4 vmodel在组件中的使用

使用自定义事件处理v-model的双向绑定。一般用于子组件中的输入框与父组件中的属性双向绑定。

需求:在vue实例中定义searchText属性,然后在子组件中定义一个input搜索框,搜索框内容发生变化的时候,改变vue实例的searchText属性的值。

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
	</head>
	<body>
        <h4>17-vmodel在组件中的应用</h4>
        <div id="app">
            <!-- 
                在组件中使用v-model就相当于:
                <custom-input v-bind:value="searchText"
                    v-on:input="searchText = $event"></custom-input>

                上面代码执行了两个操作:
                1)v-bind:value 实现父组件的searchText参数与子组件value属性之间的数据绑定 
                2)v-on:input 定义一个监听器,该监听器用来监听input事件。当子组件中的input内容发生改变,
                    那么就会就会把新的内容($event)设置到父组件的searchText参数中。
            -->
            <custom-input v-model="searchText"></custom-input>
            {{searchText}}
        </div>
        <script>

            // 子组件
            Vue.component('custom-input', {
                props: ['value'],
                // v-on:input用于监控用户输入,当input事件被触发的时候,
                // 将新的值($event.target.value)通过自定义的input事件抛出
                template: `
                    <input v-bind:value="value" v-on:input="$emit('input', $event.target.value)" />
                `
            })

            // 父组件
            let vue = new Vue({ 
                el: '#app',
                data: {
                    searchText: '呵呵'
                }
            })
        </script>
	</body>
</html>

3.13 插槽

插槽:子组件中的模板接口,它可以在父组件中填充子组件的模板。

定义插槽:

<slot></slot>

示例代码:

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
        <script>
                      
        </script>
	</head>
	<body>
        <h4>18-插槽</h4>
        <div id="app">
            <alert-box>
                Something bad happened.
            </alert-box>
        </div>
        <script>
            // 子组件
            Vue.component('alert-box', {
                template: `
                    <div class="demo-alert-box">
                        <strong>Error!</strong>
                        <slot></slot>
                    </div>
                `
            })

            // 父组件
            let vue = new Vue({ 
                el: '#app'
            })
        </script>
	</body>
</html>

3.14 动态组件

当组件的内容不确定时,使用动态组件技术选择加载的组件。例如:选择Posts的时候显示Posts组件,选择Archive时候显示Archive组件。
在这里插入图片描述

3.14.1 创建动态组件

第一步:在data对象中定义一个属性,该属性指定要加载的组件名;

let vue = new Vue({ 
    el: '#app',
    data: {
        currentComponent: 'component-2'
    }
})

第二步:使用component引用组件。

<component v-bind:is="currentComponent"></component>

上面<component>元素是vue 里面的一个内置组件,v-bind:is 决定哪个组件被渲染成动态组件。

示例代码:

<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript"></script>
        <script>
                      
        </script>
	</head>
	<body>
        <h4>19-动态组件</h4>
        <div id="app">
            <component v-bind:is="currentComponent"></component>
        </div>
        <script>
            // 子组件
            Vue.component('component-1', {
                template: `
                    <h3>组件1...</h3>
                `
            })

            Vue.component('component-2', {
                template: `
                    <h3>组件2...</h3>
                `
            })

            // 父组件
            let vue = new Vue({ 
                el: '#app',
                data: {
                    currentComponent: 'component-2'
                }
            })
        </script>
	</body>
</html>

3.14.2 动态组件缓存问题

在这里插入图片描述
当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题。这时候可以使用<keep-alive>标签。使用<keep-alive>修饰的组件会保持在内存中,下次使用组件时候直接显示,避免重新渲染的问题。

<!-- 失活的组件将会被缓存!-->
<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>
发布了111 篇原创文章 · 获赞 41 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/zhongliwen1981/article/details/100703449