使用组件的细节点

  1. is属性: 有些html标签如table,ul,ol,select对哪些标签可以出现在其内部是有着严格的要求的。 因此当这些标签内部出现了自定义组件,有可能会被作为无效的内容提升到外部,导致页面渲染出错。 而是用is属性则可以解决这个问题,在子级标签中用is属性来使用自定义组件。

  2. 子组件中的data必须是一个函数,并且返回一个对象,当一个组件被多次使用的时候,组件间的数据不会相互影响。

    Vue.component('row', {    data:function () {          return{              content:'this is row'          }    },    template:"{{content}}"})

  3. 通过ref 获取dom节点

    hello world

    handdle:function(){    console.log(this.$refs.hello)}

父子组件传值

  1. 父组件向子组件传值

父组件通过属性绑定将值绑定到子组件上,子组件通过 props 属性来接收,然后子组件就可以使用父组件中传递过来的数据了。props是一个数组。

  1. 子组件向父组件传值:
  • 子组件通过this.$emit()方法向父组件传值;

  • $emit("事件名",args)第一个参数是自定义事件名,第二个参数是需要传递的数据

  • 父组件使用v-on监听子组件

  1. 单向数据流

父组件可以随意向子组件传递参数,子组件不可以改变父组件的数据,否则会报警告。 解决办法:要想改变父组件的参数,在子组件的data属性中拷贝一份父组件的数据,然后可以对数据进行操作。

<div id="app">    <counter :count="1" @change="handleAdd"></counter>    <counter :count="2" @change="handleAdd"></counter>    <div>{{total}}</div></div><script>    var counter = {        props:['count'],        data:function(){          return{              number:this.count          }        },        template:'<div @click="handdle">{{number}}</div>',        methods:{            handdle:function(){                this.number++;                this.$emit('change',1)            }        }    }    var app = new Vue({        el:'#app',        data:{          total:3        },        components:{            counter:counter        },        methods: {            handleAdd:function(step){                this.total+=step            }        }    })</script>复制代码

组件参数校验与非props特性

  1. 简单校验:限定传入的值的类型,可以是单个类型,也可以是一个数组。

    props:{  content: [String,Number]}

  2. 复杂校验:

    props:{ content:{  type: String,//数据类型  required: false,//是否是必传  default: 'default content',//如果没传值,默认值  validator: function(val){//自定义校验器,数据必须>5    return (val.length>5)  } }}

给组件绑定原生事件

  1. 在父组件上绑定事件(如:@click.native="handleClick")

  2. 在vue实例中的methods下定义事件函数。

    <child @click.native="handleClick" >

传统方法绑定事件:

  1. 在子组件上绑定事件

  2. 在子组件中的methods中设置相应的事件函数,并在函数中定义自定义事件函数,将自定义事件函数传给父组件(如 this.$emit('click'))

  3. 在父组件上绑定子组件methods函数中传来的自定义函数

  4. 在父组件methods中设置对应的事件函数

非父子组件间的传值

  1. vuex,

  2. 发布订阅模式(总线模式)

  • 给 Vue 类加上原型属性 bus, 这样每个 Vue 实例都能访问到原型属性 bus

    Vue.prototype.bus = new Vue()

  • 利用 bus 的实例方法 $emit 触发事件

    this.bus.$emit('触发事件', this.selfContent)

  • 再利用生命周期方法(钩子) mounted 给 bus 绑定监听函数, 在事件触发时执行

    this.bus.$on('eventName', cellback)

  • 建议使用箭头函数做为回调函数,不会影响回调函数中this的指向问题

    this.bus.$on('eventName',(msg) => {     this.selfContent = mag; })

完整代码

<div id="app">    <child  content="Dell"></child>    <child  content="Lee"></child></div><script> Vue.prototype.bus = new Vue()    Vue.component('child',{        data:function(){          return{              selfContent:this.content          }        },        props:{            content:{                type:String,            }        },        template:'<div @click="handClick">{{selfContent}}</div>',        methods: {            handClick:function () {                this.bus.$emit('change',this.selfContent)            }        },        mounted:function(){            var that = this;           this.bus.$on('change',function(msg){             that.selfContent = msg           })        }    })    var app = new Vue({        el:'#app',    })</script>复制代码

vue中使用插槽

  1. 插槽:可以使父组件很容易向子组件传递DOM元素

  2. 匿名插槽:父组件内部的DOM元素,可以通过子组件的标签渲染,slot标签中可以写默认的内容,如果父组件中不传递就显示默认内容

    Vue.component('child',{        template:'

    ' +            '默认内容' +            '

    ',    })


  3. 具名插槽:有名字的插槽,父组件中为slot属性设置值,子组件slot中使用name属性接收父组件slot的属性值可以实现具名插槽。

    header

    footer

  4. 作用域插槽

  • 使用场景:当子组件做循环的数据和结构需要外部传入时

  • 父组件中必须以


作为包裹的标签,slot-scope接受子组件传递过来的值

  • 作用是:可以使父组件灵活的控制样式

动态组件与v-once指令

  1. 使用is与使用:is的区别:

  • is:如果这里使用is,is=后面跟的是字符串,就是指将当前使用is替换为名为type的组件,

  • :is:如果使用:is,其实,就是v-bind:is,:is=后面跟的就是一个JS表达式,表达式为type指向了type这个对象

vue自带的动态标签


根据type的值变换为相应的组件 如果点击按钮前是type=“one”则会显示vue.component(“one”,{})这个组件 如果点击前按钮是type=“two”则会显示vue.component(“two”,{})这个组件

<div id="app">    <component :is="type"></component>    <button @click="handclick">点击</button></div><script>Vue.component('child-one',{    template:'<div>one</div>'})Vue.component('child-two',{    template:'<div>two</div>'})    var app = new Vue({        el:'#app',        data:{            type:'child-one'        },        methods:{            handclick:function(){                this.type = this.type =='child-one'?'child-two':'child-one'            }        }    })复制代码
  1. v-once只对内部渲染一次,如果模板发生变化,也不会理会