前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue 3 选项 API

Vue 3 选项 API

作者头像
公众号---人生代码
发布2020-11-26 10:26:10
2.6K0
发布2020-11-26 10:26:10
举报
文章被收录于专栏:人生代码人生代码

选项

data

类型:Function

详细:

其实我们经常使用到组件里面的数据,而这些数据是定义在 data 对象函数里面的,为什么要实现定义在 data 对象函数里面呢?在 data 对象函数中的数据,Vue 会对其进行响应式劫持,代理,使他们具有一修改就会相应地更新到页面上,也就是说这些数据是被监测着的。

实例创建之后,通过 vm.data 访问原始数据对象,组件实例也代理了 data 对象所有属性,因此你访问 vm.a 相当于访问 vm.data.a。

以 _ 或 开头的 property 不会被组件实例代理,因为它们可能和 Vue 内置的 property、API 方法冲突。你可以使用例如 vm.data._property 的方式访问这些 property。

接下来我们来看个例子,在 src/main.js,首先我们先要导入 Vue

代码语言:javascript
复制
import { createApp } from 'vue/dist/vue.esm-bundler.js'

为什么要从这个源码导入呢?因为如果用到 template 属性会报以下警告:

代码语言:javascript
复制
runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js". 
  at <App>
warn @ runtime-core.esm-bundler.js?5c40:38

我们在 data 中声明一个变量 a,不声明变量 b ,但是都在 template 模板使用,我们可以知道 a 可能会有数据,b 没有数据:

代码语言:javascript
复制
let app = createApp({
  template: `
    <div>在data中监测的数据a -- {{a}}</div>
    <div>不在data中监测的数据b --- {{b}}</div>
  `,
  data() {
    return {
      a: 1
    }
  }
})
app.use(store).use(router).mount('#app')

然后我们来给 app 添加个 b 属性:

代码语言:javascript
复制
app.b = 10

你会发现在控制台中会有警告:

代码语言:javascript
复制
runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Property "b" was accessed during render but is not defined on instance. 
  at <App>

props

类型:Array<string> | Object

详细:

props 可以是数组,也可以是对象,主要用于接收组件传递进来的,允许配置类型检测,设置默认值,自定义验证。

你可以基于对象的语法使用以下选项:

  • type:可以是下列原生构造函数中的一种:StringNumberBooleanArrayObjectDateFunctionSymbol、任何自定义构造函数、或上述内容组成的数组。会检查一个 prop 是否是给定的类型,否则抛出警告。Prop 类型的更多信息在此。
  • defaultany 为该 prop 指定一个默认值。如果该 prop 没有被传入,则换做用这个值。对象或数组的默认值必须从一个工厂函数返回
  • requiredBoolean 义该 prop 是否是必填项。在非生产环境中,如果这个值为 truthy 且该 prop 没有被传入的,则一个控制台警告将会被抛出。
  • validatorFunction 自定义验证函数会将该 prop 的值作为唯一的参数代入。在非生产环境下,如果该函数返回一个 falsy 的值 (也就是验证失败),一个控制台警告将会被抛出。你可以在这里查阅更多 prop 验证的相关信息。

我们在 src/main.js 基于以上代码继续加下面的代码:

代码语言:javascript
复制
import { createApp } from 'vue/dist/vue.esm-bundler.js'
// import App from './App.vue'
import router from './router'
import store from './store'
// let app = createApp(App)
let app = createApp({
  template: `
    <div>在data中监测的数据a -- {{a}}</div>
    <div>不在data中监测的数据b --- {{b}}</div>

    <props-demo-simple size="16" my-message="hahaja"></props-demo-simple>
    <props-demo-advanced :height="100" :age="100"></props-demo-advanced>
  `,
  data() {
    return {
      a: 1
    }
  }
})

app.b = 10


// 简单语法
app.component('props-demo-simple', {
  props: ['size', 'myMessage'],
  template: `<div>size --- {{size}}} --- myMessage --- {{myMessage}}</div>`,
})

// 对象语法,提供验证
app.component('props-demo-advanced', {
  props: {
    // 类型检查
    height: Number,
    // 类型检查 + 其他验证
    age: {
      type: Number,
      default: 0,
      required: true,
      validator: value => {
        return value >= 0
      }
    }
  },
  template: `<div>height is {{height}} -- age is {{age}}</div>`
})

/**
 * runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js". 
  at <App>
warn @ runtime-core.esm-bundler.js?5c40:38
 * */

/***
 * runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Property "b" was accessed during render but is not defined on instance. 
  at <App>
 * */ 

// console.log('appp====>', app)
app.use(store).use(router).mount('#app')


// app.component('my-component', {
//   template: `
//     <div>11111</div>
//   `,
// })




// app.config.optionMergeStrategies.custom = (toVal, fromVal) => {
//   console.log(fromVal, toVal)
//   // => "goodbye!", undefined
//   return fromVal || toVal
// }

// app.mixin({
//   custom: 'goodbye!',
//   created() {
//     console.log(this.$options.custom) // => "hello!"
//   }
// })

computed

  • 类型:{ [key: string]: Function | { get: Function, set: Function } }

详细

计算属性将被混入到组件实例中。所有 getter 和 setter 的 this 上下文自动地绑定为组件实例。

注意,如果你为一个计算属性使用了箭头函数,则 this 不会指向这个组件的实例,不过你仍然可以将其实例作为函数的第一个参数来访问。

计算属性的结果会被缓存,除非依赖的响应式 property 变化才会重新计算。注意,如果某个依赖 (比如非响应式 property) 在该实例范畴之外,则计算属性是不会被更新的。

继续在 src/main.js 加代码:

代码语言:javascript
复制
import { createApp } from 'vue/dist/vue.esm-bundler.js'
// import App from './App.vue'
import router from './router'
import store from './store'
// let app = createApp(App)
let app = createApp({
  template: `
    <div>在data中监测的数据a -- {{a}}</div>
    <div>不在data中监测的数据b --- {{b}}</div>

    <props-demo-simple size="16" my-message="hahaja"></props-demo-simple>
    <props-demo-advanced :height="100" :age="100"></props-demo-advanced>
  `,
  data() {
    return {
      a: 1
    }
  },
  computed: {
    // 仅仅读取
    aDouble() {
      return this.a * 2
    },
    // 既设置有读取
    aPlus: {
      get() {
        return this.a
      },
      set(val) {
        this.a = this.a + val
      }
    }
  }
})

app.b = 10


// 简单语法
app.component('props-demo-simple', {
  props: ['size', 'myMessage'],
  template: `<div>size --- {{size}}} --- myMessage --- {{myMessage}}</div>`,
})

// 对象语法,提供验证
app.component('props-demo-advanced', {
  props: {
    // 类型检查
    height: Number,
    // 类型检查 + 其他验证
    age: {
      type: Number,
      default: 0,
      required: true,
      validator: value => {
        return value >= 0
      }
    }
  },
  template: `<div>height is {{height}} -- age is {{age}}</div>`
})

/**
 * runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js". 
  at <App>
warn @ runtime-core.esm-bundler.js?5c40:38
 * */

/***
 * runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Property "b" was accessed during render but is not defined on instance. 
  at <App>
 * */ 

// console.log('appp====>', app)
const vm = app.use(store).use(router).mount('#app')

console.log(vm.aPlus) // 1
vm.aPlus = 3
console.log(vm.a) // 4
console.log(vm.aDouble) // 8 
// app.component('my-component', {
//   template: `
//     <div>11111</div>
//   `,
// })




// app.config.optionMergeStrategies.custom = (toVal, fromVal) => {
//   console.log(fromVal, toVal)
//   // => "goodbye!", undefined
//   return fromVal || toVal
// }

// app.mixin({
//   custom: 'goodbye!',
//   created() {
//     console.log(this.$options.custom) // => "hello!"
//   }
// })

methods

  • 类型:{ [key: string]: Function }

详细

methods 将被混入到组件实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的 this 自动绑定为组件实例。

注意
  • 注意,不应该使用箭头函数来定义 method 函数 (例如 plus:() => this.a++)。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向组件实例,this.a 将是 undefined。

继续在 src/main.js 加入代码:

代码语言:javascript
复制
import { createApp } from 'vue/dist/vue.esm-bundler.js'
// import App from './App.vue'
import router from './router'
import store from './store'
// let app = createApp(App)
let app = createApp({
  template: `
    <div>在data中监测的数据a -- {{a}}</div>
    <div>不在data中监测的数据b --- {{b}}</div>

    <props-demo-simple size="16" my-message="hahaja"></props-demo-simple>
    <props-demo-advanced :height="100" :age="100"></props-demo-advanced>
  `,
  data() {
    return {
      a: 1
    }
  },
  computed: {
    // 仅仅读取
    aDouble() {
      return this.a * 2
    },
    // 既设置有读取
    aPlus: {
      get() {
        return this.a
      },
      set(val) {
        this.a = this.a + val
      }
    }
  },
  methods: {
    plus() {
      console.log(this.a + 1)
    }
  }
})

app.b = 10


// 简单语法
app.component('props-demo-simple', {
  props: ['size', 'myMessage'],
  template: `<div>size --- {{size}}} --- myMessage --- {{myMessage}}</div>`,
})

// 对象语法,提供验证
app.component('props-demo-advanced', {
  props: {
    // 类型检查
    height: Number,
    // 类型检查 + 其他验证
    age: {
      type: Number,
      default: 0,
      required: true,
      validator: value => {
        return value >= 0
      }
    }
  },
  template: `<div>height is {{height}} -- age is {{age}}</div>`
})

/**
 * runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js". 
  at <App>
warn @ runtime-core.esm-bundler.js?5c40:38
 * */

/***
 * runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Property "b" was accessed during render but is not defined on instance. 
  at <App>
 * */ 

// console.log('appp====>', app)
const vm = app.use(store).use(router).mount('#app')

console.log(vm.aPlus) // 1
vm.aPlus = 3
console.log(vm.a) // 4
console.log(vm.aDouble) // 8 
// app.component('my-component', {
//   template: `
//     <div>11111</div>
//   `,
// })

vm.plus()



// app.config.optionMergeStrategies.custom = (toVal, fromVal) => {
//   console.log(fromVal, toVal)
//   // => "goodbye!", undefined
//   return fromVal || toVal
// }

// app.mixin({
//   custom: 'goodbye!',
//   created() {
//     console.log(this.$options.custom) // => "hello!"
//   }
// })

watch

  • 类型:{ [key: string]: string | Function | Object | Array}

详细

一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。组件实例将会在实例化时调用 watch(),参阅 watch,了解更多关于 deep、immediate 和 flush 选项的信息。

代码语言:javascript
复制
import { createApp } from 'vue/dist/vue.esm-bundler.js'
// import App from './App.vue'
import router from './router'
import store from './store'
// let app = createApp(App)
let app = createApp({
  template: `
    <div>在data中监测的数据a -- {{a}}</div>
    <div>不在data中监测的数据b --- {{b}}</div>

    <props-demo-simple size="16" my-message="hahaja"></props-demo-simple>
    <props-demo-advanced :height="100" :age="100"></props-demo-advanced>
  `,
  data() {
    return {
      a: 1,
      b: {
        name: 'haha'
      }
    }
  },
  computed: {
    // 仅仅读取
    aDouble() {
      return this.a * 2
    },
    // 既设置有读取
    aPlus: {
      get() {
        return this.a
      },
      set(val) {
        this.a = this.a + val
      }
    }
  },
  methods: {
    plus() {
      console.log(this.a + 1)
    },
    someMethod() {
      console.log("b发生变化了")
    }
  },
  watch: {
    b: 'someMethod',
    b: {
      handler(val, oldVal) {
        console.log(val, oldVal)
      },
      deep: true,
      immediate: true
    }
  }
})

app.b = 10


// 简单语法
app.component('props-demo-simple', {
  props: ['size', 'myMessage'],
  template: `<div>size --- {{size}}} --- myMessage --- {{myMessage}}</div>`,
})

// 对象语法,提供验证
app.component('props-demo-advanced', {
  props: {
    // 类型检查
    height: Number,
    // 类型检查 + 其他验证
    age: {
      type: Number,
      default: 0,
      required: true,
      validator: value => {
        return value >= 0
      }
    }
  },
  template: `<div>height is {{height}} -- age is {{age}}</div>`
})

/**
 * runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js". 
  at <App>
warn @ runtime-core.esm-bundler.js?5c40:38
 * */

/***
 * runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Property "b" was accessed during render but is not defined on instance. 
  at <App>
 * */ 

// console.log('appp====>', app)
const vm = app.use(store).use(router).mount('#app')

console.log(vm.aPlus) // 1
vm.aPlus = 3
console.log(vm.a) // 4
console.log(vm.aDouble) // 8 
// app.component('my-component', {
//   template: `
//     <div>11111</div>
//   `,
// })

vm.plus()

vm.b.name = "Ken, 人生代码"

// app.config.optionMergeStrategies.custom = (toVal, fromVal) => {
//   console.log(fromVal, toVal)
//   // => "goodbye!", undefined
//   return fromVal || toVal
// }

// app.mixin({
//   custom: 'goodbye!',
//   created() {
//     console.log(this.$options.custom) // => "hello!"
//   }
// })

emits

  • 类型:Array<string> | Object

详细

emits 可以是数组或对象,从组件触发自定义事件,emits 可以是简单的数组,或者对象作为替代,允许配置和事件验证。

在对象语法中,每个 property 的值可以为 null 或验证函数。验证函数将接收传递给 emit 调用的其他参数。如果 this.emit('foo',1) 被调用,foo 的相应验证函数将接收参数 1。验证函数应返回布尔值,以表示事件参数是否有效。

代码语言:javascript
复制
import { createApp } from 'vue/dist/vue.esm-bundler.js'
// import App from './App.vue'
import router from './router'
import store from './store'
// let app = createApp(App)
let app = createApp({
  template: `
    <div>在data中监测的数据a -- {{a}}</div>
    <div>不在data中监测的数据b --- {{b}}</div>

    <props-demo-simple size="16" my-message="hahaja"></props-demo-simple>
    <props-demo-advanced :height="100" :age="100"></props-demo-advanced>
  `,
  data() {
    return {
      a: 1,
      b: {
        name: 'haha'
      }
    }
  },
  computed: {
    // 仅仅读取
    aDouble() {
      return this.a * 2
    },
    // 既设置有读取
    aPlus: {
      get() {
        return this.a
      },
      set(val) {
        this.a = this.a + val
      }
    }
  },
  methods: {
    plus() {
      console.log(this.a + 1)
    },
    someMethod() {
      console.log("b发生变化了")
    }
  },
  watch: {
    b: 'someMethod',
    b: {
      handler(val, oldVal) {
        console.log(val, oldVal)
      },
      deep: true,
      immediate: true
    }
  }
})

app.b = 10


// 简单语法
app.component('props-demo-simple', {
  props: ['size', 'myMessage'],
  template: `<div>size --- {{size}}} --- myMessage --- {{myMessage}}</div>`,
})

// 对象语法,提供验证
app.component('props-demo-advanced', {
  props: {
    // 类型检查
    height: Number,
    // 类型检查 + 其他验证
    age: {
      type: Number,
      default: 0,
      required: true,
      validator: value => {
        return value >= 0
      }
    }
  },
  template: `<div>height is {{height}} -- age is {{age}}</div>`
})

// 数组语法
app.component('todo-item', {
  emits: ['check'],
  created() {
    this.$emit('check')
  }
})

// 对象语法
app.component('reply-form', {
  emits: {
    // 没有验证函数
    click: null,

    // 带有验证函数
    submit: payload => {
      if (payload.email && payload.password) {
        return true
      } else {
        console.warn(`Invalid submit event payload!`)
        return false
      }
    }
  }
})

/**
 * runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js". 
  at <App>
warn @ runtime-core.esm-bundler.js?5c40:38
 * */

/***
 * runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Property "b" was accessed during render but is not defined on instance. 
  at <App>
 * */ 

// console.log('appp====>', app)
const vm = app.use(store).use(router).mount('#app')

console.log(vm.aPlus) // 1
vm.aPlus = 3
console.log(vm.a) // 4
console.log(vm.aDouble) // 8 
// app.component('my-component', {
//   template: `
//     <div>11111</div>
//   `,
// })

vm.plus()

vm.b.name = "Ken, 人生代码"

// app.config.optionMergeStrategies.custom = (toVal, fromVal) => {
//   console.log(fromVal, toVal)
//   // => "goodbye!", undefined
//   return fromVal || toVal
// }

// app.mixin({
//   custom: 'goodbye!',
//   created() {
//     console.log(this.$options.custom) // => "hello!"
//   }
// })
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-11-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CryptoCode 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 选项
    • data
    • props
    • computed
    • methods
      • 注意
      • watch
      • emits
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档