Handlebars.js入門教程


概述

剛接觸前端的時候,師傅就給我推薦了Handlebars,自己也蠻喜歡它的語法。到現在,Handlebars都已經更新到3.0.3了,是時候重新過一遍文檔了。

引入

要使用Handlebars,首先你得download,然后再頁面引入,就像這樣

<script src="script/lib/jquery.js"></script>
<script src="script/lib/handlebars.js"></script>

如果你使用了模塊化的管理工具,如requirejs、webpack、seajs,不用擔心。Handlebars是支持amd、cmd規范的,使用就像這樣

var Handlebars=require('Handlebars');

基本

來一個簡單的例子,向服務器發起了一個ajax請求獲取了一個對象數組,要渲染到頁面上。數據格式是這樣的

var data = [
    {
        name: 'xxx',
        age: 10
    },
    {
        name: 'zzz',
        age: 12
    },
    {
        name: 'yyy',
        age: 9
    }
];

首先我們要建立一個模板結構,也就是我們的Html,為了展示和邏輯分離,我們不應該將模版內容放到js當中,先看下不好的做法:

var $container = $('#container');//容器
var content = '';

data.forEach(function (item) {
    content += '<p>' + item.name + ':' + item.age + '</p>';
});

$container.html(content);

當Html內容一多,各種單引號,雙引號,可讀性、結構性太差。維護起來將是我們開發的噩夢。
使用Handlebars,首先我們將Html抽出來,就像用script標簽包裹起來,放入我們當前的頁面中,就像這樣

<body>
    <div id="container"></div>
    <script type="text/x-handlebars-template" id="template-user">{{#each this}} <p>{{name}}:{{age}}</p> {{/each}}</script>
    <script src="script/lib/jquery.js"></script>
    <script src="script/lib/handlebars.js"></script>
    <script src="script/my/basicuse.js"></script>
</body>

記得改變type類型,這樣瀏覽器就不會把標簽里的內容當作js執行。然后編寫我們的代碼

var $container = $('#container');//容器
var source = $('#template-user').html();//獲取到html結構
var template = Handlebars.compile(source);//編譯成模板
var html = template(data);//生成完成的html結構
$container.html(html);//插入dom

Handlebars的基本使用就如上了,用{{ }}輸出內容。記住了

模板最外層的this就是你調用template方法時傳入的對象

Block

我們使用模板一般都是為了遍歷對象結構,然后渲染到頁面上。有人說了如果我就傳遞個字符串進去呢?直接

$container.html(str);

用JBM模板!使用模板最常用的就是if判斷和each遍歷了,下面來詳細講解。

Handlebars的block都是這種{{#each}}{{/each}}的閉合結構

if/unless

if

Handlebars的if判斷只能判斷true和false,沒辦法進行這種a===3的邏輯判斷。它的設定就是如此,它認為邏輯判斷的內容不應該出現在模板中。看個例子

#template {{#if isEdit}} <p>isEdit</p> {{/if}}{{#if email}} <p>{{email}}</p> {{/if}}{{#if num}} <p>{{num}}</p> {{/if}} #數據 var data = { isEdit: true, email: '', num: '0' }; #頁面效果 isEdit 0 

Handlebars if在判斷前會做類型轉換,如''、undefined、null、0、[]等都會被識別為false。而實際情況下我們都用數字來標識不同的狀態,碰到這種數據我們需要預處理下,才能渲染哦。

if else

#template {{#if isEdit}} <p>isEdit</p> {{else}} <p>isNotEdit</p> {{/if}} #數據 var data = { isEdit: false }; #頁面效果 isNotEdit 

看看多分支是咋子寫的

#template {{#if isEdit}} <p>isEdit</p> {{else if isRead}} <p>isNotEdit isRead</p> {{else}} <p>isNotRead</p> {{/if}} #數據 var data = { isEdit: false, isRead: false }; #頁面效果 isNotRead 

unless

作用剛好跟if相反,if是true的時候返回,unless是false的時候返回,看例子

#template {{#unless isEdit}} <p>isNotEdit</p> {{else unless isRead}} <p>isRead</p> {{else}} <p>isNotRead</p> {{/unless}} #數據 var data = { isEdit: true, isRead:true }; #頁面效果 isNotRead 

each

遍歷數組

#template {{#each this}} <p>{{this.name}}:{{this.age}}</p> {{else}} <p>no data</p> {{/each}} #數據 var data = [ { name: 'yyy', age: 23 }, { name: 'zzz', age: 55 } ]; #頁面效果 yyy:23 zzz:55 

each也支持else的判斷。each里面的this是指向單個對象的,這個時候this可以省略不寫,效果是一樣的

{{#each this}} <p>{{name}}:{{age}}</p> {{/each}}

遍歷數組的時候一般都會輸出序號,怎么破?

#template {{#each this}} <p>{{this.name}}:{{this.age}}</p> {{/each}} #頁面效果 0 yyy:23 1 zzz:55 

通過@index或者@key都可以獲得序號,但是序號都是從0開始的,這個比較坑!如果要從1開始,得自己寫個helper處理,真實日了狗了!

遍歷數組的需要判別是第一個還是最后一個怎么破?

#template {{#each this}} <p>{{name}}:{{age}}{{#if @first}}first{{/if}}{{#if @last}}last{{/if}}</p> {{/each}} #頁面效果 yyy:23 first zzz:55 last 

通過@first和@last可以判斷是否是數組的第一個或者最后一個。

如果在加上@odd、@even就完美了!

遍歷對象

真實的應用場景下,服務器很可能會返回一個map,就是js當中的對象,這個時候我們是不知道有哪些key的,如何遍歷這個map呢?

#template {{#each this}} <p>{{@key}}:{{this}}</p> {{/each}} #數據 var data = { name: 'yyy', age: 23 }; #頁面效果 name:yyy age:23 

通過@key可以獲取到對象的key名稱。

Html轉義

假想這樣一個場景,通過ajax獲取到了一段富文本內容,然后展示在頁面中

#template
<div>{{richText}}</div>

#數據
var data = {
    richText: '<div>this is rich text</div>'
};

#頁面效果
<div>this is rich text</div>

這個時候你肯定會想了,真實日了狗了,怎么原樣輸出了,沒有解析成html啊。因為{{richText}}的輸出默認轉義Html,幾乎所有的模板引擎輸出默認都是轉義Html的,避免xss攻擊。如果你想避免轉義,請這樣用

{{{richText}}}

Helpers

列表輸出的時候,如果有時間字段,一般都需要格式化時間,拿到數據后我們還得處理

#template
{{#each this}}
    <p>{{name}}:{{addTime}}</p>
{{/each}}

#js
var data = [
    {
        name: 'xxx',
        addTime: new Date()
    },
    {
        name: 'zzz',
        addTime: new Date()
    }
];

data.forEach(function(item){
   item.addTime=moment(item.addTime).format('YYYY-MM-DD');
});

#頁面效果
xxx:2015-05-26
zzz:2015-05-26

換個頁面碰到類似的情景,相同的代碼又得寫一面,冗余的代碼太多了,不利於后期維護。怎么破?

#template
{{#each this}}
    <p>{{name}}:{{moment addTime}}</p>
{{/each}}

#js
Handlebars.registerHelper('moment', function (date, options) {
    var formatStr = options.hash.format || 'YYYY-MM-DD';
    return new Handlebars.SafeString(moment(date).format(formatStr));
});

var data = [
    {
        name: 'xxx',
        addTime: new Date()
    },
    {
        name: 'zzz',
        addTime: new Date()
    }
];

注冊一個全局的moment,這樣所有的時間格式化,都可以通過{{moment time}}調用,維護的成本大大降低。
需要注意的是helper如{{moment arg1 arg2}}的形式最多添加兩個參數可以被注冊函數獲取到,如果要添加多個參數,請使用hash的形式

#template
<p>{{query name 'arg2' hash1='hash1' hash2='hash2'}}</p>

#數據
Handlebars.registerHelper('query', function (arg1, arg2, options) {
    console.log('arg1:' + arg1);
    console.log('arg2:' + arg2);
    console.log(options.hash);
});

var data = {
    name: 'jacky'
};

#控制台
$ arg1:jacky
$ arg2:arg2
$ Object {hash2: "hash2", hash1: "hash1"}

Handlebars.SafeString就是不轉義Html,如果想轉義Html直接return內容即可。

#template
<p>{{safe}}</p>

#js
Handlebars.registerHelper('safe', function () {
   return new Handlebars.SafeString('<div>safe string</div>')
});

#頁面效果
safe string

Partials

共享同一個模板內容,后端渲染使用的比較多

#template
<p>{{> footer}}</p>

#js
Handlebars.registerPartial('footer', function () {
    return new Handlebars.SafeString('<div>This is footer</div>')
});

var data = {
    name: 'jacky'
};

#頁面效果
This is footer

../

這樣一個數據結構渲染到頁面上

#template {{#each company.prodList}} <p>{{prodName}}{{company.comName}}</p> {{/each}} #js var data = { company: { comName: '技術有限公司', prodList: [ { prodName: '產品1' }, { prodName: '產品2' } ] } }; #頁面效果 產品1 產品2 

等等好像有點不對勁啊,為啥沒有公司名稱呢?前面說到each里面的this都是指向單個對象的,{{prodName}} {{company.comName}}這種寫法省略了this,還原下

{{#each company.prodList}} <p>{{this.prodName}}{{this.company.comName}}</p> {{/each}}

知道問題在哪里了吧。怎么破?

{{#each company.prodList}} <p>{{prodName}}{{../company.comName}}</p> {{/each}}

通過../回到each之外。下面來填另一個經典的坑

#template <ul> {{#each this}} <li> <ul> {{#each this}} <li>{{@../index}}-{{@index}}{{this}}</li> {{/each}} </ul> </li> {{/each}} </ul> #js var data = [ ['aaa', 'bbb', 'ccc'], ['ddd', 'eee', 'fff'] ]; #頁面效果 0-0 aaa 0-1 bbb 0-2 ccc 1-0 ddd 1-1 eee 1-2 fff 

代碼鏈接

Github

參考

Handlebars

概述

剛接觸前端的時候,師傅就給我推薦了Handlebars,自己也蠻喜歡它的語法。到現在,Handlebars都已經更新到3.0.3了,是時候重新過一遍文檔了。

引入

要使用Handlebars,首先你得download,然后再頁面引入,就像這樣

  1.  
    <script src="script/lib/jquery.js"> </script>
  2.  
    <script src="script/lib/handlebars.js"> </script>

如果你使用了模塊化的管理工具,如requirejs、webpack、seajs,不用擔心。Handlebars是支持amd、cmd規范的,使用就像這樣

var Handlebars=require('Handlebars');

基本

來一個簡單的例子,向服務器發起了一個ajax請求獲取了一個對象數組,要渲染到頁面上。數據格式是這樣的

  1.  
    var data = [
  2.  
    {
  3.  
    name: 'xxx',
  4.  
    age: 10
  5.  
    },
  6.  
    {
  7.  
    name: 'zzz',
  8.  
    age: 12
  9.  
    },
  10.  
    {
  11.  
    name: 'yyy',
  12.  
    age: 9
  13.  
    }
  14.  
    ];

首先我們要建立一個模板結構,也就是我們的Html,為了展示和邏輯分離,我們不應該將模版內容放到js當中,先看下不好的做法:

  1.  
    var $container = $( '#container'); //容器
  2.  
    var content = '';
  3.  
     
  4.  
    data. forEach( function (item) {
  5.  
    content += '<p>' + item.name + ':' + item.age + '</p>';
  6.  
    });
  7.  
     
  8.  
    $container.html(content);

當Html內容一多,各種單引號,雙引號,可讀性、結構性太差。維護起來將是我們開發的噩夢。
使用Handlebars,首先我們將Html抽出來,就像用script標簽包裹起來,放入我們當前的頁面中,就像這樣

  1.  
    <body>
  2.  
    <div id="container"> </div>
  3.  
    <script type="text/x-handlebars-template" id="template-user">
  4.  
    {{#each this}}
  5.  
    <p>{{name}}:{{age}} </p>
  6.  
    {{/each}}
  7.  
    </script>
  8.  
    <script src="script/lib/jquery.js"> </script>
  9.  
    <script src="script/lib/handlebars.js"> </script>
  10.  
    <script src="script/my/basicuse.js"> </script>
  11.  
    </body>

記得改變type類型,這樣瀏覽器就不會把標簽里的內容當作js執行。然后編寫我們的代碼

  1.  
    var $container = $( '#container'); //容器
  2.  
    var source = $( '#template-user').html(); //獲取到html結構
  3.  
    var template = Handlebars.compile(source); //編譯成模板
  4.  
    var html = template(data); //生成完成的html結構
  5.  
    $container.html(html); //插入dom

Handlebars的基本使用就如上了,用{{ }}輸出內容。記住了

模板最外層的this就是你調用template方法時傳入的對象

Block

我們使用模板一般都是為了遍歷對象結構,然后渲染到頁面上。有人說了如果我就傳遞個字符串進去呢?直接

$container.html(str);

用JBM模板!使用模板最常用的就是if判斷和each遍歷了,下面來詳細講解。

Handlebars的block都是這種{{#each}}{{/each}}的閉合結構

if/unless

if

Handlebars的if判斷只能判斷true和false,沒辦法進行這種a===3的邏輯判斷。它的設定就是如此,它認為邏輯判斷的內容不應該出現在模板中。看個例子

  1.  
    #template
  2.  
    {{ #if isEdit}}
  3.  
    <p>isEdit</p>
  4.  
    {{/ if}}
  5.  
    {{ #if email}}
  6.  
    <p>{{email}}</p>
  7.  
    {{/ if}}
  8.  
    {{ #if num}}
  9.  
    <p>{{num}}</p>
  10.  
    {{/ if}}
  11.  
     
  12.  
    #數據
  13.  
    var data = {
  14.  
    isEdit: true,
  15.  
    email: '',
  16.  
    num: '0'
  17.  
    };
  18.  
     
  19.  
    #頁面效果
  20.  
    isEdit
  21.  
    0

Handlebars if在判斷前會做類型轉換,如''、undefined、null、0、[]等都會被識別為false。而實際情況下我們都用數字來標識不同的狀態,碰到這種數據我們需要預處理下,才能渲染哦。

if else

  1.  
    #template
  2.  
    {{ #if isEdit}}
  3.  
    <p>isEdit</p>
  4.  
    {{ else}}
  5.  
    <p>isNotEdit</p>
  6.  
    {{/ if}}
  7.  
     
  8.  
    #數據
  9.  
    var data = {
  10.  
    isEdit: false
  11.  
    };
  12.  
     
  13.  
    #頁面效果
  14.  
    isNotEdit

看看多分支是咋子寫的

  1.  
    #template
  2.  
    {{ #if isEdit}}
  3.  
    <p>isEdit</p>
  4.  
    {{ else if isRead}}
  5.  
    <p>isNotEdit isRead</p>
  6.  
    {{ else}}
  7.  
    <p>isNotRead</p>
  8.  
    {{/ if}}
  9.  
     
  10.  
    #數據
  11.  
    var data = {
  12.  
    isEdit: false,
  13.  
    isRead: false
  14.  
    };
  15.  
     
  16.  
    #頁面效果
  17.  
    isNotRead

unless

作用剛好跟if相反,if是true的時候返回,unless是false的時候返回,看例子

  1.  
    #template
  2.  
    {{ #unless isEdit}}
  3.  
    <p>isNotEdit</p>
  4.  
    {{ else unless isRead}}
  5.  
    <p>isRead</p>
  6.  
    {{ else}}
  7.  
    <p>isNotRead</p>
  8.  
    {{/unless}}
  9.  
     
  10.  
    #數據
  11.  
    var data = {
  12.  
    isEdit: true,
  13.  
    isRead: true
  14.  
    };
  15.  
     
  16.  
    #頁面效果
  17.  
    isNotRead

each

遍歷數組

  1.  
    #template
  2.  
    {{#each this}}
  3.  
    <p>{{ this.name}}:{{ this.age}}</p>
  4.  
    {{ else}}
  5.  
    <p>no data</p>
  6.  
    {{/each}}
  7.  
     
  8.  
    #數據
  9.  
    var data = [
  10.  
    {
  11.  
    name: 'yyy',
  12.  
    age: 23
  13.  
    },
  14.  
    {
  15.  
    name: 'zzz',
  16.  
    age: 55
  17.  
    }
  18.  
    ];
  19.  
     
  20.  
    #頁面效果
  21.  
    yyy: 23
  22.  
    zzz: 55

each也支持else的判斷。each里面的this是指向單個對象的,這個時候this可以省略不寫,效果是一樣的

  1.  
    {{# each this}}
  2.  
    <p>{{name}}:{{age}}</p>
  3.  
    {{/ each}}

遍歷數組的時候一般都會輸出序號,怎么破?

  1.  
    #template
  2.  
    {{#each this}}
  3.  
    <p>{{ this.name}}:{{ this.age}}</p>
  4.  
    {{/each}}
  5.  
     
  6.  
    #頁面效果
  7.  
    0 yyy: 23
  8.  
    1 zzz: 55

通過@index或者@key都可以獲得序號,但是序號都是從0開始的,這個比較坑!如果要從1開始,得自己寫個helper處理,真實日了狗了!

遍歷數組的需要判別是第一個還是最后一個怎么破?

  1.  
    #template
  2.  
    {{ #each this}}
  3.  
    <p>{{name}}:{{age}} {{ #if @first}}first{{/if}} {{#if @last}}last{{/if}}</p>
  4.  
    {{/each}}
  5.  
     
  6.  
    #頁面效果
  7.  
    yyy: 23 first
  8.  
    zzz: 55 last

通過@first和@last可以判斷是否是數組的第一個或者最后一個。

如果在加上@odd、@even就完美了!

遍歷對象

真實的應用場景下,服務器很可能會返回一個map,就是js當中的對象,這個時候我們是不知道有哪些key的,如何遍歷這個map呢?

  1.  
    #template
  2.  
    {{#each this}}
  3.  
    <p>{{ @key}}:{{ this}}</p>
  4.  
    {{/each}}
  5.  
     
  6.  
    #數據
  7.  
    var data = {
  8.  
    name: 'yyy',
  9.  
    age: 23
  10.  
    };
  11.  
     
  12.  
    #頁面效果
  13.  
    name:yyy
  14.  
    age: 23

通過@key可以獲取到對象的key名稱。

Html轉義

假想這樣一個場景,通過ajax獲取到了一段富文本內容,然后展示在頁面中

  1.  
    #template
  2.  
    <div>{{richText}}</div>
  3.  
     
  4.  
    #數據
  5.  
    var data = {
  6.  
    richText: '<div>this is rich text</div>'
  7.  
    };
  8.  
     
  9.  
    #頁面效果
  10.  
    <div> this is rich text</div>

這個時候你肯定會想了,真實日了狗了,怎么原樣輸出了,沒有解析成html啊。因為{{richText}}的輸出默認轉義Html,幾乎所有的模板引擎輸出默認都是轉義Html的,避免xss攻擊。如果你想避免轉義,請這樣用

{{{richText}}}

Helpers

列表輸出的時候,如果有時間字段,一般都需要格式化時間,拿到數據后我們還得處理

  1.  
    #template
  2.  
    {{ #each this}}
  3.  
    <p>{{name}}:{{addTime}}</p>
  4.  
    {{/each}}
  5.  
     
  6.  
    #js
  7.  
    var data = [
  8.  
    {
  9.  
    name: 'xxx',
  10.  
    addTime: new Date()
  11.  
    },
  12.  
    {
  13.  
    name: 'zzz',
  14.  
    addTime: new Date()
  15.  
    }
  16.  
    ];
  17.  
     
  18.  
    data. forEach( function(item){
  19.  
    item.addTime=moment(item.addTime).format( 'YYYY-MM-DD');
  20.  
    });
  21.  
     
  22.  
    #頁面效果
  23.  
    xxx: 2015 -05 -26
  24.  
    zzz: 2015 -05 -26

換個頁面碰到類似的情景,相同的代碼又得寫一面,冗余的代碼太多了,不利於后期維護。怎么破?

  1.  
    #template
  2.  
    {{ #each this}}
  3.  
    <p>{{name}}:{{moment addTime}}</p>
  4.  
    {{/each}}
  5.  
     
  6.  
    #js
  7.  
    Handlebars.registerHelper( 'moment', function (date, options) {
  8.  
    var formatStr = options.hash.format || 'YYYY-MM-DD';
  9.  
    return new Handlebars.SafeString(moment(date).format(formatStr));
  10.  
    });
  11.  
     
  12.  
    var data = [
  13.  
    {
  14.  
    name: 'xxx',
  15.  
    addTime: new Date()
  16.  
    },
  17.  
    {
  18.  
    name: 'zzz',
  19.  
    addTime: new Date()
  20.  
    }
  21.  
    ];

注冊一個全局的moment,這樣所有的時間格式化,都可以通過{{moment time}}調用,維護的成本大大降低。
需要注意的是helper如{{moment arg1 arg2}}的形式最多添加兩個參數可以被注冊函數獲取到,如果要添加多個參數,請使用hash的形式

  1.  
    #template
  2.  
    <p>{{query name 'arg2' hash1= 'hash1' hash2= 'hash2'}}</p>
  3.  
     
  4.  
    #數據
  5.  
    Handlebars.registerHelper( 'query', function (arg1, arg2, options) {
  6.  
    console.log( 'arg1:' + arg1);
  7.  
    console.log( 'arg2:' + arg2);
  8.  
    console.log(options.hash);
  9.  
    });
  10.  
     
  11.  
    var data = {
  12.  
    name: 'jacky'
  13.  
    };
  14.  
     
  15.  
    #控制台
  16.  
    $ arg1:jacky
  17.  
    $ arg2:arg2
  18.  
    $ Object {hash2: "hash2", hash1: "hash1"}

Handlebars.SafeString就是不轉義Html,如果想轉義Html直接return內容即可。

  1.  
    #template
  2.  
    <p>{{safe}}</p>
  3.  
     
  4.  
    #js
  5.  
    Handlebars.registerHelper( 'safe', function () {
  6.  
    return new Handlebars.SafeString( '<div>safe string</div>')
  7.  
    });
  8.  
     
  9.  
    #頁面效果
  10.  
    safe string

Partials

共享同一個模板內容,后端渲染使用的比較多

  1.  
    #template
  2.  
    <p>{{> footer}}</p>
  3.  
     
  4.  
    #js
  5.  
    Handlebars.registerPartial( 'footer', function () {
  6.  
    return new Handlebars.SafeString( '<div>This is footer</div>')
  7.  
    });
  8.  
     
  9.  
    var data = {
  10.  
    name: 'jacky'
  11.  
    };
  12.  
     
  13.  
    #頁面效果
  14.  
    This is footer

../

這樣一個數據結構渲染到頁面上

  1.  
    #template
  2.  
    {{ #each company.prodList}}
  3.  
    <p>{{prodName}} {{company.comName}}</p>
  4.  
    {{/each}}
  5.  
     
  6.  
    #js
  7.  
    var data = {
  8.  
    company: {
  9.  
    comName: '技術有限公司',
  10.  
    prodList: [
  11.  
    {
  12.  
    prodName: '產品1'
  13.  
    },
  14.  
    {
  15.  
    prodName: '產品2'
  16.  
    }
  17.  
    ]
  18.  
    }
  19.  
    };
  20.  
     
  21.  
    #頁面效果
  22.  
    產品 1
  23.  
    產品 2

等等好像有點不對勁啊,為啥沒有公司名稱呢?前面說到each里面的this都是指向單個對象的,{{prodName}} {{company.comName}}這種寫法省略了this,還原下

  1.  
    {{#each company.prodList}}
  2.  
    <p>{{ this.prodName}} {{ this.company.comName}}</p>
  3.  
    {{/each}}

知道問題在哪里了吧。怎么破?

  1.  
    {{# each company.prodList}}
  2.  
    <p>{{prodName}} {{../company.comName}}</p>
  3.  
    {{/ each}}

通過../回到each之外。下面來填另一個經典的坑

  1.  
    #template
  2.  
    <ul>
  3.  
    {{#each this}}
  4.  
    <li>
  5.  
    <ul>
  6.  
    {{#each this}}
  7.  
    <li>{{@../index}}-{{ @index}} {{ this}}</li>
  8.  
    {{/each}}
  9.  
    </ul>
  10.  
    </li>
  11.  
    {{/each}}
  12.  
    </ul>
  13.  
     
  14.  
    #js
  15.  
    var data = [
  16.  
    [ 'aaa', 'bbb', 'ccc'],
  17.  
    [ 'ddd', 'eee', 'fff']
  18.  
    ];
  19.  
     
  20.  
    #頁面效果
  21.  
    0 -0 aaa
  22.  
    0 -1 bbb
  23.  
    0 -2 ccc
  24.  
    1 -0 ddd
  25.  
    1 -1 eee
  26.  
    1 -2 fff

代碼鏈接

Github

參考

Handlebars


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM