vuejs知乎_Laravel Vuejs 实战:开发知乎 (20)使用 Vuejs 组件化

1.vue 目录位置:resources/js/components

PhpStorm语法设置:

1.1 在reources/js/components文件夹内新建一个QuestionFollowButton.vue文件【问题关注按钮vue组件】

将原show.blade.php中的 关注按钮部分 移入新vue组件内部:

初步样式:

执行

1 npm install & npm run watch-poll

刷新页面看到

现在只是大致样式,还不能工作,因为要用ajax请求 所以后面要去掉blade中的if can逻辑 放到vue组件中。

2.ajax

laravel 使用 prop 传递blade中的数据到vue组件中;

axios请求要注意 :then里面赋值的时候 报错property undefine 是因为在then里面 this作用域超出了,需要如下示例的代码才能起作用:

this.followable = response.data.followable;在then里面 this作用域超出了

这样会超出作用域,要修改如下:

1 mounted() {

2 let currentObj = this;

3 axios.post('/api/questions/follow', {'question': this.question, 'user': this.user})

4 .then(function (response) {

5 currentObj.followable = response.data.followable;

6 });

7 },

8 methods: {

9 follow() {

10 let currentObj = this;

11 axios.post('/api/questions/follow', {'question': this.question, 'user': this.user})

12 .then(function (response) {

13 currentObj.followable = response.data.followable;

14 }

15 );

16 },

17 }

18

QuestionFollowButton.vue文件:

1

2

3 :class="classObject"

4 @click="follow"

5 v-text="text">

6

7

8

9

10 export default {

11 props: ['question', 'user'],

12 name: "QuestionFollowButton",

13 data() {

14 return {

15 href: '',

16 followable: false,

17 }

18 },

19 computed: {

20 text() {

21 return this.followable ? "关注用户" : "取消关注";

22 },

23 classObject() {

24 return this.followable ? "btn btn-block btn-primary" : "btn btn-block btn-danger";

25 },

26 },

27 mounted() {

28 let currentObj = this;

29 axios.post('/api/questions/follow', {'question': this.question, 'user': this.user})

30 .then(function (response) {

31 currentObj.followable = response.data.followable;

32 });

33 },

34 methods: {

35 follow() {

36 let currentObj = this;

37 axios.post('/api/questions/follow', {'question': this.question, 'user': this.user})

38 .then(function (response) {

39 currentObj.followable = response.data.followable;

40 }

41 );

42 },

43 }

44 }

45

46

47

48

49

QuestionFollowButton.vue

api.php文件:

1 <?php

2

3 use Illuminate\Http\Request;

4

5 /*

6 |--------------------------------------------------------------------------

7 | API Routes

8 |--------------------------------------------------------------------------

9 |

10 | Here is where you can register API routes for your application. These

11 | routes are loaded by the RouteServiceProvider within a group which

12 | is assigned the "api" middleware group. Enjoy building your API!

13 |

14 */

15

16 Route::middleware('auth:api')->get('/user', function (Request $request) {

17 return $request->user();

18 });

19

20 Route::middleware('api')->get('/topics', function (Request $request) {

21 $query = $request->query('q');

22 return \App\Topic::query()->where('name', 'like', '%' . $query . '%')->get();

23 });

24

25 Route::middleware('api')->post('/questions/follow', 'QuestionController@followThroughApi');

26

api.php

show.blade.php文件:

1 @extends('layouts.app')

2 @section('content')

3

4

5

6 {{--问题--}}

7

8

9 {{ $question->title }}

10

11 @foreach(['success','warning','danger'] as $info)

12 @if(session()->has($info))

13

{{ session()->get($info) }}

14 @endif

15 @endforeach

16

17 @can('update',$question)

18 编辑

19 @endcan

20

21 @can('destroy',$question)

22

23 @csrf

24 @method('DELETE')

25 删除

26

27 @endcan

28

29 @forelse($question->topics as $topic)

30 {{ $topic->name }}

31 @empty

32

"No Topics"

33 @endforelse

34

35

已有{{ count($question->answers) }}个回答

36

37

38

39 {!! $question->content !!}

40

41

42

43

44 {{--回答提交form--}}

45 {{--只有登录用户可以提交回答--}}

46 @if(auth()->check())

47

48

49 提交回答

50

51

52

53 @csrf

54

55

57

@error('content') {{ $message }} @enderror

58

59 提交回答

60

61

62

63 @else

64 {{--显示请登录--}}

65 登录提交答案

66 @endif

67 {{--展示答案--}}

68 @forelse($question->answers as $answer)

69

70

71

72

73 style="height: 50px" alt="{{ $answer->user->name }}">

74 {{ $answer->user->name }}

75

76 {{ $answer->updated_at }}

77

78

79

80 {!! $answer->content !!}

81

82

83

84 @empty

85

86 @endforelse

87

88

89

90

91

92

{{ $question->followers_count }}

93 关注者

94

95

96

97

98

99 user="{{ auth()->user()->id }}"user()->id }}">

100

101

102

103

104

105

106

107 @endsection

108 @section('footer-js')

109 @include('questions._footer_js')

110 @endsection

111

112

api.php

QuestionController.php文件:

1 <?php

2

3 namespace App\Http\Controllers;

4

5 use App\Http\Requests\QuestionStoreRequest;

6 use App\Models\Question;

7 use App\Repositories\QuestionRepository;

8 use App\User;

9 use Illuminate\Http\Request;

10

11 class QuestionController extends Controller

12 {

13

14 /**

15 * @var QuestionRepository

16 */

17 private $questionRepository;

18

19 public function __construct(QuestionRepository $questionRepository)

20 {

21 $this->middleware(

22 'auth',

23 [

24 'except' =>

25 [

26 'index',

27 'show',

28 'followThroughApi'

29 ]//非注册用户只能查看不能编辑添加更改删除

30 ]

31 );

32

33 $this->questionRepository = $questionRepository;

34 }

35

36

37 /** Display a listing of the resource.

38 * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View

39 */

40 public function index()

41 {

42 //

43 $questions = $this->questionRepository->getQuestionPublished();

44 return view('questions.index', compact('questions'));

45 }

46

47

48 /**

49 * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View

50 */

51 public function create()

52 {

53 //

54 return view('questions.create');

55 }

56

57

58 /**

59 * @param QuestionStoreRequest $request

60 * @return \Illuminate\Http\RedirectResponse

61 */

62 public function store(QuestionStoreRequest $request)//依赖注入QuestionStoreRequest实例

63 {

64 //

65 // $data = $request->validate([

66 // 'title' => 'required|min:8',

67 // 'content' => 'required|min:28',

68 // ]);

69 //存储topics

70 $topics = $this->questionRepository->normalizeTopics($request->get('topics'));

71 //初始化question要用到的数据

72 $data = $request->all();

73 $data['user_id'] = auth()->user()->id;

74

75 // $question=Question::create($data); 被下方代码取代

76 $question = $this->questionRepository->create($data);

77

78 //使用我们再question model里面添加的topics方法获得 topics关联,再使用attach方法

79 $question->topics()->attach($topics);

80

81 return redirect()->route('questions.show', $question);

82 }

83

84

85 /**

86 * @param Question $question

87 * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View

88 */

89 public function show(Question $question)

90 {

91 //使用关系关联加载,with方法会将分类之下的主题一起查询出来,而且不会出现N+1影响性能的问题

92 $question->with('topics')->get();

93 //使用关系关联加载,with方法会将分类之下的回答一起查询出来,而且不会出现N+1影响性能的问题

94 $question->with('answers')->get();

95

96 return view('questions.show', compact('question'));

97 }

98

99

100 /**判断权限 返回视图

101 * @param Question $question

102 * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View

103 */

104 public function edit(Question $question)

105 {

106 if (auth()->user()->can('update', $question)) //判断当前用户是否有权编辑更新该question实例

107 {

108 //返回编辑视图

109 return view('questions.edit', compact('question'));

110 } else {

111 //返回警告 没有权限

112 return redirect()->back()->with('warning', '你不能编辑不属于你的问题!');

113 }

114 }

115

116

117 /** Update the specified resource in storage.

118 * @param QuestionStoreRequest $questionStoreRequest

119 * @param Question $question

120 * @return \Illuminate\Http\RedirectResponse

121 */

122 public function update(QuestionStoreRequest $questionStoreRequest, Question $question)

123 {

124 //更新前 判断下权限

125 if (!(auth()->user()->can('update', $question))) {

126 //返回警告 没有权限

127 return redirect()->back()->with('warning', '你不能编辑不属于你的问题!');

128 }

129 //取得更新的字段 使用Eloquent提供的update方法执行问题更新

130 $question->update([

131 'title' => $questionStoreRequest->get('title'),

132 'content' => $questionStoreRequest->get('content'),

133 ]);

134

135

136 //topics的操作这时候看起来有点臃肿 可以使用TopicController来管理,暂时省略

137 //存储topics

138 $topics = $this->questionRepository->normalizeTopics($questionStoreRequest->get('topics'));

139 //使用我们再question model里面添加的topics方法获得 topics关联,

140 //再使用sync方法同步tag 【删除的会被删除掉,没删除的就保留,新的就增加】

141 $question->topics()->sync($topics);

142

143 //更新完成,跳转回去

144 return redirect()->back();

145 }

146

147

148 /**Remove the specified resource from storage.

149 * @param Question $question

150 * @return \Illuminate\Http\RedirectResponse

151 * @throws \Exception

152 */

153 public function destroy(Question $question)

154 {

155 //

156 if (auth()->user()->can('destroy', $question)) {

157 $question->delete();

158 return redirect()->route('questions.index')->with('success', "删除成功!");

159 }

160 return redirect()->back()->with('danger', "你不能删除不属于你的问题!");

161 }

162

163

164 public function follow(Question $question)

165 {

166 if (auth()->user()->can('follow', $question)) //通过QuestionPolicy的follow方法判断用户是否可以关注问题

167 {

168 $message = "关注";

169 } else {

170 $message = "取关";

171 }

172 //同步记录

173 auth()->user()->followQuestions()->toggle($question);

174 $question->followers_count = $question->followUsers()->count();

175 $question->save();

176 return redirect()->back()->with('success', $message . '成功!');

177 }

178

179 public function followThroughApi(Request $request)

180 {

181 $user = User::find($request->get('user'));

182 $question = Question::find($request->get('question'));

183

184 if ($user->can('follow', $question)) {

185 $followable = false;

186 } else {

187 $followable = true;

188 }

189 //同步记录

190 $user->followQuestions()->toggle($question->id);

191 $question->followers_count = $question->followUsers()->count();

192 $question->update();

193 return response()->json([

194 'followable' => $followable,

195 ]);

196 }

197 }

198

QuestionController.php

QuestionPlolicy.php文件:

1 <?php

2

3 namespace App\Policies;

4

5 use App\Models\Question;

6 use App\User;

7 use Illuminate\Auth\Access\HandlesAuthorization;

8

9 class QuestionPolicy

10 {

11 use HandlesAuthorization;

12

13 /**

14 * Create a new policy instance.

15 *

16 * @return void

17 */

18 public function __construct()

19 {

20 //

21

22 }

23

24

25 /**

26 * 判断用户是否有权编辑更新问题

27 * @param User $user

28 * @param Question $question

29 * @return bool

30 */

31 public function update(User $user, Question $question)

32 {

33 return $user->id === $question->user_id;

34 }

35

36

37 /**

38 * 判断用户是否有权删除问题

39 * @param User $user

40 * @param Question $question

41 * @return bool

42 */

43 public function destroy(User $user, Question $question)

44 {

45 return $user->id === $question->user_id;

46 }

47

48

49 /** 用户是否可以关注问题,未登录不行,关注了不行

50 * @param User $user

51 * @param Question $question

52 * @return bool

53 */

54 public function follow(User $user, Question $question)

55 {

56 //axiox api 需要auth:api 先不实现,注释掉

57 // if (auth()->check()) {

58 // return !$user->followQuestions->contains('id', $question->id);

59 // } else {

60 // abort(401, "请登录");

61 // }

62 return !$user->followQuestions->contains('id', $question->id);

63 }

64 }

65

QuestionController.php

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值