VUE

vue.js入门(三,vue核心概念,属性,事件,插槽)

2019-10-09  本文已影响0人  感觉不错哦

如果上次安装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>

好啦,因为自己也不是很懂就不误人子弟了

上一篇下一篇

猜你喜欢

热点阅读