【day 06】vue的组件
组件
组件就是把一个网页分割成独立的小的模块,然后通过把模块进行组合,构建成一个大型的应用
单文件组件 只有一个组件 html css js 都在这个文件内
非单文件组件 可有多个组件
全局注册
!! 得先注册子组件 再生成 vm实例对象
创建子组件
const child = Vue.extend({//除了 el 其他任意配置项都可以用 name: 'child',data() {return {msg: 123}},// 写组件的html内容 template: `<h1>我是child子组件</h1>`})//全局注册子组件 自定义组件名 组件对象 Vue.component('child', child)const vm = new Vue({name: 'app',el: '#app',data() {return {}}})
语法糖的写法 省略 Vue.extend() 在使用 child组件时 内部会自己调用
const child = {name: 'child',data() {return {msg: 123}},// 写组件的html内容 template: `<h1>我是child子组件</h1>`}Vue.component('child', child)
view model vm new Vue() 产生的 老大哥 管理一切 小弟 子组件实例对象 简称 vc
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style></style>
</head>
<body><div id="app"><child></child><child></child><child></child></div><script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script><script>// 得先注册子组件 再生成vm实例对象// 创建子组件const child = Vue.extend({// 除了el其他任意配置项都可以用name:'child',data(){return{msg:123}},//写组件的html内容template:`<h1>我是child子组件</h1>`})// 全局注册子组件 自定义组件名 组件对象Vue.component('child',child)const vm = new Vue({el:"#app",data(){return{bool:true,}},methods: {}})console.log(vm)</script>
</body>
</html>
注意:子组件内 data 只能是函数 不能是对象的写法
全局注册组件 任意的组件内都可以使用此组件
我们期望 组件直供 某一个组件使用 需要使用局部注册
new Vue({el:"#box",data(){return{}},methods: {},components:{child}})
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style></style>
</head>
<body><div id="app"><child></child></div><div id="box"><p>我现在是在box下</p><child></child></div><script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script><script>const child = Vue.extend({name:'Child'data(){return{}},methods:{},template:`<h1>我是儿子组件<h1>`})// Vue.component('child',child) 关闭全局注册new Vue({el:"#app",data(){return{bool:true,}},methods: {}})new Vue({el:"#box",data(){return{}},methods: {},components:{child}})</script>
</body>
</html>
最好是配置上name属性 name写的是啥 浏览器工具内 组件的位置就显示啥 最好是 组件名 保持一致 首字母大写
name:'child'
自定义标签名命名
- 不能跟已有的标签发生冲突
- 子组件命名 使用时 写成
vue2 非单文件组件为:
components:{
childDemo:child
}
会被转为 小写识别 就会报错 childdemo
我们需要更换成 这种写法
模板的规定
vue2内
template内 只能接收一个根元素template:
`
//这样子写会报错
我是儿子组件
我是儿子组件/
`需要改成
template:
<div> <h2>我是儿子组件</h2> <h2>我是儿子组件</h2> </div>
vue3内不存在这个问题 可以接收多个根元素
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style></style>
</head>
<body><div id="app"><!-- <child></child> --></div><div id="box"><p>我现在是在box下</p><child-demo></child-demo></div><script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script><script>const child = Vue.extend({name:'child',data(){return{}},methods:{},template:` <div><h2>我是儿子组件</h2><h2>我是儿子组件</h2> </div> `})// Vue.component('child',child) 关闭全局注册new Vue({el:"#app",data(){return{bool:true,}},methods: {}})new Vue({el:"#box",data(){return{}},methods: {},components:{childDemo:child}})</script>
</body>
</html>
组件的嵌套
全局注册
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style></style>
</head>
<body><div id="app"><child></child></div><script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script><script>const moLeft = {name:'MoLeft',template:`<h2 style='float:left;background:red;'>我是左边的组件</h2>`}const child = Vue.extend({name:'child',data(){return{}},methods:{},template:` <div><h1>我是儿子组件</h1><mo-left> </mo-left></div> `})Vue.component('child',child) Vue.component('moLeft',moLeft) new Vue({el:"#app",data(){return{}},methods: {},components:{childDemo:child}})</script>
</body>
</html>
局部注册
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style></style>
</head>
<body><div id="app"><child></child></div><script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script><script>const moLeft = {name:'MoLeft',template:`<h2 style='float:left;background:red;'>我是左边的组件</h2>`}const child = Vue.extend({name:'child',data(){return{}},methods:{},template:` <div><h1>我是儿子组件</h1><mo-left> </mo-left></div> `,components:{moLeft}})Vue.component('child',child) // Vue.component('moLeft',moLeft) new Vue({el:"#app",data(){return{}},methods: {},components:{childDemo:child}})</script>
</body>
</html>
分析:
new Vue 产生的是 vm实例对象
Vue.extend() 返回的是 f VueComponent(options) //构造函数
{
this.inint(options)
}
VueComponent 构造函数 组件使用的时候 内部会执行 产出 vc实例对象 (被vm管理的小弟)
vc和vm两个人 配置差不多完全一致
子组件内 this 指向 自己的vc实例对象
单文件组件
<template><div class="father">我是父组件</div>
</template><script>
export default{name:"Father",data(){return{};},
};
// export default{} 默认暴露 引用时 import ??? from '????'// 分别暴露
// export const obj = {};引用时 import {obj} from '?????'
// 等价于暴露出去了
// {
// obj
// }// 统一暴露
// let obj = {}
// let obj1 = {}
// import {obj,obj1} from '?????'</script>
<style lang="sass" scoped></style>
脚手架
Vue官方提供的标准化开发工具(开发平台)
可以把vue文件及相关的ess编译为可执行的html css js
安装
npm i -g @vue/cli 进行安装