• Laravel Vuejs 实战:开发知乎 (42-44)用户头像


    1.组件式上传头像vue组件:

    安装扩展包:vue-image-crop-upload 或者 Vue Avatar Cropper我用的这个,暂时弃坑,需要加一个csrftoken

    执行:

      1 npm i vue-avatar-cropper
      1 npm install & npm run watch-poll

    使用vue-image-crop-upload

    执行:

      1 npm install vue-image-crop-upload
      1 npm run watch-poll

    2.路由:

    添加:

      1 #region
      2 //访问用户详细页面
      3 
      4 Route::get('/avatar', 'UserController@avatar')->name('users.avatar');
      5 
      6 #endregion
      7 

    3.执行:

      1 php artisan make:controller UserController

    增加UserContoller.php,代码如下:

      1 <?php
      2 
      3 namespace AppHttpControllers;
      4 
      5 use IlluminateHttpRequest;
      6 
      7 class UserController extends Controller
      8 {
      9     //
     10 
     11     /** 返回用户avatar页面视图
     12      * @return IlluminateContractsViewFactory|IlluminateViewView
     13      */
     14     public function avatar()
     15     {
     16         return view('users._avatar');
     17     }
     18 
     19 
     20 }
     21 
     22 
    UserController.php

    4.增加视图文件:viewsusers\_avatar.blade.php:

      1 @extends('layouts.app')
      2 
      3 @section('content')
      4 
      5     <div class="container">
      6         <div class="row">
      7             <div class="col-md-8 col-md-offset-2">
      8                 <div class="card">
      9                     <div class="card-header">
     10                         更换头像
     11                     </div>
     12                     <div class="card-body">
     13                         <avatar avatar="{{ auth()->user()->avatar }}"></avatar>
     14                     </div>
     15                 </div>
     16             </div>
     17         </div>
     18     </div>
     19 
     20 @endsection
     21 
     22 
    _avatar.blade.php

    5.vue组件:

    执行:

      1 npm install babel-polyfill
    安装babel-polyfill

    代码:

      1 <template>
      2     <div>
      3         <a class="btn btn-success" @click="toggleShow">设置头像</a>
      4         <my-upload field="img"
      5                    @crop-success="cropSuccess"
      6                    @crop-upload-success="cropUploadSuccess"
      7                    @crop-upload-fail="cropUploadFail"
      8                    v-model="show"
      9                    :width="300"
     10                    :height="300"
     11                    url="/upload"
     12                    :params="params"
     13                    :headers="headers"
     14                    img-format="png"></my-upload>
     15         <img :src="imgDataUrl">
     16     </div>
     17 </template>
     18 
     19 <script>
     20     import 'babel-polyfill'; // es6 shim
     21     import myUpload from 'vue-image-crop-upload';
     22 
     23     export default {
     24         props: ['avatar'],
     25         name: "Avatar",
     26         data: function () {
     27             return {
     28                 show: false,
     29                 params: {
     30                     token: '123456798',
     31                     name: 'avatar'
     32                 },
     33                 headers: {
     34                     smail: '*_~'
     35                 },
     36                 imgDataUrl: this.avatar // the datebase64 url of created image
     37             }
     38         },
     39         components: {
     40             'my-upload': myUpload
     41         },
     42         methods: {
     43             toggleShow() {
     44                 this.show = !this.show;
     45             },
     46             /**
     47              * crop success
     48              *
     49              * [param] imgDataUrl
     50              * [param] field
     51              */
     52             cropSuccess(imgDataUrl, field) {
     53                 console.log('-------- 剪截成功 --------');
     54                 this.imgDataUrl = imgDataUrl;
     55             },
     56             /**
     57              * upload success
     58              *
     59              * [param] jsonData  server api return data, already json encode
     60              * [param] field
     61              */
     62             cropUploadSuccess(jsonData, field) {
     63                 console.log('-------- 上传成功 --------');
     64                 console.log(jsonData);
     65                 console.log('field: ' + field);
     66             },
     67             /**
     68              * upload fail
     69              *
     70              * [param] status    server api return error status, like 500
     71              * [param] field
     72              */
     73             cropUploadFail(status, field) {
     74                 console.log('-------- 上传失败 --------');
     75                 console.log(status);
     76                 console.log('field: ' + field);
     77             }
     78         }
     79 
     80     }
     81 </script>
     82 
     83 <style scoped>
     84 
     85 </style>
     86 
     87 
    Avatar.vue 还未配置完

    6.app.js:

      1 /**
      2  * First we will load all of this project's JavaScript dependencies which
      3  * includes Vue and other libraries. It is a great starting point when
      4  * building robust, powerful web applications using Vue and Laravel.
      5  */
      6 
      7 require('./bootstrap');
      8 require('../../vendor/select2/select2/dist/js/select2.js');
      9 // 将views/vendor/ueditor/assets.blade.php中的引用换到本处
     10 require('../../public/vendor/ueditor/ueditor.config.js');
     11 require('../../public/vendor/ueditor/ueditor.all.js');
     12 
     13 window.Vue = require('vue');
     14 
     15 /**
     16  * The following block of code may be used to automatically register your
     17  * Vue components. It will recursively scan this directory for the Vue
     18  * components and automatically register them with their "basename".
     19  *
     20  * Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
     21  */
     22 
     23 // const files = require.context('./', true, /.vue$/i)
     24 // files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))
     25 
     26 // Vue.component('example-component', require('./components/ExampleComponent.vue').default);
     27 Vue.component('question-follow-button', require('./components/QuestionFollowButton').default);
     28 Vue.component('user-follow-button', require('./components/UserFollowButton').default);
     29 Vue.component('user-vote-button', require('./components/UserVoteButton').default);
     30 Vue.component('send-message', require('./components/SendMessage').default);
     31 Vue.component('comments', require('./components/Comments').default);
     32 Vue.component('avatar', require('./components/Avatar').default);
     33 /**
     34  * Next, we will create a fresh Vue application instance and attach it to
     35  * the page. Then, you may begin adding components to this application
     36  * or customize the JavaScript scaffolding to fit your unique needs.
     37  */
     38 
     39 const app = new Vue({
     40     el: '#app',
     41 });
     42 
     43 
    app.js


    7.配置图片上传到服务器本地:

    web.php添加:

      1 <?php
      2 
      3 /*
      4 |--------------------------------------------------------------------------
      5 | Web Routes
      6 |--------------------------------------------------------------------------
      7 |
      8 | Here is where you can register web routes for your application. These
      9 | routes are loaded by the RouteServiceProvider within a group which
     10 | contains the "web" middleware group. Now create something great!
     11 |
     12 */
     13 
     14 Route::get('/', function () {
     15     return view('welcome');
     16 });
     17 
     18 Auth::routes(['verify' => true]);
     19 
     20 Route::get('/home', 'HomeController@index')->name('home');
     21 
     22 Route::resource('questions', 'QuestionController');
     23 
     24 
     25 #region 回答路由CRUD
     26 
     27 //查看回答 以及 回答的form 都是在questions详细内容页面
     28 
     29 //提交回答
     30 Route::post('questions/{question}/answers', 'AnswerController@store')->name('answers.store');
     31 
     32 //更新回答
     33 
     34 
     35 //删除回答
     36 
     37 
     38 #endregion
     39 
     40 
     41 #region
     42 //用户关注 取消关注问题
     43 Route::get('questions/{question}/follow', 'QuestionController@follow')->name('questions.follow');
     44 #endregion
     45 
     46 
     47 #region
     48 
     49 //用户通知消息路由
     50 Route::get('/notifications', 'NotificationController@index')->name('notification.index');
     51 #endregion
     52 
     53 #region
     54 //用户查看短消息
     55 Route::get('/inbox', 'InboxController@index')->name('inbox.index');
     56 
     57 //展示用户间私信对话具体内容页
     58 Route::get('/inbox/{userId}', 'InboxController@show')->name('inbox.show');
     59 
     60 //用户回信息
     61 Route::post('/inbox/{userId}/send', 'InboxController@store')->name('inbox.store');
     62 #endregion
     63 
     64 
     65 #region
     66 //访问用户详细页面
     67 
     68 Route::get('/avatar', 'UserController@avatar')->name('users.avatar');
     69 
     70 Route::post('/avatar/upload', 'UserController@avatarStore');
     71 
     72 #endregion
     73 
     74 
     75 
     76 
    web.php

    UserContoller.php增加代码如下:

      1 <?php
      2 
      3 namespace AppHttpControllers;
      4 
      5 use IlluminateHttpRequest;
      6 
      7 class UserController extends Controller
      8 {
      9     //
     10     public function __construct()
     11     {
     12         $this->middleware('auth');
     13     }
     14 
     15 
     16     /** 返回用户avatar页面视图
     17      * @return IlluminateContractsViewFactory|IlluminateViewView
     18      */
     19     public function avatar()
     20     {
     21         return view('users._avatar');
     22     }
     23 
     24     public function avatarStore(Request $request)
     25     {
     26         $user = auth()->user();
     27         $file = $request->file('img');
     28         $fileName = md5(time() . $user->id) . '.' . $file->getClientOriginalExtension();
     29         $file->move('uploads/image/avatars', $fileName);
     30 
     31         $user->avatar = asset('uploads/image/avatars/' . $fileName);
     32 
     33         $user->save();
     34 
     35         return response()->json(
     36             [
     37                 'url' => $user->avatar,
     38             ]);
     39     }
     40 }
     41 
     42 
    UserController.php

    Vue文件修改:

    注意这个token在laravel中应该是_token,否则会419未授权。

    批注 2020-03-04 220629

      1 <template>
      2     <div>
      3         <a class="btn btn-success" @click="toggleShow">设置头像</a>
      4         <my-upload field="img"
      5                    @crop-success="cropSuccess"
      6                    @crop-upload-success="cropUploadSuccess"
      7                    @crop-upload-fail="cropUploadFail"
      8                    v-model="show"
      9                    :width="300"
     10                    :height="300"
     11                    url="/avatar/upload"
     12                    :params="params"
     13                    :headers="headers"
     14                    img-format="png"></my-upload>
     15         <img :src="imgDataUrl" style="50px">
     16     </div>
     17 </template>
     18 
     19 <script>
     20     import 'babel-polyfill'; // es6 shim
     21     import myUpload from 'vue-image-crop-upload';
     22 
     23     export default {
     24         props: ['avatar'],
     25         name: "Avatar",
     26         data: function () {
     27             return {
     28                 show: false,
     29                 params: {
     30                     _token: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
     31                     name: 'avatar'
     32                 },
     33                 headers: {
     34                     smail: '*_~',
     35                 },
     36                 imgDataUrl: this.avatar // the datebase64 url of created image
     37             }
     38         },
     39         components: {
     40             'my-upload': myUpload
     41         },
     42         methods: {
     43             toggleShow() {
     44                 this.show = !this.show;
     45             },
     46             /**
     47              * crop success
     48              *
     49              * [param] imgDataUrl
     50              * [param] field
     51              */
     52             cropSuccess(imgDataUrl, field) {
     53                 console.log('-------- 剪截成功 --------');
     54                 this.imgDataUrl = imgDataUrl;
     55             },
     56             /**
     57              * upload success
     58              *
     59              * [param] jsonData  server api return data, already json encode
     60              * [param] field
     61              */
     62             cropUploadSuccess(jsonData, field) {
     63                 console.log('-------- 上传成功 --------');
     64                 // console.log(jsonData);
     65                 // console.log('field: ' + field);
     66                 this.toggleShow();
     67             },
     68             /**
     69              * upload fail
     70              *
     71              * [param] status    server api return error status, like 500
     72              * [param] field
     73              */
     74             cropUploadFail(status, field) {
     75                 console.log('-------- 上传失败 --------');
     76                 console.log(status);
     77                 console.log('field: ' + field);
     78             }
     79         }
     80 
     81     }
     82 </script>
     83 
     84 <style scoped>
     85 
     86 </style>
     87 
     88 
    Avatar.vue


    8.七牛云存储:

  • 相关阅读:
    POJ 2752 KMP中next数组的理解
    KMP详解
    HDU 3221 矩阵快速幂+欧拉函数+降幂公式降幂
    POJ 3220 位运算+搜索
    反素数深度分析
    POJ 2886 线段树单点更新
    求反素数的方法
    CV第八课 GPU/CPU
    49. 字母异位词分组
    48. 旋转图像
  • 原文地址:https://www.cnblogs.com/dzkjz/p/12409837.html
Copyright © 2020-2023  润新知