经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Vue.js » 查看文章
Vue源码学习(七):合并生命周期(混入Vue.Mixin)
来源:cnblogs  作者:养肥胖虎  时间:2023/9/20 9:32:02  对本文有异议

好家伙,

 

1.使用场景

现在来,来想一下,作为一个使用Vue的开发者,假设现在我们要使用created(),我们会如何使用

1.1.  .vue文件中使用

  1. <template>
  2. <div>
  3. <h1>{{ message }}</h1>
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. created() {
  9. this.message = 'Hello, created() in single file component!';
  10. },
  11. data() {
  12. return {
  13. message: ''
  14. };
  15. }
  16. };
  17. </script>

 

1.2.    Vue实例中使用

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Vue created() example</title>
  5. </head>
  6. <body>
  7. <div id="app">
  8. <h1>{{ message }}</h1>
  9. </div>
  10. <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
  11. <script>
  12. new Vue({
  13. el: '#app',
  14. data: {
  15. message: ''
  16. },
  17. created() {
  18. this.message = 'Hello, created() in Vue instance!';
  19. }
  20. });
  21. </script>
  22. </body>
  23. </html>

 

 

1.3.   混入

  1. Vue.Mixin({ //全局
  2. created:function a(){
  3. console.log('a----1')
  4. }
  5. })

 

那么如果我这样去定义

  1. <script>
  2. Vue.Mixin({ //全局
  3. created:function a(){
  4. console.log('a----1')
  5. }
  6. })
  7. Vue.Mixin({ //全局
  8. created:function b(){
  9. console.log('b----2')
  10. }
  11. })
  12. let vm = new Vue({
  13. el: '#app', //编译模板
  14. // data: {
  15. // },
  16. data() {
  17. // console.log(this)
  18. return {
  19. msg: 'hello',
  20. a: {
  21. b: 99
  22. },
  23. list: [1, 2, 3],
  24. arr: [{
  25. a: 1
  26. }]
  27. }
  28. },
  29. created(){
  30. console.log(555)
  31. }
  32. })
  33. </script>

是否会报错呢?

答案是不会

对于created()钩子函数,在每个Vue实例创建时,会依次执行全局混入函数中定义的created()方法和实例本身定义的created()方法。

当Vue实例被创建时,它会先执行全局混入函数的对应生命周期钩子函数,然后再执行实例本身的生命周期钩子函数。

因此,在你的代码中,全局混入函数中的created()会在实例的created()之前执行,且会按照它们在全局混入函数中的定义顺序执行

这样的设计允许开发者在多个地方定义相同的生命周期钩子函数,以实现不同的功能扩展和逻辑处理。

同时,由于生命周期钩子函数的执行顺序已经确定,开发者可以根据需要合理安排代码逻辑

 

最后,也说明,created()定义的方法被合并处理了,所以我们要把这个"合并"实现

 

 

2.项目上下文

老样子,先看看项目更新了哪些东西

代码已开源https://github.com/Fattiger4399/analytic-vue.git

 

 

2.1.Vue入口文件index.js中

添加全局方法

 

2.2. global-api/index.js

  1. import { mergeOptions } from "../utils/index"
  2. export function initGlobApi(Vue) {
  3. //源码
  4. //Vue.options ={created:[a,b,c],watch:{a,b}}
  5. Vue.options ={}
  6. Vue.Mixin = function (mixin) { // {}
  7. //源码
  8. //{created:[a,b,c],watch:[a,b]}
  9. //对象的合并
  10. console.log(999)
  11. this.options = mergeOptions(this.options,mixin)
  12. console.log(Vue.options,"||this is vue.options")
  13. }
  14. }

此处涉及我们的核心方法mergeOptions

 

这方法要实现一个怎么样的效果?

  1. Vue.Mixin({ //全局
  2. created: function a() {
  3. console.log('a----1')
  4. }
  5. })
  6. Vue.Mixin({ //全局
  7. created: function b() {
  8. console.log('b----2')
  9. }
  10. })
  11. let vm = new Vue({
  12. el: '#app', //编译模板
  13. // data: {
  14. // },
  15. data() {
  16. // console.log(this)
  17. return {
  18. msg: 'hello',
  19. a: {
  20. b: 99
  21. },
  22. list: [1, 2, 3],
  23. arr: [{
  24. a: 1
  25. }]
  26. }
  27. },
  28. created() {
  29. console.log(555)
  30. }
  31. })

将上述所有与created()有关的方法

最后合并到一个对象当中去

 

3.核心方法

3.1.utils/index.js

来到我们全篇最核心也是最难的部分

  1. //对象合并 {created:[]}
  2. export const HOOKS =[
  3. "beforeCreated",
  4. "created",
  5. "beforeMount",
  6. "mounted",
  7. "beforeUpdate",
  8. "updated",
  9. "beforeDestory",
  10. "destroyed",
  11. ]
  12. // 策略模式
  13. let starts ={}
  14. starts.data =function(parentVal,childVal){
  15. return childVal
  16. } //合并data
  17. starts.computed =function(){} //合并computed
  18. starts.watch =function(){} //合并watch
  19. starts.methods =function(){} //合并methods
  20. //遍历生命周期
  21. HOOKS.forEach(hooks=>{
  22. starts[hooks] = mergeHook
  23. })
  24. function mergeHook(parentVal,childVal){
  25. if(childVal){
  26. if(parentVal){
  27. //把子元素合并进去
  28. return parentVal.concat(childVal)
  29. }else{
  30. return [childVal] //[a]
  31. }
  32. }else{
  33. return parentVal
  34. }
  35. }
  36. export function mergeOptions(parent, child) {
  37. console.log(parent,child,'||this is parent and child in mergeOptions()')
  38. const options ={}
  39. //判断父亲
  40. for(let key in parent){
  41. console.log(key,'||this is key')
  42. mergeField(key)
  43. }
  44. //判断儿子
  45. for(let key in child){
  46. console.log(key,'||this is key')
  47. mergeField(key)
  48. }
  49. function mergeField(key){
  50. //根据key 策略模式
  51. if(starts[key]){ //created {created:[a]}
  52. options[key] =starts[key](parent[key],child[key])
  53. }else{
  54. options[key] = child[key]
  55. }
  56. }
  57. return options
  58. }

 

前端设计模式之策略模式 - 掘金 (juejin.cn)

这玩意要看懂,必须先把这玩意学了,策略模式

一句话概括策略模式是一种行为型设计模式,它允许在运行时根据不同的情境选择并应用不同的算法或行为(不是条件判断)

 

挖个坑,后面会补一章策略模式

 

  1. //对象合并 {created:[]}
  2. export const HOOKS =[
  3. "beforeCreated",
  4. "created",
  5. "beforeMount",
  6. "mounted",
  7. "beforeUpdate",
  8. "updated",
  9. "beforeDestory",
  10. "destroyed",
  11. ]
  12. // 策略模式
  13. let starts ={}
  14. starts.data =function(parentVal,childVal){
  15. return childVal
  16. } //合并data
  17. starts.computed =function(){} //合并computed
  18. starts.watch =function(){} //合并watch
  19. starts.methods =function(){} //合并methods
  20. //遍历生命周期
  21. HOOKS.forEach(hooks=>{
  22. starts[hooks] = mergeHook
  23. })
  24. function mergeHook(parentVal,childVal){
  25. if(childVal){
  26. if(parentVal){
  27. //把子元素合并进去
  28. return parentVal.concat(childVal)
  29. }else{
  30. return [childVal] //[a]
  31. }
  32. }else{
  33. return parentVal
  34. }
  35. }

这里定义常量HOOKS包含了一组生命周期钩子的名字

随后创建starts对象,用于存储各个不同属性的不同合并策略

至于mergeHook,这就是个简单的合并方法,不用多解释了

  1.  

再来看下半部分

  1. export function mergeOptions(parent, child) {
  2. console.log(parent,child,'||this is parent and child in mergeOptions()')
  3. const options ={}
  4. //判断父亲
  5. for(let key in parent){
  6. console.log(key,'||this is key')
  7. mergeField(key)
  8. }
  9. //判断儿子
  10. for(let key in child){
  11. console.log(key,'||this is key')
  12. mergeField(key)
  13. }
  14. function mergeField(key){
  15. //根据key 选择不同策略区处理
  16. if(starts[key]){ //created {created:[a]}
  17. options[key] =starts[key](parent[key],child[key])
  18. }else{
  19. options[key] = child[key]
  20. }
  21. }
  22. return options
  23. }
  1. mergeOptions将父项和子项合并成一个新的对象

    这个你真的得亲自上手调试一下



    3.2.init.js

  1. 这句就是将在option合并Vue.option中并返回给vm.$options
    (optionnew Vue时带的参数)

    最后,看看效果

    将方法都合并到了created

 

 

 

原文链接:https://www.cnblogs.com/FatTiger4399/p/17714856.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号