关于vue组件的一个小结
用vue进行开发到目前为止也有将近一年的时间了,在项目技术选型的时候隔壁组选 react的时候我们坚持使用vue作为前端的开发框架。虽然两者思想上的差异不大,但是vue的语法在代码的可读性以及后期的维护成本更加的适合,而且最近看到Apache对react的相关许可限制;这里不讨论react和vue的对比哪个好,技术框架没有最好的,只有适合项目才是最好的。
进入主题。。。。。。。
组件,是vue的核心之一。
我们可以把页面各个子模块看成一个组件,可以独立拆分出来。这样不仅维护变得简单了,而且代码复用性也高。
vue组件分为全局组件和局部组件。组件中属性和vue实例基本类似,基本可以使用其所有属性如computed,methods,components,filter,directive.....但data属性不同,在组件中data是函数,而且数据需要return出来;因为组件可能会被引用多次,就会创建多次实例,如果data是个对象的话那引用到这个组件的地方都将公用一个data这样就回造成了数据的污染。如果使用data属性函数返回一个对象的话就可以解决这个问题,每次引入到这个组件实例的时候就可以在data函数中返回一个初始的数据对象。
组件的介绍
全局组件
使用Vue.component进行全局注册,所有vue实例都会共享此组件
<div id="app">
{{msg}}
<const-comp></const-comp> </div>
<script> Vue.component('constComp', {
template: "<h3>我是全局组件</h3>" }); new Vue({
el: "#app",
data: {
msg: "hello component"
}
}); </script>
局部组件
局部组件只能在引入当前的vue实例中有效,在当前vue实例中components属性加上引入进来的组件实例即可
<div id="app">
{{msg}}
<!-- <const-comp></const-comp> -->
<local-comp></local-comp>
</div>
<script> /*Vue.component('constComp', {
template: "<h3>我是全局组件</h3>" });*/
let localComp = {
template: "<div>我是局部组件</div>"
};
new Vue({
el: "#app",
data: {
msg: "hello component"
},
components: {
localComp
}
}); </script>
单文件组件(xxx.vue)
其实就是将写在js中的组件提出到一个vue文件中写而已,这样组件更加的好维护以及阅读性也会好,提取出来了相应的引入即可,不会显得文件很多行很长。
其主要有<template></template><script></script><style></style>这三个标签,每个标签做自己的事。template就像我们在html中写dom,script写js代码当前的组件实例,style写组件样式,注意:加上scoped即可使当前样式只在当前组件生效,组件渲染的时候此组件的dom会加上data-v-xxx属性来选择当前组件样式。如果没加上scoped的话当前组件的样式就会在引入这个组件的实例中造成影响
如我写的一个found.vue文件demo
<template>
<div>
<div class="saerchDiv">
<Search
@result-click="resultClick"
@on-change="changeResult"
:results="results"
v-model="searchVal"
position="absolute"
auto-scroll-to-top
top="46px"
@on-focus="onFocus"
@on-cancel="onCancel"
@on-submit="onSubmit"
ref="search"></Search>
</div> </div>
</template>
<script>
import {Search} from 'vux'; export default {
name:"found",
data() {
return {
msg:"found page",
// searchVal:"寻找更多好文章",
searchVal:"",
results:[]
}
},
components:{
Search
},
methods:{
resultClick(item) { //选中搜索
console.log(item.title);
},
changeResult(val) { //获取搜索关键字
console.log(val);
/*this.$http.get('').then(res => { }).catch(err => { });*/ this.results = this.getResults(val);
},
onFocus(){
console.log("on focus");
// this.searchVal = ""
},
onCancel(){
console.log("点击取消按钮");
},
onSubmit(){
console.log("on submit");
},
getResults(keyword) { //暂时获取假数据
let rsArr = [];
for(let i = 0; i < 6; i++) {
rsArr.push({
title:keyword + (i+1),
other:i //文章id
});
}
return rsArr;
} }
}
</script>
<style scoped> .saerchDiv {
height: .75rem;
font-size: .27rem;
} </style>
组件的通信
vue组件的通信是vue组件的核心,组件不仅仅是要把模板的内容进行复用;更主要的是组件间要进行通信;组件之间的通信数据传递是组件的生命力之一。
props单向数据流,父组件向子组件传递数据
props可以是一个数据类型也可以是一个数组,也可以是对象,对象下的数据有3个属性type,default,require。其中default,require值都是布尔类型值。type有Number,String,Boolean,Array,Object,Function,Symbol。如果props数据是对象或数组时默认值default必须是一个函数来返回初始化数据。而且因为对象或数据是引用类型,指向的是同一个内存空间所以当props数据是这两个类型时,数据改变时子组件内改变是会影响父组件的。
props数据类型及相关样例
// props: ['propsDataA'],
props: {
propA: {
type: String,
default: "",
require: true
},
propB: {
type: Number,
default: 1,
require: false
},
propC: {
type: Array,
default: function() {
return [];
},
require: true
},
propD: {
type: Object,
default: function() {
return {};
},
require: true
},
propE: {
type: Function,
fn: function(val) { //一个时间未满两位数前面补零验证
return val > 9 ? val : '0' + val;
},
require: true
},
propF: {
type: Boolean,
default: false,
require: true
},
propG: [String, Number],
propH: Number
}
这里稍微改动一下局部组件的代码,父组件向子组件传递数据;
<div id="app">
{{msg}}
<!-- <const-comp></const-comp> -->
<local-comp :props-a="info"></local-comp>
</div>
<script> /*Vue.component('constComp', {
template: "<h3>我是全局组件</h3>" });*/
let localComp = {
template: "<div>我是局部组件<p>父组件传过来的数据为-->{{propsA}}</p></div>",
props: {
propsA: {
type: String,
default: "",
require: true
}
}
};
new Vue({
el: "#app",
data: {
msg: "hello component",
info: "hello props"
},
components: {
localComp
}
}); </script>
自定义事件$emit,子组件向父组件通信
这里还是在原来的基础上改,子组件使用$emit自定义一个send事件向父组件发送数据
<div id="app">
{{msg}}
<!-- <const-comp></const-comp> -->
<div>子组件数据为---->{{fromChildData}}</div>
<local-comp :props-a="info" @send="getChildData"></local-comp>
</div>
<script> /*Vue.component('constComp', {
template: "<h3>我是全局组件</h3>" });*/
let localComp = {
template: "<div>我是局部组件\
<p>父组件传过来的数据为-->{{propsA}}</p>\
<button @click='sendMsg'>使用$emit子组件向父组件传递事件</button>\
</div>",
props: {
propsA: {
type: String,
default: "",
require: true
}
},
data() {
return {
msg: "子组件数据"
}
},
methods: {
sendMsg(evt) {
this.$emit('send', this.msg);
}
}
};
new Vue({
el: "#app",
data: {
msg: "hello component",
info: "hello props",
fromChildData: ""
},
components: {
localComp
},
methods: {
getChildData(val) {
this.fromChildData = val
}
}
}); </script>
非子父组件通信,使用一个空的Vue实例作为一个事件总线监听数据变化
这种场景用于组件之间不为子父层级关系的时候相关通信,我们使用的那个空vue实例里也可以放vue的属性。用这个空的vue实例来$emit自定义一个事件然后再用这个实例来$on监听自定义事件,从而达到非子父组件之间的通信。(PS:这里暂时不讨论vuex),看demo代码。demo例子使用了ref组件索引。
<div id="app">
{{message}}
<component-a ref="a"></component-a>
<component-a ref="b"></component-a>
</div>
<script>
const bus = new Vue({}); Vue.component('component-a', {
data () {
return {
msg: 1
}
},
template: '<button @click="handleEvent">传递事件</button>',
methods: {
handleEvent () {
bus.$emit('on-message', '来自组件 com-a 的内容');
}
}
}); const app = new Vue({
el: '#app',
data: {
message: ''
},
mounted () {
bus.$on('on-message', (msg) => {
this.message = msg;
}); this.$children.msg = 2; }
})
</script>
slot组件内容分发
单个就默认slot,多个使用具名slot,$slots访问对应slot,vue2.0新增;因为vue2使用render函数来渲染,所以需要使用this.$slots来访问slot。this.$slots.xxx访问具体的slot,即slot中name指定的值 值类型{ [name: string]: ?Array<VNode> }
如果需要给slot添加默认内容的时候直接在slot上写就可以了,这个时候默认的slot内容所在的作用域就是其所在的组件实例,可以根据其所在的组件来控制slot默认的内容展示如:<slot>{{msg}}</slot>。如果没有指定默认数据的话slot内容根据其父组件所在的作用域。
当 vue 组件中当需要组件混合使用的时候需要用到内容分发,内容不确定的时候需要用到slot内容分发。
看demo代码;
<div id="app">
<com-out>
<div slot="b">{{msgB}}</div>
<div slot="a">{{msgA}}</div> </com-out>
</div>
<template id="co">
<div>
hello
<slot name="a"></slot>
<slot name="b"></slot>
</div>
</template>
<script>
Vue.component('com-out', {
template: "#co",
mounted() {
console.log("com-out slot" + this.$slots.a[0]);
}
});
new Vue({
el: "#app",
data: {
msgA: '父组件数据a',
msgB: '父组件数据b'
}
})
</script>
递归组件
递归组件要记住两点:
1.递归组件必须要给组件设置name。
2.要在一个合适的时间(条件)跳出递归否则会报栈溢出异常。
<div id="app">
<com :count="1"></com>
</div>
<template id="cr">
<div><com :count="count + 1" v-if="count < 3"></com>{{count}}</div>
</template>
<script>
Vue.component('com', {
name: 'comr',
template: "#cr",
props: {
count: {
type: Number,
default: 1
}
}
})
new Vue({
el: '#app'
}) </script>
动态组件
vue动态组件其实就是在组件中使用:is属性根据值来判断显示哪个组件。
<div id="app">
<button @click="changeCom">点击让子组件显示</button>
<com v-bind:is="activeCom"></com>
</div>
<script>
new Vue({
el: '#app',
data: {
activeCom: "comA"
},
methods: {
changeCom: function () {
let arr = ["comA", "comB", "comC"], index;
index = Math.ceil(Math.random()*arr.length);
this.activeCom = arr[index];
}
},
components: {
comA: {
template: "<div>组件comA</div>"
},
comB: {
template: "<div>组件comB</div>"
},
comC: {
template: "<div>组件comC</div>"
},
}
});
</script>
异步组件
异步组件在性能上有一定的优势,不仅加快了渲染时间也减少了不必要的加载;在路由中经常用到
看demo;
<div id="app">
<child-component></child-component> </div>
<script>
Vue.component('child-component', function (resolve, reject) {
window.setTimeout(function () {
resolve({
template: '<div>异步组件的内容</div>'
})
}, 2000)
});
new Vue({
el: '#app'
})
</script>
在路由中异步组件可以这样用:
{
path:"/路由地址",
name:"routeName",
component: resolve => require(["../components/xxx.vue"], resolve)
5 }
组件相关属性
$nextTick 虚拟dom完成后触发回调。进行dom操作。不过相关dom操作一般都建议放在指令中,或者自己自定义指令来进行操作,用合适的方式来做合适的事效果才能达到最优。
$ref当组件使用ref来作为索引时$ref获取当前组件
关于vue组件的一个小结的更多相关文章
- vue组件的一个总结
用vue进行开发到目前为止也有将近一年的时间了,在项目技术选型的时候隔壁组选 react的时候我们坚持使用vue作为前端的开发框架.虽然两者思想上的差异不大,但是vue的语法在代码的可读性以及后期的维 ...
- vue 组件发布记录
好久没做独立的 vue 组件了,最近突然想把一个常用的 vue 组件打成一个 npm 包,方便使用.好久不用,发现已经忘记环境怎么搭建.翻看以前的组件,才慢慢回想起来,中间还出现些错误.在这记录下开发 ...
- 来吧!一文彻底搞定Vue组件!
作者 | Jeskson 来源 | 达达前端小酒馆 Vue组件的概述 组件是什么呢,了解组件对象的分析,Vue组件中的data属性,props传递数据的原理到底是什么. 事件通信的那些事 如何了解父子 ...
- vue组件,撸第一个
实现此例您可以学到: vue-cli的基本应用 父组件如何向子组件传递值 单文件组件如何引入scss v-on和v-for的基础应用 源码下载 一.搭建vue开发环境 更换镜像到cnpmnpm ins ...
- 【vue系列之三】从一个vue-pdf-shower,说说vue组件和npm包
前言 从去年年初开始,自己便下决心要写一个vue系列的博客,但时至今日,才写系列的第三篇博客,想来甚是惭愧. 但是慢归慢,每一篇都要保证质量,以及要写出自己的心路历程,防止自己工作中填的坑再让读者走一 ...
- 写一个vue组件
写一个vue组件 我下面写的是以.vue结尾的单文件组件的写法,是基于webpack构建的项目.如果还不知道怎么用webpack构建一个vue的工程的,可以移步到vue-cli. 一个完整的vue组件 ...
- Vue父组件向子组件传递一个动态的值,子组件如何保持实时更新实时更新?
原文:https://blog.csdn.net/zhouweixue_vivi/article/details/78550738 2017年11月16日 14:22:50 zhouweixue_vi ...
- Laravel 项目中编写第一个 Vue 组件
和 CSS 框架一样,Laravel 不强制你使用什么 JavaScript 客户端框架,但是开箱对 Vue.js 提供了良好的支持,如果你更熟悉 React 的话,也可以将默认的脚手架代码替换成 R ...
- 使用Vue cli3搭建一个用Fetch Api的组件
系列参考 ,英文原文参考 我的git代码: https://github.com/chentianwei411/Typeahead 目标: 建立一个输入关键字得到相关列表的组件,用Vuejs2和Fet ...
随机推荐
- 快速排序(Quicksort)的Javascript实现
日本程序员norahiko,写了一个排序算法的动画演示,非常有趣. 这个周末,我就用它当做教材,好好学习了一下各种排序算法. 排序算法(Sorting algorithm)是计算机科学最古老.最基本的 ...
- PHP面向对象笔记解析
PHP的面向对象是很重要的内容,也是很常用的内容.所以现在就把PHP面向对象进行整理了一下. 顺带,我会在后面把我整理的一整套CSS3,PHP,MYSQL的开发的笔记打包放到百度云,有需要可以直接去百 ...
- [转] .NET领域驱动设计—初尝(疑问、模式、原则、工具、过程、框架、实践)
阅读目录: 1.1.疑问 1.1.1.UML何用 1.1.2.领域建模 1.2.模式 1.3.原则 1.5.过程 1.6.框架 1.7.项目演示 最近在研究DDD颇有收获,所以整理出来跟大家分享,共同 ...
- ecshop开发帮助
http://www.ecshop.com/template_tutorial/ ECSHOP模板结构说明 http://help.ecshop.com/index.php ECSHOP帮助中心 ht ...
- PHP中递归最详解释.
说到递归函数想必会有很多同学感到晕晕的,很难绕,容易绕错,那下面就让我来为大家详解一下. 首先,什么是递归函数呢? 1.所谓递归:指的是在函数内部,调用函数自身的操作.2.递归分两布:递(从最外层函数 ...
- HTML5+CSS3静态页面项目-PayPaul的总结
学习前端有一段时间了,一直在看书上的理论知识,而实战项目却很少.师兄常说,想要知道自己的实力有多少,知识掌握了多少,最好的方法就是去实践了,实践出真知嘛.于是决定在这个假期里,主要是通过项目的实践以及 ...
- Mybatis在oracle批量更新
最近公司业务中为了提高效率要做mybatis批量更新,但是到了oracle数据库中做了好几次都没成功,后来发现mybatis最后少了个分号,可能是Mybatis内部做了异常try catche 处 ...
- Vulkan Tutorial 23 Descriptor layout and buffer
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Introduction 我们现在可以将任意属性传递给每个顶点的顶点着色器使用.但是 ...
- ci框架中表前缀的处理
后面的写死,前面的无论如何改变都没事,会自动的替换,以后如果数据库的表前缀被修改了,只需要修改上面的配置项,下面的不变
- 0.搭建myeclipse开发环境
1.配置jdk 2.myeclipse集成tomcat 选择默认jdk