Ueditor 當頁面無刷新,初始化方法

如標題,需求為SPA模式下,初始化編輯器第一次沒問題,但第二次就無法初始化

可以前往ueditor.all.js查看程式碼 getEditor()

  UE.getEditor = function (id, opt) {
        var editor = instances[id];
        if (!editor) {
            editor = instances[id] = new UE.ui.Editor(opt);
            editor.render(id);
        }
        return editor;
    };

在上方程式碼可看到初始化時,會先判斷instances[id]必須不存在才會進行初始化

有兩種解決方式,如下

// 1.

     UE.getEditor('container').render('container');
     
//2.   

     UE.delEditor('container');
     UE.getEditor('container');

ES6學習 (1) var、let、const差異

Var 特性

function scope (函式作用域)
有hoising (變數提升)
可重複定義宣告的數值

Let 特性

block scope (塊級作用域)
同個作用域中不可重複宣告,可重新賦值
沒有hoising (沒有變數提升)
需宣告後才可使用

Const 特性

常數宣告後不可更改
block scope (塊級作用域)
同個作用域中不可重複宣告,不可重新賦值
沒有hoising (沒有變數提升)
需宣告後才可使用

三者比較

var price = 100;
var count = 10;
if(count > 5){
    var discountA = 0.9 * price;
    let discountB = 0.85 * price;
    const discountC = 0.7 * price;
    console.log("This is DiscountA: " + discountA);
    console.log("This is DiscountB: " + discountB);
    console.log("This is DiscountC: " + discountC);
}
console.log("This is DiscountA: " + discountA);  //因var 是function scope,if非函式,在這宣告等同於在全局環境下宣告

console.log("This is DiscountB: " + discountB);  //會報錯 discountB is not defined

console.log("This is DiscountC: " + discountC);  //會報錯 discountC is not defined

Const 在特殊狀況下可重新賦值,改變object中的屬性的值(不建議這使用方式)

const person = {
    name:"Hao",
    age:20
}
person.age = 21;
console.log(person);  //會變為{name: "Hao", age: 21} 

person = {name:"AAA"}; //如直接修改屬性,則會報錯

Laravel 本地開發網址後綴 .app & .dev

今早要開啟chrome發現,本地開發網址都會自動跳轉至https://查一下才發現chrome更新後,可參考Chrome更新說明用.app與.dev後綴,Chrome瀏覽器皆會自動跳轉到https,之後本地開發需使用別的後綴,可至瀏覽器輸入 chrome://net-internals/#hsts 連結到chrome設置,裡邊的Query HSTS/PKP domain輸入您本地開發的網址,如果跑出下列圖中資訊,表示這個網址後綴接會自動跳轉至https服務,如顯示為Not found,那就可以使用這個後綴,個人已將網址後綴改為.localhost了...至於.env中APP_URL請一併更新為新的後綴。

Found:
static_sts_domain: app
static_upgrade_mode: FORCE_HTTPS
static_sts_include_subdomains: true
static_sts_observed: 1508821200
static_pkp_domain:
static_pkp_include_subdomains:
static_pkp_observed:
static_spki_hashes:
dynamic_sts_domain:
dynamic_upgrade_mode: UNKNOWN
dynamic_sts_include_subdomains:
dynamic_sts_observed:
dynamic_sts_expiry:
dynamic_pkp_domain:
dynamic_pkp_include_subdomains:
dynamic_pkp_observed:
dynamic_pkp_expiry:
dynamic_spki_hashes:

Laravel Faker產生假資料使用中文

主要是看到FB Laravel 社團中有人分享Faker 產生中文方法,但是是寫在AppServiceProvider內,其實還有其他方式

首先還是建立Model做測試

php artisan make:model post -m

設定該migrations post database table

public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');               //文章標題
            $table->text('body');                  //文章內容
            $table->unsignedInteger('user_id');    //文章發起人
            $table->timestamps();
        });
    }

建立與table對應的PostFactory.php 於database/factories下

<?php
use Faker\Generator as Faker;
$factory->define(App\Post::class, function (Faker $faker) {
    return [
        'title'   => $faker->title(10),
        'body'    => $faker->realText(200),
        'user_id' => factory(\App\User::class)->create()->id
    ];
});
?>

最後在config\app.php下新增一行,指定Faker 使用zh_TW語言

'faker_locale' => 'zh_TW',

測試

php artisan tinker
factory(App\Post::class)->make()

Laravel & Vue.js - SPA (9) 修正LoginForm.vue

需求:上一章最後LoginForm.vue中formData內暴露出Passport的ID & Secret

,本章主要是針對這做一些修改

首先先執行命令composer require guzzleHttp (用於PHP中發送HTTP請求)

composer require guzzlehttp/guzzle

次先建立TokenProxy.php 類(用於獲取用戶登入Token及env中的設定),於App\Http\Proxy下

<?php
namespace App\Http\Proxy;
class TokenProxy
{
    protected $http;
    public function __construct(\GuzzleHttp\Client $http)   //引入GuzzleHttp
    {
        $this->http = $http;
    }

    public function login($username,$password)
    {
        //驗證 user email password 以及 is_active
        if(auth()->attempt(['email' => $username,'password' => $password,'is_active' => true]))
        {
            return $this->proxy('password',[
                'username' => $username,
                'password' => $password,
                'scope'    => ''
            ]);
        }
        //驗證錯誤 返回失敗訊息
        return response()->json([
            'status' => false,
            'message' => 'Credentials not match'
        ],421);
    }
    
    public function proxy($grantType,array $data = [])
    {
        $data = array_merge($data,[
            'client_id'     => env('PASSPORT_Client_ID'),
            'client_secret' => env('PASSPORT_Client_Secret'),
            'grant_type'    => $grantType
        ]);
        // oauth/token
        $response = $this->http->post(url('oauth/token'),[
            'form_params' => $data
        ]);
        $token = json_decode((string) $response->getBody(),true);
        return response()->json([
            'token'      => $token['access_token'],
            'expired_in' => $token['expires_in']
        ])->cookie('refreshToken',$token['refresh_token'],21600,null,null,false,true);  
        //60 min * 24 hour * 15 day = 21600 與 AuthServiceProvider內refreshToken過期時間設定一致
    }
}
?>

新增一條API路由

Route::post('/login','Auth\LoginController@login');

修改預設的Auth\LoginController login function

<?php
namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Http\Proxy\TokenProxy;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
    use AuthenticatesUsers;
    protected $redirectTo = '/home';
    protected $proxy;                                    //設置proxy變數

    public function __construct(TokenProxy $proxy)       //引入TokenProxy類
    {
        $this->middleware('guest')->except('logout');
        $this->proxy = $proxy;
    }

    //重寫login function
    public function login()
    {
        return $this->proxy->login(request('username'),request('password'));
    }
}
?>

修改LoginForm.vue 修改post路徑 & formData 內容 (這只附上變動的部分)

<script>
    import JWTToken from './../../helpers/jwt';
    export default {
        data() {
            return {
                email:'',
                password:''
            }
        },
        methods:{
            login() {
                let formData = {
                    username : this.email,
                    password : this.password
                };
                axios.post('/api/login',formData).then(response => {
                    console.log(JWTToken.getToken());
                    JWTToken.setToken(response.data.token);
                }).catch(error =>{
                    console.log(error.response.data);
                });
            }
        }
    }
</script>

現在登入Chrome 開發者模式仍會拿到response.data.token,如帳號密碼錯誤則會提示錯誤訊息