Vue基础知识 -过滤器、样式绑定、slot插槽内容分发

习惯了使用React, 偶尔接手Vue项目,使用的时候有点别扭,故做此笔记,以供时不时查看。

1. 过滤器

插值或绑定表达式。

<p>{{name|formatValue}}</p>

<my-info :name="name|formatValue" />
// ...
export default{
    data(){
        return {
            name:""
        }
    },
    filters:{
        formatValue(val){
            return val.toLocaleUpperCase()
        }
    }
}
1.1 全局过滤器与局部过滤器重名时,采用局部过滤器
1.2 可接受多个过滤器,前一个过滤器的结果值作为第一个参数
<p>{{name|formatValue|formatValue2}}</p>

// ...
export default{
    data(){
        return {
            name:""
        }
    },
    filters:{
        formatValue(val){
            return val.toLocaleUpperCase()
        },
        formatValue2(val){
            return val.substring(1)
        }
    }
}
1.3 接受额外参数,目标过滤的值为第一个参数
<p>{{name|formatValue("-")}}</p>

// ...
export default{
    data(){
        return {
            name:""
        }
    },
    filters:{
        formatValue(val,join){
            return val.splice("").join(join)
        }
    }
}

2. 事件默认参数

通过事件绑定,并可传入指定的其他参数。

<button @click="hanleClick($event,'view')"></button>

$event则是事件对象。如果是自定义组件,抛出的事件时,为传入的参数。

不需要自定义传入参数时,则监听函数默认接受事件抛出的参数。

<button @click="hanleClick"></button>

//...
export default{
    dat(){
        return {}
    },
    methods:{
        hanleClick(event){}
    }
} 

2.1 事件修饰器

事件修饰符定义:

  • .stop 阻止事件冒泡
  • .prevent 阻止事件默认行为
  • .capture 使用事件的捕获模式
  • .self 只在当前元素上触发事件时触发。
  • .once 触发一次事件
  • .passive 监听的事件会立即触发。提升移动端的性能

按键修饰符:.enter \ .tab \ .delete \ .esc \ .space \ .up \ .down \ .left \ .right . 也可自定义按键修饰符

系统修饰符 :.ctrl \ .alt \ .shift \ .meta

.exact 可以更精确的控制组合按键。


<!-- 按下alt或shift键也会触发点击事件 -->
<button @click.ctrl="handle"></button>

<!-- 仅只有ctrl键会按下才会触发 -->
<button @click.ctrl.exact="handle"></button>
2.2 .native 可以将原生事件绑定到组件上

3. 访问data属性的初始值

通过$optoins实例属性访问初始化选项。

// 访问 data的初始值
this.$options.data()

4. 手动对某些数据进行监听

通过实例方法$watch检测一个值或键值表达式的变化。

export default{
    data(){
        return {
            name:""
        }
    },
    mounted(){
        this.$watch('name',function(newVal,oldVal){})
    }
}
4.1 第一个参数为函数,用于处理更复杂的值得计算
export default{
    data(){
        return {
            firstName:"",
            lastName:""
        }
    },
    mounted(){
        this.$watch(funtion(){
            return this.firstName+this.lastName
        },
        function(newVal,oldVal){})
    }
}
4.2 返回一个取消函数,用来停止触发回调
var unwatch = vm.$watch('a', cb)
// 之后取消观察
unwatch()
4.3 第三个参数配置监听的逻辑处理
this.$watch('name',function(newVal,oldVal){
    // ...
},{
    // 深度检测,检测对象内部的值
    deep:true,
    // 立即触发检测变化的回调函数
    immediate:true
})

5. 手动调用生命周期

通常我们通过组建的选项定义生命周期,

export default{
    data(){
        return {}
    },
    mounted(){},
    destory(){}
}

如果我们要即时定义在组建销毁时处理某些事件监听器被销毁或者对象清空

export default{
    data(){
        return {}
    },
    mounted(){
        let event = new Event()
        // 
        this.$once('hook:beforeDestroy', function () {
            event.off()
        })
    },
    destory(){}
}

6. 可动态绑定属性、绑定事件

<template>
    <div>
        <a :[key]="url" @[event]="handleClick"></a>
    </div>
</template>
<script>
    export default{
        data(){
            return {
                key:'virtual-href',
                url:'',
                event:'click'
            }
        },
        mounted(){
            // 可以判断URL是否可访问,
            let img = new Image()
            img.onload = function () {
                // 转换为真实的URL地址
                this.key = href
            }
            img.onerror = function () {
                // 可备用访问地址
                this.url = ""
            }
            img.src = url
        },
        methods:{
            handleClick(){}
        }
    }
</script>

7. class 与 style的绑定

7.1 class对象属性绑定。
<div class="box" :class="{active:isActive}" />

可通过对象绑定

<div :class="styleObj" />

// ...
export default {

    data(){
        return {
            isActive:false
        }
    },
    computed:{
        styleObj(){
            return {
                box,
                active:this.isActive
            }
        }
    }
}
7.2 数组绑定

多个属性进行绑定

<div :class="[activeClass,errorClass]" />

// ...
export default {

    data(){
        return {
            activeClass:'active',
            errorClass:'text-error'
        }
    },
}

使用三元表达式进行绑定

<div :class="[isActive?activeClass:'',errorClass]" />

// 可数组内使用对象进行绑定

<div :class="[{activeClass:isActive},errorClass]" />
7.3 自定义组件上绑定的class属性会被自动绑定到根元素上

MyTable.vue

<template>
    <div class="my-tabl"></div>
</template>

使用自定义组件

<my-table class="table-box" />

// 渲染后, 绑定属性合并
<div class="my-tabl table-box"></div>
7.4 style绑定基本使用class绑定的模式

style绑定可指定浏览器的前缀

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

根据浏览器支持情况,渲染出支持的模式。

7.5 通过inheritAttrs:false定义阻止属性绑定到根元素上
export default{
    inheritAttrs:false
}

对于class和style的绑定,是不生效的。除此之外$attrs可以绑定到其他子元素上。

8. Props类型定义

props:{
    name:String,
    // 多个类型定义
    value:[String,Number],
    // 默认值对象
    info:{
        type:Object,
        default:()=>{}
    },
    // 自定义验证函数
    age:{
        validator: function (value) {
            // 验证失败时,产生一个警告
            return value.match(/^0-9$/)
        }
    }
}

9. slot 作用于插槽

实现内容分发,用于封装公共组件的关键API。

9.1 默认内容的分发

my-info.vue

<template>
    <div>
        <p>slot内容分发</p>
        <slot></slot>
    </div>
</template>

在使用时,组件内部的呢日用会被插槽放置到slot 的位置

<my-info>
    <div>
        自定义的内容会被放置在slot中
    </div>
</my-info>
9.2 当有多个slot内容需要分发时,通过name定义位置名称

通过定义slotname属性,

<template>
    <div>
        <p>slot内容分发</p>
        <header>
            <slot name="header"></slot>
        </header>
        <main>
            <slot></slot>
        </main>
        <footer>
            <slot name="footer"></slot>
        </footer>
    </div>
</template>

使用时,则通过v-slot占位空间,放置内容。

<my-info>
    <div v-slot:header>
        自定义的内容会被放置在slot中 header处。
    </div>
</my-info>

v-slot:header可简写 为#header

<my-info>
    <div #header>
        自定义的内容会被放置在slot中 header处。
    </div>
</my-info>
9.3 作用于插槽,访问子组件中的数据
<template>
    <div>
        <p>slot内容分发</p>
        <slot v-bind:params="user"></slot>
    </div>
</template>

在使用时,通过v-slot获取到绑定的属性

<my-info>
    <div v-slot="{params}">
        自定义的内容会被放置在slot中 - {{params.name}}
    </div>
</my-info>

在简写时,则不能省略插槽名,默认插槽必须追加#default

<my-info>
    <div #default="{params}">
        自定义的内容会被放置在slot中 - {{params.name}}
    </div>
</my-info>
9.4 只有提供了默认插槽内容时,自定义组件才能当做插槽的模板使用。

info-detail.vue 自定义组件 , my-info只有默认的插槽内容

<my-info>
    <info-detail v-slot="{params}">
        自定义的内容会被放置在slot中 - {{params.name}}
    </info-detail>
</my-info>
9.5 当有多个插槽内容时,v-slot默认插槽不能缩写,书写为v-slot:default
<my-info>
    <div v-slot:header="{params}">
        在slot中, header位置放置内容- {{params.name}}
    </div>
    <div v-slot:default="{params}">
        自定义的内容会被放置在slot中 - {{params.name}}
    </div>
</my-info>
9.6 定义动态的插槽名,通过数据状态不同,展示不同数据内容。
<my-info>
  <template v-slot:[dynamicSlotName]>
    // ...
  </template>
</my-info>

10. 动态组件、异步组件

切换组件展示,

<component v-bind:is="activeComponent"></component>

可通过动态定义的activeComponent展示不同的组件。

10.1 缓存已创建的组件,提高性能 keep-alive

这样组件不会被销毁,状态也不会销毁。

<keep-alive>
    <component v-bind:is="activeComponent"></component>
</keep-alive>
10.2 异步加载组件,优化打包
Vue.component('my-info', function (resolve) {
  // 全局注册组件是,异步加载,编译时构建多个包
  require(['./my-info'], resolve)
})

// 或者使用import
Vue.component('my-info', ()=>import('./my-info'))

如果是局部组件注册

new Vue({
  // ...
  components: {
    'my-info': () => import('./my-info.vue')
  }
})
10.3 异步加载时,定义加载状态

定义异步组件加载的配置对象,可定义加载时的展示组件、加载失败后的组件

const AsyncComponent = () => ({
  // 需要加载的组件 (应该是一个 `Promise` 对象)
  component: import('./MyComponent.vue'),
  // 异步组件加载时使用的组件
  loading: LoadingComponent,
  // 加载失败时使用的组件
  error: ErrorComponent,
  // 展示加载时组件的延时时间。默认值是 200 (毫秒)
  delay: 200,
  // 如果提供了超时时间且组件加载也超时了,
  // 则使用加载失败时使用的组件。默认值是:`Infinity`
  timeout: 3000
})

11. 进入/离开、过渡效果

11.1 单组件过度效果 transition
  1. 条件渲染v-if、v-show
  2. 动态组件
  3. 可用于组件根节点
<transition name="fade">
    <p v-if="bool"></p>
</transition>

则会在适当的实际追加class,如果没有指定name,则以v-为前缀

  • v-enter 进入过渡的开始状态。在元素插入前生效
  • v-enter-active 定义过渡中的状态
  • v-enter-to 元素插入之后的状态。
  • v-leave 定义元素离开的开始状态
  • v-leave-active 定义元素离开过渡生效时的状态。
  • v-leave-to 定义元素离开过渡完成的状态
11.2 如果使用第三方动画库,可直接定义各阶段的class

在需要过渡的元素定义过渡的class名。

  • enter-class
  • enter-active-class
  • enter-to-class
  • leave-class
  • leave-active-class
  • leave-to-class

这些优先级高于普通的类名。

11.3 通过钩子函数定义过渡执行的时机回调

可以手动控制元素,使用JS动画。

可通过设置v-bind:css="false"跳过css过渡的检测,避免影响JS多度

  • v-on:before-enter
  • v-on:enter
  • v-on:after-enter
  • v-on:enter-cancelled
  • ...

在完成过渡的时候,在enter和leave中必须使用done进行回调。否则过渡会被同步调用,立即完成。

11.4 通过过渡模式定义新、旧元素的切换
<transition name="fade" mode="out-in">
    <p v-if="bool"></p>
</transition>
  • in-out 新元素先过渡,完成之后当前元素多度离开。
  • out-in 当前元素先过渡,完成之后新元素过渡进入
11.5 transition-group 处理渲染多个元素的过渡效果
  • 会议真实的节点元素渲染,默认为span. 也可指定tag属性,
  • 不可使用过渡模式
  • 内部元素需要提供唯一key键值
  • css过渡类会应用内部的每一个元素上。

了解新的一个过渡类v-move 用与设置过度的切换时机和过渡曲线。

12. 状态过渡

  • 数字和运算
  • 颜色的显示
  • SVG 节点的位置
  • 元素的大小和其他的 property

13. CreateElement 参数

通常会简写为 h

h(tag,options,children) 主要的是options设置

{   
    // 定义class名
    class:{},
    // 定义内联style样式
    style:{},
    // 普通的html元素属性设置
    attrs:{
        id:"",
    },
    // 组件的props 设置,自定义组件
    props:{
        info:{}
    },
    // DOM 自身属性
    domProps:{},
    // 事件监听器
    on:{
        click:this.handleClick
    },
    // DOM 原生事件,非组件内部触发`$emit.on()`
    nativeOn:{
        click:this.handleNativeClick
    },
    // 自定义指令,
    directives:[
        {
            name: 'my-directive',
            value: '2',
            expression: '1 + 1',
            arg: 'foo',
            modifiers: {
                bar: true
            }
        }
    ],
    // 作用于插槽
    // slotName:props=>定义的组件
    scopedSlots:{
        default:props=>VNode
    },
    // 如果组件是其他组件的子组件按,指定插槽名称
    slot:"",
    key:"",
    ref:"box",
    // 在创建其他元素时,是否应用了一样的ref名称,
    // `$refs.box`变成一个数组
    refInFor: true
}

还是喜欢使用JSX风格书写组件

14. 使用插件

自定义组件或者开发公共组件需要提供一个install方法。然后通过Vue.use()注册。

// 第一个参数为当前Vue实例对象,第二个为配置项
export default {
    install:(app,option)=>{
        // 注册全局属性、方法
        app.globalAttrs = ""
        // 全局组件注册
        app.component(Component.name,Component)

        // 组件实例可访问的方法
        app.prototype.$myFn = (){
            // ...
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容

  • 什么是Vue 是一套用于构建用户界面的渐进式 javascript 框架(渐进式:想用什么就用什么不必全都用) 在...
    王果果阅读 4,769评论 0 14
  • Vue.js(读音/vjuː/, 类似于 view)是一个构建数据驱动的web 界面的渐进式框架。Vue.js的目...
    xingyunfuhao阅读 585评论 0 0
  • 1. Vue 实例 1.1 创建一个Vue实例 一个 Vue 应用由一个通过 new Vue 创建的根 Vue 实...
    王童孟阅读 1,016评论 0 2
  • 构造器 实例化vue时,需传入一个选项对象,它可以包括 数据、模板、挂载元素、方法和生命周期钩子属性与方法 每个v...
    饥人谷_阿银阅读 440评论 0 0
  • 每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的: 实例生命周期钩子 每个 Vue 实例...
    Timmy小石匠阅读 1,372评论 0 11