8.函数式组件
无状态 无法实例化 内部没有任何生命周期函数 一切都是通过context参数传递
context 属性有: 1.props:提供所有 prop 的对象 2.children: VNode 子节点的数组 3.slots: 一个函数,返回了包含所有插槽的对象 4.scopedSlots: (2.6.0+) 一个暴露传入的作用域插槽的对象。也以函数形式暴露普通插槽。 5.data:传递给组件的整个数据对象,作为 createElement 的第二个参数传入组件 6.parent:对父组件的引用 7.listeners: (2.3.0+) 一个包含了所有父组件为当前组件注册的事件监听器的对象。这是 data.on 的一个别名。 8.injections: (2.3.0+) 如果使用了 inject 选项,则该对象包含了应当被注入的属性

<template functional>
  <div v-for="(item,index) in props.arr">{{item}}</div>
</template>
  1. components和Vue.component
局部注册
export default{
  components:{home}
}
全局注册
Vue.component('home',home)
  1. Vue.extend

有时需要将一些元素挂载到元素上,需要用到extend

// 创建构造器
var Profile = Vue.extend({
  template: '<p>{{extendData}}</br>实例传入的数据为:{{propsExtend}}</p>',//template对应的标签最外层必须只有一个标签
  data: function () {
    return {
      extendData: '这是extend扩展的数据',
    }
  },
  props:['propsExtend']
})

// 创建的构造器可以挂载到元素上,也可以通过 components 或 Vue.component()注册使用
// 挂载到一个元素上。可以通过propsData传参.
new Profile({propsData:{propsExtend:'我是实例传入的数据'}}).$mount('#app-extend')

// 通过 components 或 Vue.component()注册
Vue.component('Profile',Profile)

11.mixins
有些组件有重复的js逻辑 校验 可以放入mixins

const mixin={
    created(){
      this.dealTime()
    },
    methods:{
      dealTime(){
        console.log('这是mixin的dealTime里面的方法');
      }
  }
}

export default{
  mixins:[mixin]
}
  1. extends

只能单次扩展一个组件

const extend={
    created(){
      this.dealTime()
    },
    methods:{
      dealTime(){
        console.log('这是mixin的dealTime里面的方法');
      }
  }
}

export default{
  extends:extend
}
  1. Vue.use()

会触发install函数

  1. install 第一个参数是vue的构造器,第二个参数是一个可选的选项对象
var MyPlugin = {}
MyPlugin.install = function (Vue,options) {
//添加全局资源
 Vue.directive('click',{
        bind(el,binding,vnode,oldVnode){
            //绑定的准备工作,添加时间监听
 console.log('指令my-directive的bind执行了');
 },
 inserted:function (el) {
            //获取绑定的元素
 console.log('指令my-directive的inserted执行啦')
        },
 update:function () {
            //初始化会调用一次 更新也会调用
 console.log('指令my-directive的update执行啦');
 },
 componentUpdated:function () {
            console.log('指令my-directive的componentUpdated执行啦');
 },
 unbind:function () {
        //做清理工作
 //    例如一次bind时的事件监听器 console.log('指令my-directive的unbind执行啦');
 }
    })
    //混入组件
 Vue.mixin({
        created:function () {
            console.log('注入组件的created被调用啦');
 console.log('options的值为',options)
        }
    })
    Vue.prototype.$myMethod = function (methodOptions) {
        console.log('实例方法myMethod被调用啦');
 }
}
Vue.use(MyPlugin,{someOption:true})
  1. Vue.nextTick

页面加载后需要获取焦点 在dom更新完成结束后立即调用事件

mounted(){ //因为 mounted 阶段 dom 并未渲染完毕,所以需要$nextTick this.$nextTick(() => { this.$refs.inputs.focus() //通过 $refs 获取dom 并绑定 focus 方法 }) }
  1. Vue.directive

例如将color变成指令时可以使用

// 全局定义
Vue.directive("change-color",function(el,binding,vnode){
  el.style["color"]= binding.value;
})

// 使用
<template>
<div v-change-color=“color”>{{message}}</div>
</template>
<script>
  export default{
    data(){
      return{
        color:'green'
      }
    }
  }
</script>

1.bind 只调用一次,指令第一次绑定到元素时候调用,用这个钩子可以定义一个绑定时执行一次的初始化动作。 2.inserted:被绑定的元素插入父节点的时候调用(父节点存在即可调用,不必存在document中) 3.update: 被绑定与元素所在模板更新时调用,而且无论绑定值是否有变化,通过比较更新前后的绑定值,忽略不必要的模板更新 4.componentUpdate :被绑定的元素所在模板完成一次更新更新周期的时候调用 5.unbind: 只调用一次,指令月元素解绑的时候调用

17.Vue.filter
将时间戳转化成年月日的公共方法

// 使用
// 在双花括号中
{{ message | capitalize }}

// 在 `v-bind` 中
<div v-bind:id="rawId | formatId"></div>

// 全局注册
Vue.filter('stampToYYMMDD', (value) =>{
  // 处理逻辑
})

// 局部注册
filters: {
  stampToYYMMDD: (value)=> {
    // 处理逻辑
  }
}

// 多个过滤器全局注册
// /src/common/filters.js
let dateServer = value => value.replace(/(\d{4})(\d{2})(\d{2})/g, '$1-$2-$3') 
export { dateServer }
// /src/main.js
import * as custom from './common/filters/custom'
Object.keys(custom).forEach(key => Vue.filter(key, custom[key]))

  1. Vue.compile

在render模板中编译字符串 只在独立构建时有效

var res = Vue.compile('<div><span>{{ msg }}</span></div>')

new Vue({
  data: {
    msg: 'hello'
  },
  render: res.render,
  staticRenderFns: res.staticRenderFns
})
  1. Vue.version

获取vue版本 做兼容

var version = Number(Vue.version.split('.')[0])

if (version === 2) {
  // Vue v2.x.x
} else if (version === 1) {
  // Vue v1.x.x
} else {
  // Unsupported versions of Vue
}

20.Vue.set()
当你利用索引直接设置数组项时或者修改数组长度,由于Object.defineprototype()方法限制,数据不会响应式更新

// 利用 set
this.$set(arr,index,item)

// 利用数组 push(),splice()

21.Vue.config.keyCodes
自定义按键修饰别名

// 将键码为 113 定义为 f2
Vue.config.keyCodes.f2 = 113;
<input type="text" @keyup.f2="add"/>

22.Vue.config.performance
监听性能 只适用于开发模式和支持 performance.mark api的浏览器
23.Vue.config.errorHandler
1.场景:指定组件的渲染和观察期间未捕获错误的处理函数 2.规则: 从 2.2.0 起,这个钩子也会捕获组件生命周期钩子里的错误。同样的,当这个钩子是 undefined 时,被捕获的错误会通过 console.error 输出而避免应用崩溃 从 2.4.0 起,这个钩子也会捕获 Vue 自定义事件处理函数内部的错误了 从 2.6.0 起,这个钩子也会捕获 v-on DOM 监听器内部抛出的错误。另外,如果任何被覆盖的钩子或处理函数返回一个 Promise 链 (例如 async 函数),则来自其 Promise 链的错误也会被处理 3.使用

Vue.config.errorHandler = function (err, vm, info) {
  // handle error
  // `info` 是 Vue 特定的错误信息,比如错误所在的生命周期钩子
  // 只在 2.2.0+ 可用
}

捕获全局异常
24.Vue.config.warnHandler
为Vue的运行时警告进行自定义处理 只在开发模式有效

Vue.config.warnHandler = function (msg, vm, trace) {
  // `trace` 是组件的继承关系追踪
}

25.v-pre
不进行编译

<span v-pre>{{ this will not be compiled }}</span>   显示的是{{ this will not be compiled }}
<span v-pre>{{msg}}</span>     即使data里面定义了msg这里仍然是显示的{{msg}}

26.v-cloak
在网速慢的情况下 防止变量闪烁 在元素关联到示例后进行编译CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕

// template 中
<div class="#app" v-cloak>
    <p>{{value.name}}</p>
</div>

// css 中
[v-cloak] {
    display: none;
}
  1. v-once

有些 template中的静态dom没有改变,这时候只需要渲染一次,可以降低开销
`<span v-once> 这时只需要加载一次的标签</span>
`
28.事件修饰符
.stop阻止冒泡
.prevent 阻止默认行为
.self 仅绑定元素自身触发
.once 只触发一次
.passive 滚动事件的默认行为触发

29.按键修饰符和按键码
有的时候需要监听键盘的行为,如按下enter去查询接口等

// 对应键盘上的关键字
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right

30.Vue-router
1.缓存和动画

<transition>
  <keep-alive :include="['a', 'b']">
  //或include="a,b" :include="/a|b/",a 和 b 表示组件的 name
  //因为有些页面,如试试数据统计,要实时刷新,所以就不需要缓存
    <router-view/> //路由标签
  </keep-alive>
  <router-view exclude="c"/> 
  // c 表示组件的 name值
</transition>

匹配先检查组件自身的name选项,如果name选项不可用,则匹配它的局部注册名称(父组件components 选项的键值),匿名组件不可用
2、全局路由钩子
router.beforeEach

router.beforeEach((to, from, next) => {
  console.log('全局前置守卫:beforeEach -- next需要调用') //一般登录拦截用这个,也叫导航钩子守卫
  if (path === '/login') {
    next()
    return
  }
  if (token) {
    next();
  } 
})

router.beforeResolve
和 router.beforeEach 类似,区别是在导航被确认之前,并且在所有组件内守卫和异步路由组件被解析之后 在router.beforeEach 之后
router.afterEach
全局后置钩子 路由跳转结束之后被调用
3.组件路由钩子
beforeRouteEnter 在渲染该组件的对应路由前调用,next需要手动调用 可以给next一个vm来访问示例,在导航确认时执行

beforeRouteEnter (to, from, next) {
  // 这里还无法访问到组件实例,this === undefined
  next( vm => {
    // 通过 `vm` 访问组件实例
  })
}

beforeRouterUpdate 当前路由改变,并且该组件被复用时调用
beforeRouterLeave
4.路由模式
mode属性 hash或者history
5.Vue.$router

beforeRouteEnter (to, from, next) {
  // 这里还无法访问到组件实例,this === undefined
  next( vm => {
    // 通过 `vm` 访问组件实例
  })
}

6.Vue.$route
表示当前跳转的路由对象,属性有: name:路由名称 path:路径 query:传参接收值 params:传参接收值 fullPath:完成解析后的 URL,包含查询参数和 hash 的完整路径 matched:路由记录副本 redirectedFrom:如果存在重定向,即为重定向来源的路由的名字

this.$route.params.id:获取通过 params 或/:id传参的参数
this.$route.query.id:获取通过 query 传参的参数
  1. router-view 的key

由于vue恢复用相同的组件 将不再执行created,mounted钩子
`<router-view :key="$route.fullPath"></router-view>
`
31.Object.freeze
冻结属性

new Vue({
    data: {
        // vue不会对list里的object做getter、setter绑定
        list: Object.freeze([
            { value: 1 },
            { value: 2 }
        ])
    },
    mounted () {
        // 界面不会有响应,因为单个属性被冻结
        this.list[0].value = 100;

        // 下面两种做法,界面都会响应
        this.list = [
            { value: 100 },
            { value: 200 }
        ];
        this.list = Object.freeze([
            { value: 100 },
            { value: 200 }
        ]);
    }
})

32.调试template
在开发环境挂载log

// main.js
Vue.prototype.$log = window.console.log;

// 组件内部
<div>{{$log(info)}}</div>

33.vue-loader 小技巧
preserveWhitespace 去掉空格

{
  vue: {
    preserveWhitespace: false
  }
}

transformToRequire 自动配置

// vue-cli 2.x在vue-loader.conf.js 默认配置是
transformToRequire: {
    video: ['src', 'poster'],
    source: 'src',
    img: 'src',
    image: 'xlink:href'
}

// 配置文件,如果是vue-cli2.x 在vue-loader.conf.js里面修改
  avatar: ['default-src']

// vue-cli 3.x 在vue.config.js
// vue-cli 3.x 将transformToRequire属性换为了transformAssetUrls
module.exports = {
  pages,
  chainWebpack: config => {
    config
      .module
        .rule('vue')
        .use('vue-loader')
        .loader('vue-loader')
        .tap(options => {
      options.transformAssetUrls = {
        avatar: 'img-src',
      }
      return options;
      });
  }
}

// page 代码可以简化为
<template>
  <div>
    <avatar img-src="./assets/default-avatar.png"></avatar>
  </div>
</template>

34.为路径设置别名

// 在 webpack.base.config.js中的 resolve 配置项,在其 alias 中增加别名
resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
    }
  },
 vue3.0
// 在根目录下创建vue.config.js
var path = require('path')
function resolve (dir) {
  console.log(__dirname)
  return path.join(__dirname, dir)
}
module.exports = {
  chainWebpack: config => {
    config.resolve.alias
      .set(key, value) // key,value自行定义,比如.set('@@', resolve('src/components'))
  }
}

35.img加载失败

// page 代码
<img :src="imgUrl" @error="handleError" alt="">
<script>
export default{
  data(){
    return{
      imgUrl:''
    }
  },
  methods:{
    handleError(e){
      e.target.src=reqiure('图片路径') //当然如果项目配置了transformToRequire,参考上面 27.2
    }
  }
}
</script>

36。css
局部样式 scoped
deep 属性


忘却°
15 声望0 粉丝