目录
- 一、组件
- 二、组件的分类
- (一)全局组件
- (二)局部组件
- 1、为什么vue组件 data函数返回一个对象
- 2、bootstrap的使用
- 三、父组件传值给子组件
- 1、父传子实现进度条
- 2、 props的属性
- 四、子组件传值给父组件
- 五、兄弟组件传值
一、组件
可以复用的页面的一部分
学习的前提是导入文件
链接:https://pan.baidu.com/s/1nJyLYYKt4c4QLfeuQrUGOg 提取码:1115
<script src="../../vue.global.js"> </script>
二、组件的分类
- 一个 Vue 组件在使用前需要
先被“注册”
,这样 Vue 才能在渲染模板
时找到其对应的实现。组件注册有两种方式:全局注册和局部注册
(一)全局组件
- 使用 Vue 应用实例的
app.component()
方法,让组件在当前 Vue 应用中全局可用- 定义一个
全局组件
,组件必须提供模板(component)
,提供组件的内容
template
的优先级比mount
挂载元素高
(二)局部组件
- 定义一个局部注册的组件, 必须提供
模板内容
- 必须
注册组件
console.log(Vue);
1、为什么vue组件 data函数返回一个对象
- 每个实例可以拥有一个
独立数据对象
,在其中一个实例上数据改变了,其他实例数据不收影响
<div id="box">
<Counter></Counter>
<Counter></Counter>
<Counter></Counter>
<Counter></Counter>
</div>
<script>
console.log(Vue);
let obj = {
n: 1
}
let Counter = {
template: `<div>计数器 {{n}} <button @click="add">+</button></div>`,
data() {
return {
n: 1 //计数器的初始值
}
},
methods: {
add() { //点击计数器每次加 1
this.n++;
}
}
}
Vue.createApp({
components: {
Counter
},
data() {
return {
}
},
}).mount("#box")
</script>
2、bootstrap的使用
官网:https://www.bootcss.com/
- 进度条的实现
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css">
<div id="box">
<Custom-progress></Custom-progress>
<Custom-progress></Custom-progress>
<Custom-progress></Custom-progress>
<Custom-progress></Custom-progress>
</div>
<script>
let CustomProgress={ //定义一个进度条组件(局部)
template:`<div class="progress">
<div class="progress-bar" style="width:30%">30%</div>
</div>`
}
Vue.createApp({
components:{
CustomProgress
},
data() {
return {
}
},
}).mount("#box")
</script>
三、父组件传值给子组件
- 父组件是通过
自定义属性
把值传给子组件- 传值的时候, 如果
不绑定
传过去的都是字符串
,绑定
了可以识别各种类型和变量
- 子组件通过
props属性
进行接收- 父组件传给子组件的值
不能改
<div id="box">
<!-- 父组件是通过自定义属性把值传给子组件 -->
<!-- 传值的时候 如果不绑定传过去的都是字符串,绑定了可以识别各种类型和变量 -->
<Child v-bind:n="666" :v="v" :arr="arr" :obj="obj"></Child>
</div>
<script>
//父组件传值给子组件
let Child = {
//子组件通过props属性进行接收
//props:["n","v"], 方法一
// 方法二
props: {
n: {
type: Number
},
v: String,
arr: Array,
obj: Object
},
//父组件传给子组件的值不能改
template: `
<div>
{{n}} {{typeof n}} <br>
{{v}} <br>
{{arr}}<button @click="arr[0]=123">change</button> <br>
{{obj}}<button @click="obj.a=1111">change</button> <br>
</div>`
}
Vue.createApp({
components: {
Child
},
data() {
return {
v: 'hello',
arr: [1, 2, 3],
obj: { a: 1, b: 2, c: 3 }
}
},
}).mount("#box")
</script>
1、父传子实现进度条
<style>
.progress {
margin: 30px;
}
</style>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css">
<div id="box">
<Custom-progress v-for="value in obj" :n="value">
</Custom-progress>
</div>
<script>
//定义一个进度条组件(局部)
let CustomProgress = {
//接收父组件传过来的进度
props: ["n"],
template: `
<div class="progress">
<div class="progress-bar" :style="{width:n+'%'}" >{{n}}%</div>
</div>`
}
Vue.createApp({
components: {
CustomProgress
},
data() {
return {
obj: {
one: 50, //进度条的进度
two: 40,
three: 80,
four: 20
}
}
},
}).mount("#box")
</script>
2、 props的属性
type:Number
(类型)required:true
(必须传递这个参数)default:100
(默认值)validator(value){ return value>=0 && value<=750 }
(自定义验证规则)
四、子组件传值给父组件
1.
监听
2.触发事件,发送数据
3.接收
, 就是子组件传过来的值
<div id="box">
<!-- 子组件把值传给父组件 1.监听 -->
<Child :n="n" @msg="receive($event)"></Child>
</div>
<script>
let Child = {
props: ["n"],
template: `<div>child component {{n}} <button @click="change">+</button></div>`,
methods: {
change() {
// this.n++; //error 因为父组件传过来的值不能改
// 思路:把接受过来的值+1 传给父组件,在父组件把值改掉,子组件的值自动就更新了
//n++ n+1
//2.触发事件 发送数据
this.$emit("msg", this.n + 1) //子组件把值传给父组件
}
}
}
Vue.createApp({
components: {
Child
},
data() {
return {
n: 666
}
},
methods: {
receive(e) { //e 3.接收 就是子组件传过来的值
console.log(e);
this.n=e;
}
}
}).mount("#box")
</script>
- 子传父实现todolist添加功能
<div id="box">
<Txt @msg="add"></Txt>
<List :arr="arr"></List>
</div>
let Txt = {
template: `<input type='text' v-model="str" @keyup.enter="send" />`,
data() {
return {
str: ''
}
},
methods: {
send() {
//把值发给父组件
this.$emit("msg", this.str);
//清空文本框
this.str = ""
}
}
}
let List = {
props: ["arr"],
template: `<div>
<ul>
<li v-for="(item,index) in arr" :key="index">
{{item}}
</li>
</ul>
</div>`
}
Vue.createApp({
components: {
Txt, List
},
data() {
return {
arr: ["aa", "bb", "cc"]
}
},
methods: {
add(e) { //e 就是子组件文本框的数据
this.arr.push(e);
}
}
}).mount("#box")
</script>
五、兄弟组件传值
mitt
实现兄弟组件传值- 官网:https://www.npmjs.com/package/mitt
<script src="https://unpkg.com/mitt/dist/mitt.umd.js"></script>
<div id="box">
<Child :n="n"></Child>
<Com2></Com2>
</div>
<script>
//mitt 实现兄弟组件传值
let emitter = mitt();
console.log(emitter);
let Com2 = {
template: `<div>com2 {{str}}</div>`,
//这个函数会自动调用 实例完成所有状态相关的处理之后会自动调用
created() {
//接受兄弟传过来的值
emitter.on("msg", (e) => {
console.log(e)
this.str = e;
})
},
data() {
return {
str: ''
}
}
}
let Child = {
props: {
n: {
type: Number, //类型
validator(value) { //自定义验证规则
return value >= 0 && value <= 750
}
}
},
template: `
<div>hello child {{n}}
button @click="send">发送abc到com2</button>
</div>`,
methods: {
send() {
emitter.emit("msg", "abc")
}
}
}
Vue.createApp({
components: {
Child, Com2
},
data() {
return {
n: 666
}
},
}).mount("#box")
</script>