Vue.js+vue-element搭建属于自己的后台管理模板:更深入了解Vue.js(三)
前言
上一章我们介绍了关于Vue实例中一些基本用法,但是组件、自定义指令、Render函数这些放到了本章来介绍,原因是它们要比前面讲的要难一些,组件是Vue.js最核心的功能,学习使用组件也是必不可少的知识点。
Vue实例属性和方法
在我们学习组件之前,更深入的了解下Vue实例,它除了data数据对象属性外,Vue实例还暴露了一些有用的实例属性和方法,它们都有前缀$,以便与用户定义的属性区分开来,详细适用方法可以查阅官方API文档。
实例属性:
- vm.$data:类型Object,Vue 实例观察的数据对象。Vue 实例代理了对其 data 对象属性的访问。
- vm.$props:类型Object,当前组件接收到的 props 对象。Vue 实例代理了对其 props 对象属性的访问。
- vm.$el:类型:Element,只读,Vue 实例使用的根 DOM 元素。
- vm.$options:类型Object,只读,用于当前 Vue 实例的初始化选项。需要在选项中包含自定义属性时会有用处
- vm.$parent:类型:Vue instance,只读,父实例,如果当前实例有的话。
- vm.$root:类型:Vue instance,只读,当前实例的直接子组件。需要注意 $children 并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用 $children 来进行数据绑定,考虑使用一个数组配合 v-for 来生成子组件,并且使用 Array 作为真正的来源。
- vm.$slots:类型:{ [name: string]: ?Array<VNode> },只读,用来访问被插槽分发的内容。每个具名插槽 有其相应的属性 (例如:v-slot:foo 中的内容将会在 vm.$slots.foo 中被找到)。default 属性包括了所有没有被包含在具名插槽中的节点,或 v-slot:default 的内容。
- vm.$scopedSlots:类型:{ [name: string]: props => Array<VNode> | undefined },只读,用来访问作用域插槽。对于包括 默认 slot 在内的每一个插槽,该对象都包含一个返回相应 VNode 的函数。vm.$scopedSlots 在使用渲染函数开发一个组件时特别有用。
- vm.$refs:类型:Object,只读,一个对象,持有注册过 ref 特性 的所有 DOM 元素和组件实例。
- vm.$isServer:类型:boolean,只读,当前 Vue 实例是否运行于服务器。
- vm.$attrs:类型:{ [key: string]: string },只读,包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
- vm.$listeners:类型:{ [key: string]: Function | Array<Function> },只读,包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
实例方法 / 数据:
- vm.$watch( expOrFn, callback, [options] ):返回值:{Function} unwatch,用法:观察 Vue 实例变化的一个表达式或计算属性函数。回调函数得到的参数为新值和旧值。表达式只接受监督的键路径。对于更复杂的表达式,用一个函数取代。
- vm.$set( target, propertyName/index, value ):返回值:设置的值。用法:这是全局 Vue.set 的别名。
- vm.$delete( target, propertyName/index ): 这是全局 Vue.delete 的别名。
实例方法 / 事件:
- vm.$on( event, callback ) :监听当前实例上的自定义事件。事件可以由vm.$emit触发。回调函数会接收所有传入事件触发函数的额外参数。
- vm.$once( event, callback ):监听一个自定义事件,但是只触发一次,在第一次触发之后移除监听器。
- vm.$off( [event, callback] ):移除自定义事件监听器。
- vm.$emit( eventName, […args] ):触发当前实例上的事件。附加参数都会传给监听器回调。
实例方法 / 生命周期:
- vm.$mount( [elementOrSelector] ):返回值:vm - 实例自身,如果 Vue 实例在实例化时没有收到 el 选项,则它处于“未挂载”状态,没有关联的 DOM 元素。可以使用 vm.$mount() 手动地挂载一个未挂载的实例。
- vm.$forceUpdate():迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。
- vm.$nextTick( [callback] ):将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
- vm.$destroy():完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器。
组件
组件是Vue.js中最强大的功能之一,核心目标是为了可重用性高,减少重复性开发。组件需要注册才可以使用,注册有全局注册和局部注册两种方式,全局注册的组件可以在任何Vue实例上都可以使用。Vue实例中使用compoents选项来注册局部组件,局部组件只能在当前实例中使用,组件中也可以使用compoents选项来注册子组件,使组件可以嵌套使用。
全局注册,代码示例如下:
<div id="app">
<my-component></my-component>
</div>
<script>
Vue.component('my-component', {
template: '<div>这里是组件内容</div>'
}) var app = new Vue({
el: '#app'
})
</script>
渲染后的结果是:
<div id="app">
<div>这里是组件内容</div>
</div>
局部注册,代码示例如下:
<div id="app">
<my-component></my-component>
</div>
<script>
var app = new Vue({
el: '#app',
components: {
'my-component': {template:'<div>这里是组件内容</div>'}
}
})
</script>
组件中除了template选项外,还可以像Vue实例那样使用其他选项,比如data、methods、computed等,data选项必须是函数,必须return返回才有效。
代码实例如下:
<div id="app">
<my-component></my-component>
</div>
<script>
Vue.component('my-component', {
template: '<div>这里是组件内容</div>',
data: function(){
return {
message: '组件内容' //组件内部定义的数据
}
}
}) var app = new Vue({
el: '#app'
})
</script>
prop传递数据:
Vue实例或父组件中调用子组件时,通常需要向子组件传递数据,这个过程需要通过prop来实现,组件中提供了props选项来接收参数,props的值分两种,一种是字符串数组,另一种是对象,使用对象方式实际项目中最为常见,代码示例如下:
<div id="app">
<my-component message="来自父组件的数据"></my-component>
</div>
<script>
Vue.component('my-component', {
props: ['message'],
template: '<div>{{ message }}</div>'
}) var app = new Vue({
el: '#app'
})
</script>
通常父组件中传递的数据并不是写死的,而是来自父级的动态数据,这时可以使用指令v-bind来动态绑定prop的值,当父组件的数据变化时也会传递给子组件,上面例子中props的值使用的是字符串数组方式,下面我们使用另一种对象方式接收,代码实例如下:
<div id="app">
<input type="test" v-model="msg">
<my-component :message="msg"></my-component>
</div>
<script>
Vue.component('my-component', {
props: {
message: String
},
template: '<div>子组件中显示:{{ message }}</div>'
}) var app = new Vue({
el: '#app',
data: {
msg: ''
}
})
</script>
数据验证:
当props值为对象时,定义参数类型type,包括String、Number、Boolean、Object、Array、Function,参数也可以设置初始值default,定义是否必传参数required:true,还有自定义验证函数等,当prop验证失败时,在开发版本下会在控制台抛出一条警告。
代码实例如下:
<script>
Vue.component('my-component', {
props: {
propA: Number, //必须是数字类型
propB: [String, Number], //必须是字符串或数字类型
propC: { //布尔类型,如果未传入,默认值为true
type: Boolean,
default: true
},
propD: { //数字类型,必传参数
type: Number,
required: true
},
propE: { //如果是数组或对象类型,默认值必须是一个函数来返回
type: Array,
default: function () {
return [];
}
},
propF: { //自定义一个验证函数
validator: function () {
return value > 10;
}
}
}
})
</script>
自定义事件:
上面我们知道了父组件向子组件传递数据时使用prop来完成,这里说明一下prop值属于引用类型,当改变prop值会直接影响父组件,重复使用组件时直接改变prop值时就失去了复用的目的。那么子组件中向父组件传递数据要怎么处理呢,这里我们就用到了自定义事件,自定义事件首先要在父组件中通过v-on监听一个事件,事件钩子函数在父组件实例中创建,在子组件中通过this.$emit()来触发这个自定义事件,$emit()方法的第一个参数是自定义事件的名称,后面参数为要传递的数据,后面参数可以为空或多个,代码实例如下:
<div id="app">
<p>总数:{{ total }}</p>
<my-component @inccount="handleInc"></my-component>
</div>
<script>
Vue.component('my-component', {
template: '<div><button @click="handleIncrease">+1</button></div>',
data: function(){
return {
counter: 0
}
},
methods: {
handleIncrease: function(){
this.counter++;
this.$emit('inccount', this.counter); //触发父组件中自定义事件
}
},
})
var app = new Vue({
el: '#app',
data: {
total: 0
},
methods: {
handleInc: function (count){
this.total = count;
}
}
})
</script>
组件上使用v-model:
前面章节中我们讲过v-model是一个特殊的语法糖,实际它等同于input自定义事件,我们这里通过v-model来创建自定义的表单输入组件,进行数据双向绑定,代码实例如下:
<div id="app">
<p>总数:{{ total }}</p>
<my-component v-model="total"></my-component>
</div>
<script>
Vue.component('my-component', {
props: ['value'],
template: '<div><input :value="value" @input="updateValue"></div>',
methods: {
updateValue: function(){
this.$emit('input', event.target.value);
}
},
})
var app = new Vue({
el: '#app',
data: {
total: 0
}
})
</script>
非父子组件通信:
在实际业务中,除了父子组件通信外,还有很多非父子组件通信的场景,比如兄弟组件和跨多级组件,Vue.js中提供了一个方法,创建一个空的Vue实例作为中央事件总线(bus),也就是一个中介,初始化Vue实例时,监听这个中介事件来完成自己的业务逻辑。除了它Vue还提供了一个更好的解决方案 vuex状态管理插件。
插槽
Vue.js 实现了内容分发,使用slot元素作为承载分发内容的出口,混合父组件内容与子组件的模板时使用。
单个Slot:
在子组件内使用特殊的<slot>元素就可以开启一个slot默认插槽,在父组件模板中调用子组件标签内的所有内容将替换子组件的<slot>元素内的内容,代码实例如下:
<div id="app">
<my-component>
<p>分发的内容</p>
<p>更多分发的内容</p>
</my-component>
</div>
<script>
Vue.component('my-component', {
template: '\
<div>\
<slot>\
<p>如果父组件没有插入内容,我将作为默认出现</p>\
</slot>\
</div>'
})
var app = new Vue({
el: '#app'
})
</script>
渲染后的结果是:
<div id="app">
<div>
<p>分发的内容</p>
<p>更多分发的内容</p>
</div>
</div>
具名Slot:
子组件模板中有时我们需要多个插槽,slot元素中指定name属性,可以分发多个内容,具名Slot可以与单个Slot共存,自 2.6.0 起我们可以在一个 <template> 元素上使用 v-slot 指令,代码实例如下:
<div id="app">
<my-component>
<h2 slot="header">标题</h2>
<p>分发的内容</p>
<p>更多分发的内容</p>
<h5 slot="footer">底部信息</h5>
</my-component>
<!-- 自 2.6.0 起新推荐的语法 -->
<my-component>
<template v-slot:header>
<h2>标题</h2>
</template>
<p>分发的内容</p>
<p>更多分发的内容</p>
<template v-slot:footer>
<h5>底部信息</h5>
</template>
</my-component>
</div>
<script>
Vue.component('my-component', {
template: '\
<div>\
<div class="header">\
<slot name="header"><slot>\
</div>\
<div class="main">\
<slot><slot>\
</div>\
<div class="footer">\
<slot name="footer"><slot>\
</div>\
</div>'
})
var app = new Vue({
el: '#app'
})
</script>
编译作用域:
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
作用域插槽:
作用域插槽是一种特殊的Slot,使用slot-scope特性可以接收传递给插槽的 prop,自 2.6.0 起已废弃的使用 slot-scope 特性语法,新推荐的语法在<slot>元素的一个特性绑定子组件内部数据,这个特性绑定称为插槽prop,在父组件中v-slot具名插槽带一个值类定义我们提供的插槽prop的名字,代码实例如下:
<div id="app">
<my-component :user="{firstName:'newfirst',lastName:'newlast'}">
<!-- user名字可以随意定义 -->
<template v-slot:default="user">
{{user.lastName}}
</template>
<template v-slot:main="data">
{{data.message}}
</template>
</my-component>
</div>
<script>
Vue.component('my-component', {
data() {
return {
message: '子组件内部消息'
}
},
props: {
user: {
type: Object,
default: function () {
return {
firstName: 'first',
lastName: 'last'
};
}
}
},
template: '\
<div>\
<div>\
<slot :lastName="user.lastName">\
{{user.firstName}}\
</slot>\
</div>\
<div>\
<slot name="main" :message="message">\
</slot>\
</div>\
</div>'
})
var app = new Vue({
el: '#app'
})
</script>
自定义指令
我们已经介绍过了许多Vue内置的指令,比如 v-if、 v-show 等,这些内置指令能满足我们绝大部分业务需求,不过在需要一些特殊功能时,我们仍然希望对DOM底层进行操作,这时我们就要用到自定义指令来完成。
注册自定义指令:
自定义指令的注册方法也分全局注册和局部注册,跟组件注册方式很像,代码实例如下:
// 注册一个全局自定义指令
Vue.directive('focus', {
inserted: function (el) {
el.focus()
}
}) //在组件中注册局部自定义指令
var app = new Vue({
el: '#app',
directives: {
focus: {
inserted: function (el) {
el.focus()
}
}
}
})
钩子函数:
一个指令定义对象可以提供如下几个钩子函数,每个都是可选的。
- bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
- inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
- update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
- componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
- unbind:只调用一次,指令与元素解绑时调用。
钩子函数参数:
指令钩子函数会被传入以下参数:
- el:指令所绑定的元素,可以用来直接操作 DOM 。
- binding:一个对象,包含以下属性:
- name:指令名,不包括 v- 前缀。
- value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
- oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
- expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
- arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。
- modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
- vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
- oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
下面是结合了以上参数的一个具体示例,代码实例如下:
<div id="hook-arguments-example" v-demo:foo.a.b="message"></div>
Vue.directive('demo', {
bind: function (el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name: ' + s(binding.name) + '<br>' +
'value: ' + s(binding.value) + '<br>' +
'expression: ' + s(binding.expression) + '<br>' +
'argument: ' + s(binding.arg) + '<br>' +
'modifiers: ' + s(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
}) new Vue({
el: '#hook-arguments-example',
data: {
message: 'hello!'
}
})
Render函数
什么是Render函数,Vue.js2.x开始使用了Virtual Dom(虚拟DOM)来更新DOM节点,提升渲染性能,Vue.js编译时会把template模板解析为Virtual Dom,Vue.js也提供了Render函数选项,即渲染函数,使用 JavaScript 代替模板功能。组件的template基本上满足我们业务需求,但有些场景中,使用Virtual Dom会更简单。(这个我们暂时用不到,如果想了解的朋友可以去官方文档中进一步学习)
目录导航
- Vue.js+vue-element搭建属于自己的后台管理模板:什么是Vue.js?(一)
- Vue.js+vue-element搭建属于自己的后台管理模板:Vue.js快速入门(二)
- Vue.js+vue-element搭建属于自己的后台管理模板:更深入了解Vue.js(三)
- Vue.js+vue-element搭建属于自己的后台管理模板:创建一个项目(四)
参考资料
Vue.js
Vue.js+vue-element搭建属于自己的后台管理模板:更深入了解Vue.js(三)的更多相关文章
- Vue.js+vue-element搭建属于自己的后台管理模板:什么是Vue.js?(一)
Vue.js+vue-element搭建属于自己的后台管理模板:Vue.js是什么?(一) 前言 本教程主要讲解关于前端Vue.js框架相关技术知识,通过学习一步一步学会搭建属于自己的后台管理模板,并 ...
- Vue.js+vue-element搭建属于自己的后台管理模板:Vue.js快速入门(二)
Vue.js+vue-element搭建属于自己的后台管理模板:Vue.js快速入门(二) 前言 上篇文章对Vue.js有了初步理解,接下来我们把Vue.js基础语法快速的过一遍,先混个脸熟留个印象就 ...
- Vue.js+vue-element搭建属于自己的后台管理模板:创建一个项目(四)
Vue.js+vue-element搭建属于自己的后台管理模板:创建一个项目(四) 前言 本章主要讲解通过Vue CLI 脚手架构建工具创建一个项目,在学习Vue CLI之前我们需要先了解下webpa ...
- GitHub Vue项目推荐|Vue+Element实现的电商后台管理系统功能丰富
GitHub Vue项目推荐|mall-admin-web是一个电商后台管理系统的前端项目基于Vue+Element实现 主要包括商品管理.订单管理.会员管理.促销管理.运营管理.内容管理.统计报表. ...
- Vue + ElementUI 后台管理模板推荐
最近学习和项目都用到了Vue和ElementUI,自己不是专业前端,搞这些UI上的东西还是有些难度,这里推荐两个Vue + ElementUI后台管理模板 vue-element-admin vue- ...
- 写了一个vue+antdv的后台管理模板
1,项目简介 写在前面===>这是一个vue+antdv的后台管理模板 项目地址: https://github.com/BaiFangZi/vue-antd-manage 1.1,概述 最 ...
- 28个漂亮的React.js后台管理模板
React管理模板 为您的React Web应用程序开发一个管理区域可能非常耗时.它与设计所有前端页面一样重要. 这是2020年设计出色的顶级React.js后台管理模板的列表. 这些模板确实有价值, ...
- 使用vue3.0和element实现后台管理模板
通过自己所学的这段时间,利用空余时间,使用vue3.0脚手架搭建的一个关于后台的管理模板,所实现功能也是模仿一个后台的界面,数据分为两种存放,一种是直接存储到mlab,这里的数据是存放这登录注册,只有 ...
- Asp.NetMVC利用LigerUI搭建一个简单的后台管理详解(函登录验证)
上一篇 Asp.Net 中Grid详解两种方法使用LigerUI加载数据库数据填充数据分页 了解了LigerUI 中Grid的基本用法 现在结合上一篇的内容做一个简单的后台管理,当然也有前台的页面 ...
随机推荐
- Nginx配置实例-动静分离实例:搭建静态资源服务器
场景 Nginx入门简介和反向代理.负载均衡.动静分离理解: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/102790862 U ...
- windows10 双系统安装后,grub2 引导修复(亲自实验);grub2 命令行 手动加载内核;fedora 29 系统grub2引导修复;
之前在本机有fedora 29的系统,但是由于错误安装,把windows10 启动安装到 linux 所在的硬盘中,导致原来的 efi中的grub启动被破坏,不能进入到linux中:我首先通过磁盘精灵 ...
- windows 安装xps查看器; windows 10 安装 xps viewer
最近发现windows 默认是没有xps 查看器的,需要自己手动添加: 安装完成后,即可使用: 参考链接:https://www.windowscentral.com/how-get-xps-view ...
- Linux-3.14.12内存管理笔记【伙伴管理算法(4)】
此处承接前面未深入分析的页面释放部分,主要详细分析伙伴管理算法中页面释放的实现.页面释放的函数入口是__free_page(),其实则是一个宏定义. 具体实现: [file:/include/linu ...
- 微信 电脑版 HOOK(WeChat PC Hook)- 定位dll获取数据和调用功能的地址
方案一:CE搜索内存数据,OD断点查看堆栈方案二:使用旧版本的特征码,在新版本搜索方案三:借鉴WeTool的dll,用ida分析获取地址方案四:ida静态分析微信,看字符串和输出日志 源码: http ...
- 05-深入python的set和dict
一.深入python的set和dict 1.1.dict的abc继承关系 from collections.abc import Mapping,MutableMapping #dict属于mappi ...
- Java 操作Word书签(三):用文本、图片、表格替换书签
本篇文章将继续介绍通过Java来操作Word书签的方法,即替换Word中已有书签,包括用新的文本.图片.表格等替换原有书签处的内容. 使用工具:Free Spire.Doc for Java (免费版 ...
- php 将科学计算法得出的结果转换成原始数据 NumToStr
由于php最大只支持显示 15位因的数据运算,大于15位的2数加减乘除的数据的结果,会直接用科学计数法显示, 但在现实生活中,科学计数法不利于普通人识别,所以,本函数将:科学计数法的出的结果转换成原始 ...
- How to: Specify a Display Member (for a Lookup Editor, Detail Form Caption, etc.)如何:指定显示成员(用于查找编辑器、详细信息表单标题等)
Each business object used in an XAF application should have a default property. The default property ...
- C language bit byte and word
bit:The smallest storage unit of a computer byte:Common computer storage unit word:Computer natural ...