如果上次安装vue-cli不小心安装了eslint,在build下方的webpack.base.conf.js中注释此段代码即可,有机会再写写如何格式化
然后顺带提下vue中的scoped
在APP.vue主组件随意写DOM并打开它的css可以看到是全局的css
<style scoped>
input{
color: red
}
</style>
加上scoped的话vue就会自己加个限制
这样css样式就隔开了,当然你不会如此丧心病狂取这种属性名来让它全局吧
属性(props)
Vue组件=Vue实例=new Vue(options)
一个个小UI模块(组件)构成一个大的结构,有点像oop面向编程思想
属性分为三类:
自定义属性props : 组件中props中声明的属性
原生属性attrs : 没有声明的属性,默认自动挂载到组件根元素上,设置inheritAttrs为false可以关闭自动挂载
特殊属性class、style : 挂载到组件根元素上,支持字符串、对象、数组等多种语法
昨天写demo的时候,在子组件中我在下方声明了props数组用来接收属性
props:['name','type','isVisible','types'],
从搬砖角度讲很舒服,从维护上面却不是,这个当然还是看自己老大怎么安排,如何设置props呢?
export default {
// props:['name','type','isVisible','types'],
props:{
name:String, //数据类型 也就是说name这个属性它必须是个字符串,
//如果是多个类型也可以
//name:[String,Number]
//如果设置多个,使用对象形式
type:{
//自定义验证值
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
},
list:{
type:Array,
//默认值,像对象数组 引用类型的值需要使用工厂函数获取,普通的类似Number直接丢值就行 比如default:10
default:()=>[]
// default:function(){
// return {vue:'hello'}
// }
},
isVisible:{
type:Boolean,
default:false //不写的话Vue默认也是false
},
}
}
通常常用的就是这些,再子组件上给他显示一下
<template>
<div>
name:{{name}}
<hr/>
type:{{type}}
<hr/>
list:{{list}}
<hr/>
isVisible:{{isVisible}}
</div>
</template>
接下来我把这个子组件引入到主组件中
此时页面中就能接收到数据了
可以看到我在标签内写入了几个属性,那么此时子组件中也是会存在这几个属性
这就是默认挂载上的,如果不想要,在子组件中设置 inheritAttrs:false,即可
此时加个函数进来,在属性中添加一个函数
传递一个onChange属性,是一个函数,函数很简单,改变一下type的值
methods:{
handleClick(value){
this.type=value
}
}
那么在子组件内,在props中需要声明一下属性
isVisible:{
type:Boolean,
default:false //不写的话Vue默认也是false
},
onChange:{
type:Function,
default:()=>{}
}
然后在下方的methods中声明
methods:{
handleClick(){
this.onChange(this.type ==='success'?'warning':'success')
}
}
此时打开页面会发现type在随之改变,这个效果先带过!那么这里要提一下Vue中的数据流是单向的,也就是如果在这个函数中直接这么写
methods:{
handleClick(){
this.type ==='success'?'warning':'success'
}
}
是会报错的,所以函数也是可以当成属性传递的
事件
事件分为两类
普通事件:@click @input @change @xxx等事件,通过this.$emit(‘xxx’,...)触发
修饰符事件 : @input.trim,@click.stop,@submit.prevent等,(可百度),一般用于原生HTML元素
简单写个demo
<template>
<div id="app">
<Event :name="name" @change="handleEventChange">
</Event>
</div>
</template>
<script>
import Event from './components/Event'
export default {
name: 'App',
data(){
return {
name:'Hello'
}
},
components:{
Event
},
methods:{
handleEventChange(value){
this.name=value
}
}
}
</script>
<style scoped>
</style>
首先是APP.vue的代码,代码很简单,就是在子组件中传递了一个name,并且绑定了一个@change事件
<template>
<div>
name:{{name||'--'}}
<br/>
<input :value="name" @input="handleChange"/>
<br/>
<br/>
<div @click="handleDivClick">
<button @click="handleClick">重置成功</button>
<button @click.stop="handleClick">重置失败</button>
</div>
</div>
</template>
<script>
export default {
props:['name'],
methods:{
handleChange(e){
this.$emit('change',e.target.value)
},
handleDivClick(){
this.$emit('change',"")
},
handleClick(e){
//都会失败
//e.stopPropagation
}
}
}
</script>
<style>
</style>
那么在子组件中,我们通过$emit的形式,将子组件的数据返回给父组件然后传递回来,有萌新可能觉得给父组件加个v-model绑定name,这样是不对的,相当于子组件改变了父组件的数据了,子组件仅仅是接收而已
(放在这里容易再次理解)
普通事件:@click @input @change @xxx等事件,通过this.$emit(‘xxx’,...)触发
这里有个stop修饰符,这是一个阻止冒泡的作用,当然也可以在下面的e.stopPropagation 注释打开,效果相同,
那么此时@click.stop阻止冒泡之后就无法点击到父元素从而触发handleDivClick函数了
从网上找了一些修饰符的效果:
.stop - 调用 event.stopPropagation()。
.prevent - 调用 event.preventDefault()。
.capture - 添加事件侦听器时使用 capture 模式。
.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
.native - 监听组件根元素的原生事件。
.once - 只触发一次回调。
.left - (2.2.0) 只当点击鼠标左键时触发。
.right - (2.2.0) 只当点击鼠标右键时触发。
.middle - (2.2.0) 只当点击鼠标中键时触发。
.passive - (2.3.0) 以 { passive: true } 模式添加侦听器
不懂的可以百度一下
之前自己写过一篇组件通信的例子,有兴趣可以看看
https://www.jianshu.com/p/b31a53b93ce9 (可能后续会重新写一篇)
插槽
先看个demo
很空白的一段内容,然后在主组件中引入
OK 此时没得任何问题
页面也是还OK,此时我更改一下主组件
<Slots>
!超会说
</Slots>
但是页面并没有发生变化
此时加个插槽,效果就出来了
到现在,我们知道了什么是插槽:
插槽就是Vue实现的一套内容分发的API,将<slot></slot>元素作为承载分发内容的出口。
具名插槽
<template>
<div id="app">
<Slots>
<template slot="girl">
18,身材好,漂亮
</template>
<template slot="boy">
帅气、色胚
</template>
</Slots>
</div>
</template>
之前也接触过了,只要在子组件中申明name即可
<slot name="girl"></slot>
就是只显示girl 内容
<Slots>
<template slot="girl">
18,身材好,漂亮
</template>
<template slot="boy">
帅气、色胚
</template>
<div>
我是一类人,
是的 我就是舔狗
</div>
</Slots>
如果子组件slot并没有name就会显示其他非具名内容
作用域插槽slot-scope(其实自己也不是很明白)
我的理解就是在组件上的属性,可以在组件元素内使用!
<template>
<div>
<slot say="你好"></slot>
</div>
</template>
此时我在子组件中声明一个属性,当然可以绑定data中的内容,偷个懒
<Slots>
<template slot-scope="a">
<!-- {"say":"你好"} -->
{{a}}
</template>
</Slots>
在父组件中即可接收到a的值 就是一个对象
这时候我给他传一个数组过去
在子组件中接收,并且循环一哈
注意当前显示的仅仅是a啊,这种时候可以做什么事情呢?比如说
<Slots :lists="nameList">
<template slot-scope="a">
<Div v-if="a.obj.id==1">
你好: {{a.obj.name}}
</Div>
<div v-else>
{{a.obj.name}}
</div>
</template>
</Slots>
好啦,因为自己也不是很懂就不误人子弟了
网友评论