Vue-组件相关
vue组件相关组件为什么使用组件???定义组件定义全局组件定义局部组件调用组件内的属性,跟vue实例中的属性一样,但是有些是函数形式,有些是跟vue实例一样组件的参数组件的传参-父传子组件的传参-子传父组件插槽-slot具名插槽组件分离案例---todoList组件为什么使用组件???组件复用性强,可以更改几个参数等,就可以拿到其他地方用隔离(拆分),大型项目里,每个人只需要负责一部分,等定义组件
·
vue组件相关
组件
为什么使用组件???
- 组件复用性强,可以更改几个参数等,就可以拿到其他地方用
- 隔离(拆分),大型项目里,每个人只需要负责一部分,等
定义组件
定义全局组件
- 使用 实例化的Vue对象调用组件方法
component("组件名字" { template : 组件内容})
// 使用全局调用
Vue.component("Counter",{
template : `
<div>
<button>按钮</button>
</div>
`
})
定义局部组件
- 在Vue实例对象中使用
components
属性,components : { 组件名字 : { template : 组件内容}}
new Vue({
el : "#app",
data : {
},
components : {
// 注册
Counter : {
template : `
<div>
<button>按钮</button>
</div>
`
}
}
})
- 第二种方法 先声明 后注册
var Counters = {
template : `
<div>
<button>按钮</button>
</div>
`
}
new Vue({
el : "#app",
data : {
},
// 注册组件
components : { Counters },
})
调用
- 组件的调用不区分首字符大小写
<Counter></Counter>
<counter></counter>
<Counters></Counters>
<counters></counters>
- 组件的名字如果中间有大写字母调用时使用
-
来链接
<Counter-Item></Counter-Item>
<counter-item></counter-item>
组件内的属性,跟vue实例中的属性一样,但是有些是函数形式,有些是跟vue实例一样
- 组件中有,data(函数),methods,created(函数),props(值可以为数组,对象形式),template,等
组件的参数
- 在组件中自己定义data属性,但是值是函数
data : function() { return {}}
简写data() {return {}}
components : {
Counters : {
template : `
<div>
<button @click="num++">{{num}}</button>
</div>
`,
// 组件定义的参数
data : function() {
return {num : 1};
},
}
}
组件的传参-父传子
- 在组件中调用时传递父组件的参数,但是,子组件去接收并且更改这个传递过来的数组
- 传入使用
:传递数据的中间量的名字="父组件的数据"
- 接收时:使用
props : ["传递数据的中间量的名字"]
,这个宽泛 - 接收时也可用:
props : { "传递数据的中间量的名字" : {type : 数据类型,defalut : 默认值}}
,这个比较严谨- 子组件接收父组件的数据,如果直接更改父组件传递过来的数据时会报错,
- 因为:子组件很多,父组件的数据就一个,如果子组件都去改父组件的数据,会引发混乱
- 所以父组件的参数,传递是单向的,只读的,尽量避免直接修改父组件数据
- 为了解决这个问题,可以把传递过来的数据接,收到子组件自己的数据
data() {}
中 - 在生命周期函数最早能接收数据的阶段开始
created() {}
<div id="app">
<!-- 这里的count就是传递数据的中间量,item就是需要传输的数据 -->
<Counters v-for="(item,index) in list" :key="index" :count="item"></Counter>
</div>
var Counters = {
template : `
<div>
<!-- 这里就可以直接修改自己的数据了,不用因为直接修改父组件的数据而引发的错误混乱 -->
<button @click="num++">{{num}}</button>
</div>
`,
data : function() {
return {num : 1};
},
// 接收, 这种不是很严格
// props : ["count"],
// 接收,设置默认值
props : {
"count" : {type : Number,default : 0}
},
// 子组件接收父组件的数据,如果更改时会报错,
// 因为:子组件很多,父组件的数据就一个,如果子组件都去改父组件的数据,
// 会引发混乱
// 所以父组件的参数,传递是单向的,只读
// 为了解决这个问题,可以把传递过来的数据接收到子组件自己的数据中
// 在生命周期函数最早能接收数据的阶段开始created
created : function() {
// 在创建结束,挂载最早的阶段,把父组件的参数赋值给子组件自己的数据
this.num = this.count;
}
}
}
new Vue({
el : "#app",
data : {
},
// 注册组件
components : { Counters },
})
组件的传参-子传父
- 子组件想要将自己的数据传递给父组件使用:
this.$emit("传递数据的事件名",传递的数据);
- 在组件上定义传递数据的事件:
@传递数据的事件名="触发事件名($event)"
,$event
是子组件传递过来的数据 - 父组件接收时:
因为就是一个事件,所以就可以写在methods里面,写事件方法,把传递过来的数据,再赋值给父组件的数据内
<div id="app">
<!-- @numchange就是传递的事件名 ,numbers就是需要父组件去执行获取子组件传递的数据的方法 ,$event就是子组件传递的数据-->
<Step :min="20" :max="100" :count="5" @numchange="numbers($event)"></Step>
<Step></Step>
<!-- 这里获取父组件的数据显示子组件数据的变化 -->
<p v-if="numberss">{{numberss}}</p>
</div>
<!-- 目标:当组件的数据放生改变时候,通知父组件 -->
var Step = {
template : `
<div class="step">
<button :disabled="num <= min" @click="cal(-1)">-</button>
<input type="text" v-model="num" @input="check()">
<button :disabled="num >= max" @click="cal(+1)">+</button>
</div>
`,
data : function() {
return {num : 1};
},
props : {
"count" : {type : Number,default : 1},
"min" : {type : Number,default : 1},
"max" : {type : Number,default : 999},
"step" : {type : Number,default : 9},
},
created : function() {
this.num = this.count
},
methods : {
check() {
if(this.num <= this.min) {
this.num = this.min;
}
if(this.num >= this.max) {
this.num = this.max
}
// 子组件将更改的num数据,发送一个numchange事件,用于父组件接收
this.$emit("numchange",this.num);
// 子组件为了传递数据,发送一个numchange方法,将this.num数据,发送给父组件
},
cal(type) {
this.num += this.count*type;
this.check()
}
}
}
new Vue({
el : "#app",
// 定义父组件的数据numberss
data : {numberss : null},
methods : {
// 父组件执行触发的子组件的数据的额方法,e就是$event传递过来的数据
numbers(e) {
// 把子组件传递过来的数据赋值给父组件上的数据
this.numberss = e;
}
},
components : {Step},
})
组件插槽-slot
- 可以进行组件的嵌套
匿名插槽
<组件名> <任何标签>内容</任何标签></组件名>
,这个任何标签
中的内容因为有插槽的存在可以插入到了组件<slot></slot>
中<slot></slot>
再组件中放入一个这个标签,可以将组件,标签等插入打组件内部
<div id="app">
<h1>组件插槽</h1>
// parent是一个组件,
<Parent>
// p是 加的内容,可以插入组件内部
<p>我是组件里面的p</p>
// parent 还是刚刚的组件,发现组件内部嵌套组件
<Parent>
<Parent>
</Parent>
</Parent>
</Parent>
</div>
var Parent = {
template : `
<div class="parent">
<p>parent组件里的</p>
<slot></slot>
<!-- slot这个标签可以插入内容 -->
</div>
`,
}
new Vue({
el : "#app",
data : {},
components : {Parent}
})
具名插槽
- 将内容插入到对应名字的插槽中
<任何标签 slot="名字"></任何标签>
,需要传递的内容<slot name="名字"></slot>
,将对应的内容插入到与名字对应相等的地方
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
.model {
background-color: rgba(0,0,0,.3);
position: absolute;
z-index: 1000;
height: 100vh;
width: 100%;
left: 0;
right: 0;
top: 0;
display: flex;
align-items: center;
justify-content: center;
}
.model-content {
width: 400px;
height: 300px;
background-color: #fff;
display: flex;
flex-direction: column;
}
.model-title{
line-height: 44px;
background-color: #fafafa;
display: flex;
justify-content: space-between;
padding-left: 15px;
}
.close{ width: 44px; text-align: center; color:coral;}
.model-foot{ height: 44px; padding: 0 15px; text-align: right;}
.model-body{flex:1}
</style>
</head>
<body>
<div id="app">
<h1>具名插槽</h1>
<button @click="flag = true">弹出</button>
<Model :title="'你确定要离开吗'" :visible="flag" @close="flag=$event">
<div slot="foot">
<button @click="flag = false">取消</button>
<button @click="flag = false">确定</button>
</div>
</Model>
</div>
</body>
<script type="text/javascript">
var Model = {
template : `
<div class="model" v-if="visible">
<div class="model-content">
<div class="model-title">
<div class="title">{{title}}</div>
<div class="close" @click="$emit('close',false)">×</div>
</div>
<div class="model-body">内容</div>
<div class="model-foot" v-if="$slots.foot">
<slot name="foot"></slot>
</div>
<div class="model-foot" v-else>
<p @click="$emit('close',false)">确定</p>
</div>
</div>
</div>
`,
props : {
"title" : {type : String,default : ''},
"visible" : {type : Boolean,default : false}
}
}
new Vue({
el : "#app",
data : {
flag : false
},
components : {Model}
})
</script>
</html>
组件分离案例—todoList
- 数据在那个组件那个组件操作数据(尽量)
- 子组件传递数据,不操作数据
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<Inp @add="add($event)"></Inp>
<List :list="list" @del="del($event)"></List>
</div>
</body>
<script type="text/javascript">
var Item = {
template : `
<div>
<input type="checkbox" :checked="item.done">
{{item.title}}
<button @click="$emit('del',item)">删除</button>
</div>
`,
props : {
"item" : {type : Object,default : {}}
}
};
var List = {
template : `
<div>
<Item
v-for="(item,index) in list"
:item="item"
:key="index"
@del="$emit('del',$event)"
></Item>
</div>
`,
props : {
"list" : {type : Array,default : []},
},
components : {Item}
};
var Inp = {
template : `
<div>
<input type="text" v-model="temp" @keydown.enter="addHd()" />
</div>
`,
data : function() {
return {temp : ""}
},
methods : {
addHd() {
this.$emit("add",this.temp);
this.temp = '';
}
}
};
new Vue({
el : "#app",
data : {
list : [
{done : true,title : "吃饭"},
{done : true,title : "睡觉"},
{done : true,title : "打豆豆"}
]
},
components : {List,Inp},
methods : {
del(e) {
var index = this.list.indexOf(e);
this.list.splice(index,1);
},
add(val) {
this.list.unshift({
done : false,
title : val
})
}
}
})
</script>
</html>
更多推荐
已为社区贡献8条内容
所有评论(0)