如果使用‘单文件组件’开发knockout

346 阅读4分钟
原文链接: blog.uproject.cn

    1、什么是单文件组件

    参见 vue 单文件组件

    2、如何在knockout中使用‘单文件组件’

    a. component

    b. createViewModal 加载器

     

    3、需要达成的目标

    <template>
     <div>
       <nodata params='title:"Hi,真不巧,网页走丢了…", desc:"不如返回首页,或者刷新网页试试吧。", btnHref:"/", btnText: "返回首页", img: noDataImg'></nodata>
     </div>
    </template>
    <script>
     define(["components/share/views/noData"],function (nodata) {
       return {
         viewModel: function () {
           this.noDataImg = require ('../assets/images/share/404.png')
         },
         components: {nodata}
       }
     })
    </script>
    <style lang="less" scoped rel="stylesheet/less" type="text/less">
       
    </style>

    4、如何修改

    a. 基于vue-loader做修改,kov-loader

    b. 提供一个具备解析功能的入口文件

    var Page = function (componentName, title, keywords, dataModel) {
           this.dataModel = ko.observable(dataModel || {});
           this.componentName = ko.observable(componentName || "blank");
           this.params = ko.observable({});
     
       }
       var page = new Page();
     
       var update = function (componentName, data, title, keywords, dataModel, template, params, restParams) {
           if (dataModel && (data.template || data.render)) {
               if (!ko.components.isRegistered(componentName)) {
                   if (dataModel && typeof dataModel === "function") {
                       dataModel.prototype.dispose = function () {
                           // 组件被移除之前, 调用distory
                           if (data.beforeDistory && typeof data.beforeDistory === "function") {
                               //data.beforeDistory(this);
                               data.beforeDistory.call(this);
                           }
                       }
                       if(dataModel.prototype.afterRender && !dataModel.prototype.koDescendantsComplete){
                           dataModel.prototype.koDescendantsComplete = dataModel.prototype.afterRender;
                       }
                   }
                   var finalTemplate = (data.template ? data.template : "" ) + (data.render ? data.render : "");   //  render 为template标签的内容, 如果template对象 和render对象都有内容 则合并,否则只取其一
                   ko.components.register(componentName, {
                       //viewModel: dataModel,
                       viewModel: {
                           createViewModel: function (params, componentInfo) {
                               var viewData = new dataModel(params, componentInfo);
                               //调用 beforeCreate
                               if (data.beforeCreate && typeof data.beforeCreate === "function") {
                                   data.beforeCreate.call(viewData);
                               }
                               return viewData;
                           }
                       },
                       template: finalTemplate
                   });
               }
           }
           page.dataModel(dataModel || {});
           page.componentName(componentName || defPage.blankComponent);
           page.params(params || {});
     
       }
     
       var pageInit = function (data, componentName, restParams) {
           // 针对 webpack1 或 2打包的结果分析data
           if (typeof data === "function") {
               data = data();
           }
           if (data["default"]) {
               data = data["default"];
           }
     
           update(componentName, data, data.title, data.keywords, data.viewModel, data.template, data.params, restParams);
     
       }