Vue 构造选型 options 进阶属性

简介: Vue 构造选型 options 进阶属性

1、构造选项 options

options 是创建 vue 实例时的参数,具体可以查看 选项官方文档,options 内含 五大类 属性:


数据:data、props、propsData、computed、methods、watch

DOM:el、template、render、renderError

生命周期钩子:beforeCreate/created、beforeMount/mounted、beforeUpdate/updated、activated/deactivated、beforeDestroy/destroyed、errorCaptured

资源:directives、filters、components

组合:parent、mixins、extends、provide、inject


红色代表基础重要属性,黄色代表高级重要属性,紫色代表特殊的重要属性,其余的到官网做一些了解即可。关于 Vue 的 options 选项的基础重要属性,可以参考这篇 博客。下面重要说一下 Vue 的 options 选项的高级重要属性:

2、computed 属性 - 计算属性

计算属性实为方法,但是可以被当作属性使用,它是根据其他属性计算而来的结果,使用的时候不需要加括号,Vue 会自动读取该函数的返回值,它会根据依赖是否变化来缓存。官网示例 如下:

<div id="example">
  <p>Original message: "{{ message }}"</p>    <!--Hello-->
  <p>Computed reversed message: "{{ reversedMessage }}"</p>    <!--olleH-->
</div>
<script>
  var vm = new Vue({
    el: '#example',
    data: { message: 'Hello' },
    computed: {  
      reversedMessage: function () {//计算属性的getter,要设置getter和setter则reversedMessage{ get(),set() }
        return this.message.split('').reverse().join('');   // `this` 指向 vm 实例
      }
    }
  })
</script>

在 reversedMessage 计算属性中,我们提供的函数将用作属性 vm.reversedMessage 的 getter 函数,用户可以打开浏览器的控制台,自行修改例子中的 vm。 vm.reversedMessage 的值始终取决于 vm.message 的值。


计算属性有缓存,如果依赖的属性没有变化,就不会重新计算。getter/setter 默认不会做缓存,Vue 做了特殊处理。

3、watch 属性 - 侦听/监听

当 Vue 实例上的 data 数据发生时,执行一个函数监听可以完美实现一个撤销历史数据的功能。

注意:watch 是异步的,等对应的操作都执行完了,才会去执行 watch 监听。$nextTick()

undo (){
    this.inUndoMode = true;  //撤销模式进行如下操作
    this.n = old;            //watch 是异步的
    this.$nextTick(() => {    //类似setTimeout(),在异步watch执行之后再执行
        this.inUndoMode = false;  //撤销操作被监听到后,将撤销模式置为 false
    },0)
}

注意:watch 有一个 immediate 属性。当 data 数据第一次创建到页面渲染的过程是不会被监听的,它认为数据从无到有的过程不算是真正意义上的数据改变的过程,如果想让 watch 监听数据从无到有的过程,则需要 immediate 属性:

watch:{               //如果是一级属性的话:user(){}、二级:'user.email'(){}
    'user.email':{    //如果要监听this.user.email从无到有的过程,则需将函数切换为对象{}
        handler(){    //将数据变化后的操作放到 handler(){} 中、 并设置 immediate 属性
            const { user:{ email, nickname, phone}} = this;  //结构赋值
            this. displayName = nickname || email || phone;
        },
        immediate: true;    //监听this.user.email数据从无到有的过程
    }
}

注意:watch 还有一个 deep 属性。在 Vue 的 data 内部数据中,有的可能是对象类型,比如下面示例,当改变 animal.name 的值时,监听的 animal 的函数并不会执行,因为 animal 的内存地址没变,Vue 就认为 animal 属性没有发生变化。如果希望内部属性变化也要 watch 监听到,则需要设置 deep 属性。

data: {
    num: 1,    //boolean类型
    animal: {  //对象类型
        name: '二哈'
    }
},
watch: {
    num(){ console.log( "num 变了"); },    //设置 this.num=2,就会执行该监听函数
    //animal(){ console.log( "animal 变了"); }, //设置 this.animal = { name: '二哈' }会执行这行(对象地址变了)
    animal:{
        handler(){ console.log( "animal 变了"); },
        deep: true    //表示,animal对象的内部属性变化也会触发animal的watch,有了它就不需要挨个监听其内部属性了
    },
    "animal.name": function(){ console.log("animal.name变了"); } //执行this.animal.name='金毛'会执行该监听函数
}                                                            //但是上一条并不会执行,因为Vue认为animal属性没变

补充:Vue 的默认设置是,如果给 Vue 中的对象类型的 data 数据原封不动的赋值给它,Vue 就会认为该对象变了,但内部属性没变。如果只改变对象类型数据的内部属性,则 Vue 认为该对象没变,就不会执行监听函数操作。如果希望 Vue 监听到对象类型数据的内部属性变化,也认定为该对象也变化了,可以设置 deep 属性。


补充:watch:{} 属性中的监听函数不能使用 ()=> {} 箭头函数,可用 n:function(){} 的形式,或 n(){} 的形式等。因为箭头函数中的 this 是全局对象,不是指 vm 实例对象。

//语法 1
watch: {
    o1: () => {},    //别用这种,这里的this是全局对象
    o2: function(value,oldValue){},
    o3(){},
    o4: [ fun1,fun2 ],    //这里的函数是在 methods 中声明好的
    o5: 'methodName',
    o6: { handler: fun, deep: true, immediate: true },
    'object.a': function(){}    //监听对象类型数据的内部属性
}
//语法 2 - 在 vue 实例的 options 之外使用这种方式:
vm.$watch('xxx', fun, {deep: .., immediate: ..}    //监听 xxx
//或者在 created() 钩子中使用下面这种形式
created(){
    this.$watch('xxx', fun, {deep: .., immediate: ..}    //监听 xxx
}

4、directives 属性 - 指令

我们在使用 Vue 的时候基本上不会涉及到 DOM 操作,但是有的情况下,开发人员仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令,将 DOM 操作封装成一个 directive 指令,让它来进行原生 DOM 操作。


Vue 提供了很多内置指令,一般是以 v- 开头,比如: v-if/v-for/v-bind/v-on 都是指令,除了这些之外,用户还可以自定义指令,感兴趣的话可以参考 Vue 官方文档,下面我们自己创建一个指令,创建方式又有两种:

//一、声明一个全局指令 - 可在项目中任意组件内标签使用
Vue.directive('x', directiveOptions)     //1、指令名、2、指令选项    声明后可在任何组件的标签上用 v-x 指令
Vue.directive('x', {
    inserted: function(el){    //inserted 当被绑定的元素 el 插入到 DOM 中时……    使用:<div v-x>click</div>
        el.addEventListener('click',()=>{console.log('xxx')})
    }
})
//二、声明一个局部指令 - 仅限组件内标签使用
new Vue({
    ···,
    directives: { "x": directiveOptions }  //v-x只能用在该实例中
})
new Vue({
    ···,
    directives: {
        "x": inserted: function(el){    //inserted 当被绑定的元素 el 插入到 DOM 中时……    仅限组件内便签使用
            el.addEventListener('click',()=>{console.log('xxx')})
        }
    }
})

一个指令定义对象可以提供如下几个钩子函数 (均为可选):(1) bind - 类似created、(2) inserted - 类似mounted、(3) update -  类似updated、(4) componentUpdated、(5) unbind - 类似 destroyed。具体可查看 Vue 官方文档 ,模仿 v-on 例子


指令的作用:Vue 的实例或组件主要封装了对数据绑定、事件监听、DOM操作的一些函数,这个 directive 指令属性主要的目的就是封装一些需要的原生 DOM 操作。开发人员可以将某个经常用到的或复杂的 DOM 操作封装为指令,以减少重复 DOM 操作。

5、mixins 属性 - 混入

mixins 混入说白了就是复制,即将别的组件的构造选项复制到另一个组件中,这样可以减少重复性。比如你在工作中需要开发五个组件,这五个组件中需要同样的 data、methods 等构造选项,那你不需要在五个组件中分别写上同样的 data/ methods,而是使用 mixins 属性。类比 directives 指令,directives 的作用是减少 DOM 操作的重复,mixins 的作用是减少 data、methods、钩子的重复。附上 Vue 官方文档


mixins 选项接收一个混入对象的数组。这些混入对象可以像正常的实例对象一样包含实例选项,这些选项将会被合并到最终的选项中,使用的是和 Vue.extend() 一样的选项合并逻辑。也就是说,如果你的混入包含一个 created 钩子,而创建组件本身也有一个,那么两个函数都会被调用。


Mixin 钩子按照传入顺序依次调用,并在调用组件自身的钩子 之前 被调用。

// 一般会在项目中新建一个 mixins/log.js 文件,用来些需要混入到组件中的代码
export default log = {
  data(){ return { num: 1 }}
  created: function () { console.log(num) }
}
// 在需要使用混入文件的组件中需要引入,并将其传入到 mixins 构造选项中
import log from './mixins/log.js'
var vm = new Vue({
  created: function () { console.log(2) },
  mixins: [log]
})
// => 1        Mixin 钩子按照传入顺序依次调用,并在调用组件自身的钩子之前被调用。
// => 2

上述这种方式是相当于局部添加 mixins 功能,除此之外还可以使用 Vue.mixins({ }) 来设置全局混入,这样在全局中的组件中不需要手动 mixins 引入,每个组件自动具备全局混入的属性,但是 不推荐 这种使用方式。

6、extend 属性 - 继承

如上同样的需求:你在工作中需要开发五个组件,这五个组件中需要同样的 data、methods 等构造选项,那你不需要在五个组件中分别写上同样的 data/ methods,而是使用 mixins 属性。除了使用 mixins 之外还可以使用 extends 属性。官方文档

<div id="mount-point"></div>
// 创建构造器,Profile.js,然后将 Profile export 出去
var Profile = Vue.extend({
  template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
  data: function () {    //这里也可以用mixins属性
    return {
      firstName: 'Walter',
      lastName: 'White',
      alias: 'Heisenberg'                        //或者在其他组件中导入,通过extends使用
    }                                            import Profile from './Profile.js'
  }                                              export default {
})                                                   data: ...,
// 创建 Profile 实例,并挂载到一个元素上。              extends: Profile
new Profile().$mount('#mount-point')             }

个人感觉 extends 是比 mixins 更抽象一点的封装,如果你嫌写五次 mixins 麻烦,可考虑 extends 一次。

7、provide/inject - 提供/注入

procide/inject  这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。关于 procide/inject 的 Vue 官方文档


provide 选项应该是一个对象或返回一个对象的函数,该对象包含可注入其子孙的属性。

// 祖级组件提供 'color' 属性及改变该属性的函数 'change'
export default {
    name: 'app',
    data(){
        return { color: bule }
    },
    methods:{
        change(){ this.color = red; }
    }
    provide(){    //将自身组件中的 color 复制一份提供给其他组件
        return {
            colorName: this.color,      //提供给别的组件的属性,别的组件不能擅自做修改
            colorChange: this.change    //需要再提供一个改变该属性的函数给其他组件
        }
    }
}
// 子孙级组件注入 'color'、'change'
//<div @click='usechange'>当前颜色为:{{colorName}}</div>
export default {
    inject: ['colorName', 'colorChange'],    //接收祖先组件提供的属性和方法
    methods: {
        usechange(){
            this.colorChange()    //调用祖先组件提供的方法改变祖先组件提供的属性值
        }
    }
}

如果你觉得使用这种调用父级组件中的方法改变父级组件中的属性的方式比较麻烦的话,你可以在父级组件中的 provide() 中直接将要传递给子组件的属性设置为一个对象,比如:`colorName:{value:this.color}` 的形式,这样子组件就可以直接通过 ` this.colorName.value = "red" ` 即可。


注意:但是这种方式不推荐使用,不能只传 colorName属性 不传 colorChange 函数,因为 colorName 的值是被复制给provide 的。如果上述这种通过引用的方式传递属性,则容易失控。

目录
相关文章
|
18天前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
152 2
|
4月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
584 0
|
4月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
3月前
|
JavaScript 安全
在 Vue 中,如何在回调函数中正确使用 this?
在 Vue 中,如何在回调函数中正确使用 this?
121 0
|
3月前
|
人工智能 JSON JavaScript
VTJ.PRO 首发 MasterGo 设计智能识别引擎,秒级生成 Vue 代码
VTJ.PRO发布「AI MasterGo设计稿识别引擎」,成为全球首个支持解析MasterGo原生JSON文件并自动生成Vue组件的AI工具。通过双引擎架构,实现设计到代码全流程自动化,效率提升300%,助力企业降本增效,引领“设计即生产”新时代。
258 1
|
4月前
|
JavaScript 前端开发 开发者
Vue 自定义进度条组件封装及使用方法详解
这是一篇关于自定义进度条组件的使用指南和开发文档。文章详细介绍了如何在Vue项目中引入、注册并使用该组件,包括基础与高级示例。组件支持分段配置(如颜色、文本)、动画效果及超出进度提示等功能。同时提供了完整的代码实现,支持全局注册,并提出了优化建议,如主题支持、响应式设计等,帮助开发者更灵活地集成和定制进度条组件。资源链接已提供,适合前端开发者参考学习。
379 17
|
4月前
|
JavaScript 前端开发 UED
Vue 表情包输入组件实现代码及详细开发流程解析
这是一篇关于 Vue 表情包输入组件的使用方法与封装指南的文章。通过安装依赖、全局注册和局部使用,可以快速集成表情包功能到 Vue 项目中。文章还详细介绍了组件的封装实现、高级配置(如自定义表情列表、主题定制、动画效果和懒加载)以及完整集成示例。开发者可根据需求扩展功能,例如 GIF 搜索或自定义表情上传,提升用户体验。资源链接提供进一步学习材料。
215 1
|
4月前
|
存储 JavaScript 前端开发
如何高效实现 vue 文件批量下载及相关操作技巧
在Vue项目中,实现文件批量下载是常见需求。例如文档管理系统或图片库应用中,用户可能需要一次性下载多个文件。本文介绍了三种技术方案:1) 使用`file-saver`和`jszip`插件在前端打包文件为ZIP并下载;2) 借助后端接口完成文件压缩与传输;3) 使用`StreamSaver`解决大文件下载问题。同时,通过在线教育平台的实例详细说明了前后端的具体实现步骤,帮助开发者根据项目需求选择合适方案。
329 0
|
4月前
|
JavaScript 前端开发 UED
Vue 项目中如何自定义实用的进度条组件
本文介绍了如何使用Vue.js创建一个灵活多样的自定义进度条组件。该组件可接受进度段数据数组作为输入,动态渲染进度段,支持动画效果和内容展示。当进度超出总长时,超出部分将以红色填充。文章详细描述了组件的设计目标、实现步骤(包括props定义、宽度计算、模板渲染、动画处理及超出部分的显示),并提供了使用示例。通过此组件,开发者可根据项目需求灵活展示进度情况,优化用户体验。资源地址:[https://pan.quark.cn/s/35324205c62b](https://pan.quark.cn/s/35324205c62b)。
141 0
|
6月前
|
JavaScript
vue实现任务周期cron表达式选择组件
vue实现任务周期cron表达式选择组件
785 4