欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue遠程加載sfc組件思路詳解

 更新時間:2019年12月25日 09:23:25   作者:步道者  
這篇文章主要介紹了vue遠程加載sfc組件思路詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

問題

在我們的 vue 項目中(特別是后臺系統(tǒng)),總會出現(xiàn)一些需要多業(yè)務線共同開發(fā)同一個項目的場景,如果各業(yè)務團隊向項目中提供一些公共業(yè)務組件,但是這些組件并不能和項目一起打包,因為項目中不能因為某個私有模塊的頻繁變更而重復構建發(fā)布。

^_^不建議在生產環(huán)境使用,代碼包含eval 

思路

在這種場景下我們需要將公共的業(yè)務組件部署到服務端,由客戶端請求并渲染組件。

服務端解析.vue文件

使用vue-template-compiler 模板解析器,解析SFC(單文件組件)

const compile = require('vue-template-compiler')

// 獲取sfc組件的源碼
const str = fs.readFileSync(path.resolve(__dirname, `../components/sfc.vue`), 'utf-8')

// vue-loader內置,現(xiàn)在用來解析SFC(單文件組件)
let sfc = compile.parseComponent(str)

// 獲取sfc組件配置
let sfcOptions = getComponentOption(sfc)

getComponentOption 獲取sfc組件配置

import { uuid } from 'utilscore'
import stylus from 'stylus'
import sass from 'sass'
import less from 'less'
const getComponentOption = sfc => {
  // 生成data-u-id 
  const componentId = uuid(8, 16).toLocaleLowerCase()  
  // 標簽添加data-u-id屬性  
  const template = sfc.template ? tagToUuid(sfc.template.content, componentId) : ''  
  // 轉化style(less、sass、stylus)  
  let styles = []  
  sfc.styles.forEach(sty => {    
    switch (sty.lang) {      
      case 'stylus':        
        stylus.render(sty.content, (err, css) => styles.push(formatStyl(sty, css, componentId)))        
        break;      
      case 'sass':      
      case 'scss':        
        styles.push(formatStyl(sty, sass.renderSync({ data: sty.content }).css.toString(), componentId))        
        break;      
      case 'less':        
        less.render(sty.content, (err, css) => styles.push(formatStyl(sty, css, componentId)))        
        break;    
    }  
  })  
  let options = {    
    script: sfc.script ? $require(null, sfc.script.content) : {},    
    styles,    
    template  
  }  
  return JSON.stringify(options, (k, v) => {
    if(typeof(v) === 'function') {
      let _fn = v.toString()
      return /^function()/.test(_fn) ? _fn : fn.replace(/^/,'function ')
    }
    return v
  })
}

tagToUuid  給template 中的標簽追加data-u-id 

const tagToUuid = (tpl, id) => {  
  var pattern = /<[^\/]("[^"]*"|'[^']*'|[^'">])*>/g  
  return tpl.replace(pattern, $1 => {    
    return $1.replace(/<([\w\-]+)/i, ($2, $3) => `<${$3} data-u-${id}`)  
  })
}

formatStyl 處理樣式的scoped

const formatStyl = (sty, css, componentId) => {  
  let cssText = css  
  if (sty.scoped) {    
    cssText = css.replace(/[\.\w\>\s]+{/g, $1 => {      
    if (/>>>/.test($1)) return $1.replace(/\s+>>>/, `[data-u-${componentId}]`)      
    return $1.replace(/\s+{/g, $2 => `[data-u-${componentId}]${$2}`)    
    })  
  }  
  return cssText
}

$require 執(zhí)行其中的的 JavaScript 代碼,并返回值

const $require = (filepath, scriptContext) => {
  const filename = path.resolve(__dirname, `../${filepath}`);  
  const module = { exports: {} }  
  let code = scriptContext ? scriptContext : fs.readFileSync(filename, 'utf-8')  
  let exports = module.exports  
  code = `(function($require,module,exports,__dirname,filename){$[code]})($require,module,exports,__dirname,filename)`  
  eval(code)  
  return module.exports
} 

客戶端請求組件并渲染

封裝前端遠程組件-remote.vue

<template> 
  <component :is="remote" v-bind="$attrs" v-on="$listeners"></component>
</template>
<script>
import Vue from "vue";
export default { 
  data() {  
    return {   
      remote: null  
    }
  }, 
  props: {  
    tagName: {   
      type: String,   
      defualt: "componentName"  
    } 
  }, 
  created() {  
    fetch("http://localhost:3000/getComponent/"+this.tagName)
      .then(res => res.json())   
      .then(sfc => {    
        let options = this.parseObj(sfc);    
        options.styles.forEach(css => this.appendSty(css));    
        this.remote = Vue.extend({ 
          ...options.script,     
          name: options.script.name || this.tagName,     
          template: options.template    
        });   
      }); 
   }, 
   methods: {  
    isObject(v) {   
      return Object.prototype.toString.call(v).includes("Object");  
    },  
    parseObj(data) {   
      if (Array.isArray(data)) return data.map(row => this.parseObj(row));   
      if (this.isObject(data)) {    
        let ret = {};    
        for (let k in data) {     
          ret[k] = this.parseObj(data[k]);    
         }    return ret;   
      }   
      try {    
        let pattern = /function ([\w]+)\(\) \{ \[native code\] \}/;    
        if (pattern.test(data)) {     
          return window[pattern.exec(data)[1]];    
        } else {     
          let evalData = eval(`(${data})`);     
          return typeof evalData == "function" ? evalData : data;    
        }   
      } catch (err) {    
        return data;   
      }  
    },  
    appendSty(css) { // 生成組件樣式   
      let style = document.createElement("style");   
      style.setAttribute("type", "text/css");   
      var cssText = document.createTextNode(css);   
      style.appendChild(cssText);   
      var head = document.querySelector("head");   
      head.appendChild(style);  
    } 
}};
</script>

遠程組件實踐

服務端sfc組件,注意javascript塊要使用module.exports導出,引入腳本使用$require

<template> 
  <div class="test">  
    <div>   
      <p @click='$emit("handleClick",'點我')'>遠程組件--{{msg}}--{{text}}</p>  
      </div> 
    </div>
</template>
<script>
// 加載js腳本
let {a} = $require('utils/test.js') 
module.exports = { 
  data: function() {  
    return {   
      msg: "remote component",
      ...a,
    } 
  }, 
  props: {  
    text: {   
      type: Boolean,   
      default: true  
    } 
  },
  mounted:function(){
    console.log('prop text is',this.text)
  }
};
</script>
<style lang="stylus" scoped>
.test { 
  .test2 {  
     color: red; 
  } 
  p{  
     color:red 
  }
}
</style>

客戶端渲染

// temolate
<remote text='123456' @handleClick='handleClick'/>

// script 
methods:{
 handleClick(v){
   console.log(v) // 點我 }
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:

相關文章

  • vue中formdata傳值給后臺時參數(shù)為空的問題

    vue中formdata傳值給后臺時參數(shù)為空的問題

    這篇文章主要介紹了vue中formdata傳值給后臺時參數(shù)為空的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • vue 使用Jade模板寫html,stylus寫css的方法

    vue 使用Jade模板寫html,stylus寫css的方法

    這篇文章主要介紹了vue 使用Jade模板寫html,stylus寫css的方法,文中還給大家提到了使用jade注意事項,需要的朋友可以參考下
    2018-02-02
  • vue項目中vue-i18n和element-ui國際化開發(fā)實現(xiàn)過程

    vue項目中vue-i18n和element-ui國際化開發(fā)實現(xiàn)過程

    這篇文章主要介紹了vue項目中vue-i18n和element-ui國際化開發(fā)實現(xiàn)過程,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2018-04-04
  • Vuex actions?異步操作方法詳解

    Vuex actions?異步操作方法詳解

    這篇文章主要介紹了Vuex actions?異步操作方法,需要的朋友可以參考下
    2023-10-10
  • 如何解決Vue3組合式API模式下動態(tài)組件不渲染問題

    如何解決Vue3組合式API模式下動態(tài)組件不渲染問題

    這篇文章主要介紹了如何解決Vue3組合式API模式下動態(tài)組件不渲染問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教<BR>
    2024-03-03
  • 拿來即用的vue旋轉木馬組件demo

    拿來即用的vue旋轉木馬組件demo

    這篇文章主要為大家介紹了拿來即用的vue旋轉木馬組件demo詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • vue實現(xiàn)拖拽或點擊上傳圖片

    vue實現(xiàn)拖拽或點擊上傳圖片

    這篇文章主要為大家詳細介紹了vue實現(xiàn)拖拽或點擊上傳圖片,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Vue實現(xiàn)天氣預報小應用

    Vue實現(xiàn)天氣預報小應用

    這篇文章主要為大家詳細介紹了Vue實現(xiàn)天氣預報小應用,查詢一些城市的天氣情況,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • VUEX-action可以修改state嗎

    VUEX-action可以修改state嗎

    這篇文章主要介紹了VUEX-action可以修改state嗎,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-11-11
  • vue中__ob__:?Observer的踩坑記錄

    vue中__ob__:?Observer的踩坑記錄

    這篇文章主要介紹了vue中__ob__:?Observer的踩坑記錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10

最新評論