组件 #
组件就是实现应用局部功能的代码和资源的集合
声明并注册Vue组件的三种方式 #
组件必须在vue实例管理的元素范围内使用,是用Vue.extend可以构造出来一个VueComponent实例
组件中,Data必须是一个函数data(),返回一个对象,对象内部保存数据,避免多个组件实例之间的data互相干扰
1、先用Vue.extend声明组件构造,再将模板注册为全局组件 #
<div id="d1">
<!-- 4、使用组件 -->
<com1></com1>
</div>
<script>
//1、声明组件
let temp = Vue.extend({
//在es6中,可以使用fj'yn``来定义字符串,这个字符串可以换行,不需要拼接
template:`
<form>
uname:<input />
upwd:<input />
<button>add</button>
</form>
`,
data(){
return{}
},
name:"temp"
});
//2、注册为全局组件Vue.xomponent("组件名",组件对象)
Vue.component("com1",temp);
//3、挂载元素
let v = new Vue({
el:"#d1"
})
</script>
2、直接将模板注册为全局组件 #
<div id="d1">
<!-- 3、使用组件 -->
<com1></com1>
</div>
<script>
//1、声明并注册为全局组件,Vue会自动调用extenddv进行构造
Vue.component("com1",{
temlate:`
<form>
uname:<input />
upwd:<input />
<button>add</button>
</form>
`
});
//2、挂载元素
let v = new Vue({
el:"#d1"
})
</script>
3、在html、vue代码中使用<template>标签编写模板,然后注册组件(组件模板分离,推荐)
#
<template>标签中,只可以有一个根标签,不然除了第一个根标签中内容,其他的不会显示
<template>标签也可以使用<script type="text/x-template"></script>替代
<div id="d1">
<!-- 4、使用组件 -->
<com1></com1>
</div>
<!-- 1、编写模板 -->
<template id="temp">
<form>
uname:<input />
upwd:<input />
<button>add</button>
</form>
</template>
<script>
//2、注册为全局组件
Vue.component("com1",{
temlate:"#temp"
});
//3、挂载元素
let v = new Vue({
el:"#d1"
})
</script>
全局组件和局部组件的区别 #
- 全局组件
- 声明方式:
Vue.component("组件名",组件对象) - 作用范围:所有Vue实例管理的元素
- 声明方式:
- 局部组件(子组件)
- 声明方式:在Vue实例中,使用
components属性注册组件{组件名,组件对象} - 作用范围:当前Vue实例管理的元素中
- 声明方式:在Vue实例中,使用
重要内置关系 #
//VueComponent显示原型属性的隐式原型属性等于Vue的显示原型属性
VueComponent.prototype.__proto__ === Vue.prototype
这个关系的作用:让所有组件实例对象可以访问到Vue原型上的属性、方法
单文件组件 #
- 单文件组件:文件名以
.vue结尾,一个文件中只声明一个组件(主要使用方式)- 起始就是将组件声明时
extend()函数的参数部分(组件配置)抽离出来,与模板和样式单独作为一个文件
- 起始就是将组件声明时
- 非单文件组件:普通的html文件,一个文件中声明多个组件,不好维护
<!-- 组件的模板 -->
<template>
</template>
<!-- 组件的js部分 -->
<script>
export default {
name: "App",
components: {
},
data() {
return {
};
},
}
</script>
<!-- 组件的样式部分 -->
<style>
</style>
style #
1、lang属性 #
css:默认可以解析原生css
less:脚手架需要安装less-loader
2、scoped属性 #
在多个组件中声明的style标签中的样式,最终会汇集到一起,这就导致了,如果样式中出现了同名的id、class,会发生冲突,为了解决这个问题,就需要使用scoped,这个属性不适合用与App组件
<!-- 在style标签上添加scoped属性即可 -->
<style scoped></style>
组件化编码流程 #
1、实现静态组件、抽取组件,使用组件实现静态页面效果
2、实现动态组件、并且考虑数据存放位置,操作数据的方法优先和数据放在一起
3、实现交互功能
组件的切换 #
可以使用标签<component>作为组件的载体,使用:is="componentName"设置搭载的组件
<div id="div1">
<button @click="comName='com1'">temp1</button>
<button @click="comName='com2'">temp2</button>
<component :is="comName"></component>
</div>
<template id="temp1">
<h1>This is temp1</h1>
</template>
<template id="temp2">
<h1>This is temp2</h1>
</template>
<script>
Vue.component("com1",{
template:"#temp1"
})
Vue.component("com2",{
template:"#temp2"
})
let v = new Vue({
el:"#div1",
data:{
comName:"com1"
}
})
</script>
mixin混入 #
对于多个组件公用的配置项,可以抽离出来,声明一个独立的js文件
如果混合中声明了data、methods,那么会将混合中声明的和组件声明的混合一起,全部生效;如果混合中声明了mounted等钩子,那么会都执行
export default {
//钩子函数,用于打印组件加载情况
mounted () {
console.log("组件",this.$options.name,"加载完成")
}
}
在组件中进行局部引入,并且使用
//引入
import m from '../mixin/mixin'
export default {
name: "Login",
//使用
mixins:[m]
}
也可以在main.js中进行全局引入混合
//引入
import m from '../mixin/mixin'
//声明全局混合,所有组件都会生效,可以声明多个Vue.mixin()
Vue.mixin(m);
插件 #
vue支持自定义插件,并且在main.js中,可以使用Vue.use(plugin)进行开启
定义插件(本质就是一个对象中,包含一个install函数,该函数接收Vue构造函数作为参数):
export default {
install(Vue){
//定义全局过滤器
Vue.filter("priceFormat",function(value){
return value + "元";
})
//定义全局指令
Vue.directive("log",function(element,binding){
console.log("自定义指令");
console.log(element);
console.log(binding);
})
//在Vue原型上添加函数,所有组件实例都可调用
Vue.prototype.hello = function(){
console.log("hello")
}
}
}
在main.js中引入插件js,并且进行开启
//引入插件
import p from './plugin.js';
//开启插件,可以开启多个
Vue.use(p);