vue实用难点讲解

此篇文章是我基于研究vue文档三遍的基础上,以为还有点难理解或者难记的知识点总结

  1. 列表渲染css

    1.渲染组件必须加key,而且属性是手动传递给组件的
        <my-component
            v-for="(item, index) in items"
            v-bind:item="item"
            v-bind:index="index"
            v-bind:key="item.id">
        </my-component>
    2.v-for和v-if用在同一个节点上面,会先执行v-for而后再执行v-if
    3.使用v-for最好加上key值,由于vue自己是基于就地更换的原则,也就是你在1-100之间再插入一个数值好比5,那么原来的5和后面的数据都会依次加一,这样的效率是很是低的,若是你传递了key作惟一的标识,那么插入的5就插在4后面了,后面的数据就不变了,只是位置挪了下
  2. 事件对象html

    • 要使用事件对象,必须在调用的时候传递$event,不能是其余的名字
    • 经常使用的事件修饰符vue

      .stop 阻止冒泡
      .prevent 阻止默认行为
      .capture 使用事件捕获
      .self 自身触发
      .once 触发一次
    • 按键修饰符node

      .enter
      .tab
      .delete
      .esc
      .space
      .up
      .down
      .left
      .right
      自定义修饰符 Vue.config.keyCodes.f1 = 12
    • 鼠标按键修饰符react

      .left
      .right
      .middle
  3. 表单webpack

    表单修饰符
    .lazy v-model默认是监听oninput事件的加上这个修饰符,就是监听onchange事件 <input v-model.lazy="msg" >
    .number 将用户输入值转换成数字
    .trim 自动将用户输入的首尾空格去掉
  4. 组件通讯git

    1.父组件传递信息给子组件
        子组件要想获得父组件的数据,只须要在子组件内部经过props显示的声明本身想要什么属性,是否是有点意思,就像女的问男的要东西同样,我要lv包包。声明以后父组件将数据传递给子组件就ok了,以下
            Vue.component('child',{
                props: ['message','myMessage'],
                template: '<span>{{ message }}</span>'
            })
            在父组件中使用 <child message="hello!" :my-message="parentMsg"></child> 便可
        注意:在子组件中不能修改父组件传递过来的数据,只能作备份来修改,而且引用类型要深拷贝
    2.在父组件中经过传递非props属性,将自动添加到子组件根元素上面,以下
        <bs-date-input data-3d-date-picker="true"></bs-date-input>
        若是子组件上面已经存在了同名属性,通常都是直接替换的,可是class和style是和子组件的class和style合并的
    3.子组件通知父组件
        在子组件中触发某个事件同时v-on:click="childfunciton",能够经过在childfunction内部添加this.$emit('somefunction')通知触发父组件中的事件,在父组件中经过v-on:somefunction="parentfunction"接受到通知,而后触发父组件中的parentfunction事件,也就是说在父组件中,将v-on用在子组件标签上面并非给子组件绑定事件而是监听子组件内部的消息,可是若是确实想绑定一个事件给子组件能够经过添加.native修饰符,以下
        <my-component v-on:click.native="doTheThing"></my-component>这个事件将直接绑定到子组件的根元素
    4.子组件父组件数据双向绑定
        在父组件中的子组件标签上绑定属性使用.sync修饰符,便可完成数据双向绑定,以下
        <child :foo.sync="bar"></child>
        在parent组件内部定义bar属性,便可将bar值实时的经过foo传递给子组件
        在子组件内部经过this.$emit('update:foo','hahahha');能够在任意时刻修改父组件中的bar值,此函数内部其实执行的是 bar => bar = val,实际上就是直接给bar赋值,可是只能采用这种方式
    5.其实上面说的组件通讯仍是基础的,下面来看一个高级点的
        <input v-model="something">
        v-model其实,就是下面的简写形式
        <input v-bind:value="something" v-on:input="something =  $event.target.value">
        一样v-model也能够用在组件身上,就是以下的样子了
        <custom-input :value="something" @input="value => { something = value }"></custom-input>
        因此知道这上面两点就能够实现自定义组件v-model功能了
        下面是child.vue的代码
            <div>
                <input type="text" :value="value" @input="updateValue($event.target.value)">
                {{value}}
            </div>
            export default {
                props: ['value'],
                methods: {
                    updateValue(value){
                        this.$emit('input',value)
                    }
                },
            }
        下面是father.vue的代码
            <child v-model="price"></child>
            data () {
                return {
                    price: ''
                }
            }
        在子组件中的input中输入数据,能够动态的反应到父组件中,实现双向绑定
        因为默认是value和input若是想改变这个默认的,能够在子组件中,使用model以下
            在子组件中声明
            model: {
                prop: 'checked',
                event: 'change'
            },
            props: {
                checked: Boolean,
                value: String
            }
        因此使用<my-checkbox v-model="foo" value="some value"></my-checkbox>其实就是下面的简写
        <my-checkbox :checked="foo" @change="val => { foo = val }" value="some value"></my-checkbox>
    6.非父子组件之间的通讯
        非父子组件之间的通讯就要使用$on了
        首先要有一个空的vue实例
            var bus = new Vue();
            若是你使用vue的webpack项目的话,这个东西你要单独的加在一个js文件中以store.js为例,添加以下代码
                import Vue from 'vue'
                window.bus = new Vue();
            而且还要在main.js中经过import './store.js'导入,这时就能够在vue项目全局使用bus了
        若是在一个组件中须要传递消息,就使用bus.$emit('fn', 1)传递数据
        在要接受数据的组件中使用,bus.$on('fn',function(value){...})便可
    讲到这儿,vue最核心的部分也就将完了,弄懂这块儿东西,相信后面的学习就易如反掌了
    7.使用slot实现内容分发
        实际工做中组件的组成大多数是相似下面的
            <parent>
                <child>
                    <someother-component></someother-component>
                </child>
            </parent>
        slot的做用就是用来处理嵌套在组件标签内部的内容
    8.单一slot
        若是只有一个slot标签而且没有任何属性,slot标签将会被所有替换成嵌套在组件标签内部的内容,若是slot标签自身包裹内容,这个内容只会在组件标签内部不包含任何东西的时候展现,demo以下
            若是一个child组件的模板内容以下
            <div>
                <h2>I'm the child title</h2>
                <slot>
                    这里面的内容只会在没有插入内容时显示
                </slot>
            </div>
            而后<child>hahahhahahah</child>
            那么hahahhahahah就会替换slot成为child模板的一部分
    9.命名slot
        能够给slot起个名字,好比<slot name="header"></slot>
        而后给组件标签内容添加slot属性,属性值和上面的名字相同,就能够实现特殊指派了,如
        <child>
            <h1 slot="header">指定的内容</h1>
        </child>
        这样就实现的需求导入了
    10.局部slot
        上面讲的slot都是能够实现父组件传递数据到子组件中,如今想实现将子组件中的数据传递到slot要替换的内容中
        能够在子组件中的slot插槽中添加任意属性,如 <slot text="子组件child中的数据"></slot>
        而后,在子组件标签内部,以下
            <parent>
                <child>
                    // 必须使用template标签,而且添加scope属性,属性值props就是包含slot传递的数据对象
                    <template scope="props">
                        <span>父组件parent中的数据</span>
                        <span>{{props.text}}</span>
                    </template>
                </child>
            </parent>
    11.动态组件
        可使用同一个绑定点,动态的切换渲染不一样的组件,要实现这个功能要借助component标签和is属性
            <component :is="currentView"></component>    
            vue实例代码以下
            var vm = new Vue({
                el: "#example",
                data: {
                    currentView: 'home'
                },
                components: { home,posts,archive }
            })    
            经过改变currentView的值,能够实现动态切换组件   
        上面这种写法能够知足局部组件,也就是你本身定义的组件的切换,可是若是你使用全局组件,好比某些UI组件库中的组件,那么就要像下面这样用
            var Home = {
                template: ...
            };
            var vm = new Vue({
                el: "#example",
                data: {
                    currentView: Home
                }
            });
        若是你想将切换渲染过的组件保留在内存中可使用keep-alive将动态组件包裹
            <keep-alive>
                <component :is="currentView">
                    ...
                </component>
            <keep-alive>
  5. vue动画效果github

    **vue的过渡
    过渡通常用于元素的插入,删除,移除
    下面讲解过渡的知识
        1.对单个的元素或者组件使用过渡
            使用transition标签包裹要应用过渡的元素
            <transition name="fade">
                <p v-if="show">hello</p>
            </transition>
            当上面的p元素在显示和隐藏中间切换时,会发生如下事情
            第一,检测目标元素,自动添加或移除css过渡类名
            第二,执行transition的钩子函数
            第三,若是上面两步骤都没有对应的设置,那么不会应用过渡效果
        2.过渡的类名
            v-enter 进入的开始状态,在元素插入以前添加,在元素插入以后删除
            v-enter-active 整个进入过程的状态,连续的画面,这个类就是用来定义动画的持续时间,延迟和线性函数的
            v-enter-to 进入的结束状态,在元素插入以后添加,在整个enter-active结束后删除
            v-leave 消失的开始状态
            v-leave-active 整个消失的过程
            v-leave-to 消失的结束状态
            上面的这些类名的v是默认的前缀,你能够给transition标签指定name属性,用来自定义类名前缀
            上面提到的元素的插入和移除就是页面上dom元素的一瞬间的状态
        3.css过渡
            就是指定好开始和结束的css样式,而后定义动画的执行过程,以下所示
                .v-enter-active,.v-leave-active{
                    transition: all .3s ease;
                }
                .v-enter,.v-leave-to{
                    transform: translateX(10px);
                    opacity: 0;
                }
        4.css动画
            上面都是应用的transition,这里是animation,其实相似
                .v-enter-active{
                    animation: bounce-in .5s;
                }
                .v-leave-active{
                    animation: bounce-in .5s;
                }
                @keyframes bounce-in {
                    0% {
                        transform: scale(0);
                    }
                    50% {
                        transform: scale(1.5);
                    }
                    100% {
                        transform: scale(1);
                    }
                }
        5.css过渡类名
            若是你使用animate.css这类的第三方css库,能够借助以下的类名
                enter-class
                enter-active-class
                enter-to-class
                leave-class
                leave-active-class
                leave-to-class
            使用demo
                <transition
                    enter-active-class="animated tada"
                    leave-active-class="animated bounceOutRight"
                >
                    <p v-if="show">hello</p>
                </transition>
        6.如何区分animation和transition
            当你的动画中同时使用transition形式和animation形式的动画,必须添加type属性,指定属性值为animation或者transition
        7.指定动画持续时间
            vue默认的动画持续时间是基于根过渡元素,内部的子过渡元素的持续时间若是长于根过渡元素将会被忽略,因此能够在transition标签上面添加duration属性,demo以下
                <transition :duration="1000">...</transition>
                <transition :duration="{enter: 500,leave: 800}"></transition>
        8.添加动画钩子函数,这部份内容用的比较少,感兴趣自行了解
        9.对初次渲染的元素添加过渡
            添加appear属性 <transition appear> </transition>
            添加这个属性以后,会自动应用以前指定好的enter和leave的动画,若是想实现单独的动画功能可使用以下的方式
                <transition
                    appear
                    appear-class="..."
                    appear-to-class="..."
                    appear-active-class="..."
                ></transition>
        10.在多个元素中应用过渡
            上面讨论的都是基于单个过渡元素,下面讨论多个元素的过渡
            通常使用v-if/v-else在元素以前切换,相同的元素在切换的时候回复用,因此要添加key属性,以下
                <transition>
                    <button v-if="isEditing" key="save">
                        Save
                    </button>
                    <button v-else key="edit">
                        Edit
                    </button>
                </transition>
            此外,很能够添加mode属性,用来指定显示和隐藏的前后顺序
                in-out 先入后出
                out-in 先出后入
        11.列表过渡
            上面讲的都是一次过渡一个元素,如今讲一次过渡多个元素
            过渡多个元素就要借助transition-group而且还要给须要过渡的元素添加key属性,能够给transition-group标签添加tag属性,指定具体渲染后的元素,还能够添加.v-move类,当元素的位置变化了,自动添加此类,此动画功能只适用于非display: inline元素
    **过渡state数据
        能够对数字型的数据,颜色值,这类的数据作过渡效果,主要是配合第三方库来作的,感兴趣的本身去看吧
  6. render函数web

    讲实话这部份内容在实际使用中,几乎用不上,我的感受vue的单文件组件,已经替代了这个的功能,因此说强大的jsx功能在vue中可能就是一个摆设而已,这也是为何高端互联网企业选择react的缘由了吧
    vue的render函数说白了就是用js编写html,说实话和jsx比起来,render是很是麻烦的
    vue中写render就不须要template选项了
        Vue.component('demo-render',{
            render: function(createElement){
                // 这个函数的结果就是组件的template
                return createElement(
                    // 这个函数接受三个参数
                    'div', 能够是组件也能够是html标签
                    {}, 当前vnode的属性对象,这个属性对象的介绍请看下面
                    [] 字符串或者数组均可以,子节点,若是子节点下面还有子节点能够再次调用createElement方法
                )
            }
        })
    属性对象的介绍
        {
            'class': {//v-bind:class},
            style: {//v-bind:style},
            attrs: {//正常的html属性如id这类的},
            props: {//当前的节点是另一个组件的话,这个就是传递给组件的属性对象},
            domoProps: {//Dom节点的属性对象好比innerHTML},
            on: {//v-on: 不支持修饰符},
            nativeOn: {// 只能在当前的节点是其它组件的时候生效},
            directives: [//自定义指令],
            slot: 'somename', //指定slot标签,用于插入内容,属性值是slot的name属性值
            scopedSlots: {
                // 说实话这个东西对于初学者是很难懂的,我也是看了不少遍才明白
                /*
                 局部插槽顾名思义,其实就是用来给子组件使用的,因此这部份内容就直
                 接放在render里面编写
                 default: props => createElement('span',props.text);
                 上面的代码和下面的原始写法是表达的意思是如出一辙的
                    <template scope="props">
                        <span>{{props.text}}</span>
                    </template>
                */
            },
            key: 'myKey', 就是key属性
            ref: 'myRef' 当前vnode的引用
        }
    使用render的注意点
        全部的render内部使用的vnode必须都是独一无二的,不一样使用相同vnode的引用
        能够在vue中使用jsx代替你,render函数的复杂写法,例子以下
            render (h) {
                return (
                    <AnchoredHeading level={1}>
                        <span>Hello</span> world!
                    </AnchoredHeading>
                )
            }
            这就是jsx语法,通俗易懂
            具体的学习地址https://github.com/vuejs/babel-plugin-transform-vue-jsx#usage
        建议:
            若是你被jsx的魅力所吸引,我我的以为仍是去学react的吧,在vue中的单文件组件彻底能够知足你的项目开发需求,若是你在.vue文件中使用jsx或者render会变得很是奇怪,在template中使用html又在js中使用html简直就是怪胎
  7. 自定义指令数组

    说实话,这部份内容我不太想写出来,一门技术总有好的和坏的反面,偶尔了解一些不太好的东西,对本身学习其余知识,能够扩展视野
    这部份内容就是本身写一个指令好比v-myDirective,而后利用vue提供的钩子函数,在合适的时机触发他们。简单demo以下
        Vue.directive('focus',{
            // 全局指令
        })或者
        directive: {
            focus: {
                // 局部指令
                // 能够在这里面指定钩子函数,表示在什么时候执行这些钩子函数
                // 说白了就是利用元素的生命周期钩子实现所谓的自定义指令和vue实例的生命周期钩子本质是同样的,呵呵
                bind: function(// 全部的钩子函数在这里面均可以传递参数,参数后面讲){// 当指令绑定到元素上执行,只执行一次},
                inserted: // 元素插入的时候执行,
                update: // 元素自身更新,执行,
                componentUpdated: // 子组件更新执行,
                unbind: // 解绑的时候执行
            }
        }
        具体使用,就在须要的元素上面直接写上指令名称便可 <input v-focus>
    钩子函数的参数
        el // 绑定的dom元素
        binding // 关于指令的相关属性对象,细节本身看
        vnode ,oldVnode // 虚拟节点对象
    这部份内容了解,就能够了
  8. Mixins混入

    这部份内容用的也比较少,不过当你的组件中有不少重复的method或者其余的选项,可使用这个减小冗余代码
    一个mixin对象能够包含实例的任何选项
        var myMixin = {
            created: function(){
                this.hello();
            },
            methods: {
                hello: function(){
                    console.log('hello from mixin!')
                }
            }
        }
        var Component = Vue.extend({
            mixins: [myMixin]
        })
        var component = new Component();
    混入的规则以下
        1.钩子函数会放进一个队列里面,先执行mixin对象中的钩子,而后执行实例的钩子
        2.methods,components,directives都会被合并成一个对象,同名的属性只会使用组件的,舍弃掉mixin对象的
        3.全局混入
            全局混入尽可能不要用会污染全部的vue实例
                Vue.mixin({
                    created: function() {
                        ...
                    }
                })
        4.用户自定义选项的合并
            默认是组件的直接覆盖掉mixin对象的同名属性
            若是想对自定义选项myOption应用自定义逻辑,可使用以下的函数  
                Vue.config.optionMergeStrategies.myOption = function(toVal,fromVal){
                    // ...
                }
            若是自定义选项是对象的话也可使用methods选项的合并规则
                var strategies = Vue.config.optionMergeStrategies;
                strategies.myOption = strategies.methods

    结语

    有能力的同窗,我建议去学学react,毕竟到这儿,vue你已经精通了

相关文章
相关标签/搜索