前言
前端web开发最流行的工具库之一,但之前有过学习之后。一直没有怎么使用,很多东西已经忘记,这里对之前学过一点内容做一下回顾,也可当做入门小案例。上一篇文章主要介绍vue一些常用事件、生命周期的介绍,这一篇主要围绕组件来进行介绍。
案例
一、全局组件
全局组件申明之后,就可以直接使用,无需在components中引入组件内容。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<title-bar></title-bar>
<div>{{content}}</div>
<page-footer></page-footer>
</div>
</body>
<script>
Vue.component("title-bar",{
template:"<div>{{msg}}</div>",
data(){
return{
msg:"title 模板标题"
}
}
})
Vue.component("page-footer",{
template:"<div>底部内容</div>"
})
let vm=new Vue({
el:"#app",
data:{
content:"内容"
}
})
</script>
</html>
二、局部组件
局部组件的好处 就是当你使用的是webpack这样的构建系统时,如果是用全局注册的这种方法注册的组件,那么当你不使用某一个组件的时候,它仍然会存在最终的构建结果之中,这就增加的无谓的js下载。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<title-bar></title-bar>
<div>中间展示内容</div>
<page-footer></page-footer>
</div>
</body>
<script>
let titleBar = {
name: "title-bar",
template:"<div>title组件</div>"
}
let pageFooter={
name:"page-footer",
template:"<div>页脚组件</div>"
}
let vm=new Vue({
el:"#app",
components:{
titleBar:titleBar,
pageFooter:pageFooter
}
})
</script>
</html>
三、父子组件通信
父传子: 子组件定义props接收
子传父: 子组件需要对外使用
e
m
i
t
发
布
事
件
,
父
组
件
需
要
去
监
听
emit发布事件, 父组件需要去监听
emit发布事件,父组件需要去监听emit发布的事件, 注意:事件名称使用小写
父组件传递过来的数据,子组件不能直接修改,如果想修改,发布事件让父组件去修改
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--@childclick 监听子组件$emit发布的事件-->
<title-bar :mytitle="title" @childclick="handleOnClick"></title-bar>
<div>中间展示内容</div>
<menu-bar></menu-bar>
</div>
</body>
<script>
let titleBar = {
name: "title-bar",
//父传子: 子组件定义props接收
props: ["mytitle"],
template: "<div>{{newTitle}}--<button @click='handleChildClick'>返回</button></div>",
data() {
return {
msg: "来自子组件的问候",
newTitle: this.mytitle
}
},
methods: {
handleChildClick() {
this.newTitle = "变更标题",
//子传父: 子组件需要对外使用$emit发布事件, 父组件需要去监听$emit发布的事件, 注意:事件名称使用小写
this.$emit('childclick', this.msg)
}
}
}
let menuBar = {
name: "menu-bar",
template: "<div>页码</div>"
}
let vm = new Vue({
el: "#app",
components: {
titleBar,
menuBar
},
data: {
title: "父组件的问候",
},
methods: {
handleOnClick(msg) {
alert(msg)
}
}
})
</script>
</html>
四、原生事件和使用子组件自定义事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<title>Document</title>
</head>
<style>
.cl {
background-color: blue;
}
</style>
<body>
<div id="app">
<!--使用子组件定义的@myclic事件-->
<child-bar @myclick="handleFatherClick"></child-bar>
<!--由于title-bar 中没有定义@myclick 并不生效-->
<title-bar @myclick="handleFatherClick"></title-bar>
<!--使用@click.native原生方法-->
<child-second-bar @click.native="handleFatherClick"></child-second-bar>
</div>
</body>
<script>
let titleBar = {
name: "title-bar",
template: "<div>title组件</div>"
}
//@click使用中原生的标签 , 组件不能直接使用@click ,在子组件上使用原生的事件需要使用事件修饰符 .native
// 组件上面写的这些事件其实都是用户自定义事件,需要子组件调用$emit('click')
let childBar = {
name: "child-bar",
template: "<div @click='handleChildClick'>第一个title</div>",
methods: {
handleChildClick() {
this.$emit("myclick")
}
}
}
let childSecondBar = {
name: "child-second-bar",
template: "<div>第二个title</div>"
}
let vm = new Vue({
el: "#app",
data: {
isActive: false
},
components:{
childBar,
childSecondBar,
titleBar
},
methods:{
handleFatherClick(){
alert("来自自定义事件")
}
}
})
</script>
</html>
五、插槽
插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<title>Document</title>
</head>
<body>
<div id="app">
<!--组件插槽-->
<child :content="content"></child>
<!--具名插槽-->
<name-slot>
<div slot="head"><h1>标题头</h1></div>
<div slot="foot">设置尾页</div>
</name-slot>
</div>
</body>
<script>
//组件插槽
let child = {
name: "child",
props: ['content'],
template: '<div>' +
'<div>标题部分</div>' +
'<div>{{content}}</div>' +
'<div>尾页部分</div>'
+ '</div>'
}
//具名插槽
let nameSlot = {
name: "name-slot",
template: "<div>" +
"<slot name='head'></slot>" +
"<div>中间内容</div>" +
"<slot name='foot'>底部默认内容</slot>" +
"</div>"
}
let vm = new Vue({
el: "#app",
data: {
content: "<h1>中间内容</h1>"
},
components: {
child,
nameSlot
}
})
</script>
</html>
六、动态组件
我们可以根据值的变更,直接更改组件的内容。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div>标题栏</div>
<component :is="currentTemplate"></component>
<button @click="handleClick('home')">主页内容</button>
<button @click="handleClick('user')">用户内容</button>
</div>
</body>
<script>
Vue.component('home', {
template: '<div>主页内容</div>'
})
Vue.component('user', {
template: '<div>用户内容</div>'
})
let vm = new Vue({
el: "#app",
data: {
currentTemplate: "home"
},
methods: {
handleClick(template) {
this.currentTemplate = template
}
}
})
</script>
</html>
结尾
学习vue都就离不开,脚手架的创建,两样会在接下来一篇中做一个小展示。这个系列更多是一些粗浅的展示,如果需要更加深入可以把这个当做一个框架做更深一步的学习。