前后端分离,Vue+restfullframework
一、准备
修改源:npm config set registry https://registry.npm.taobao.org
创建脚手架:
vue init webpack Vue项目名称
#Install router" title="vue-router">vue-router? Yes
插件:
npm install axiosaxios,发送Ajax请求
vuex,保存所有组件共用的变量
vue-cookies,操作cookie
二、流程
1、创建脚手架
npm config set registry https://registry.npm.taobao.orgvue init webpack
#吧route的那一个设置为yes,其他的设置为no
2、启动Vue
cd Vue项目名称npm run dev
3、显示组件
# 用于点击查看组件<router-link to="/index">首页</router-link>
# 组件显示的位置
<router-view/>
4、写路由
1 import Vue from 'vue'2 import Router from 'vue-router'
3 import Index from '@/components/Index'
4 import Login from '@/components/Login'
5 import Course from '@/components/Course'
6 import Micro from '@/components/Micro'
7 import News from '@/components/News'
8 import CourseDetail from '@/components/CourseDetail'
9 import NotFound from '@/components/NotFound'
10
11 Vue.use(Router)
12
13 export default new Router({
14 routes: [
15 {
16 path: '/',
17 name: 'index',
18 component: Index
19 },
20 {
21 path: '/index',
22 name: 'index',
23 component: Index
24 },
25 {
26 path: '/course',
27 name: 'course',
28 component: Course
29 },
30 {
31 path: '/course-detail/:id/',
32 name: 'courseDetail',
33 component: CourseDetail
34 },
35 {
36 path: '/micro',
37 name: 'micro',
38 component: Micro
39 },
40 {
41 path: '/news',
42 name: 'news',
43 component: News
44 },
45 {
46 path: '/login',
47 name: 'login',
48 component: Login
49 },
50 {
51 path: '*',
52 component: NotFound
53 }
54 ],
55 mode: 'history'
56 })
View Code
1 # 定义路由2 {
3 path: '/course-detail/:id/',
4 name: 'courseDetail',
5 component: CourseDetail
6 },
7 {
8 path: '/login',
9 name: 'login',
10 component: Login
11 },
12 {
13 path: '*',
14 component: NotFound
15 }
16
17
18 # router-link参数
19 <router-link :to="{'path':'/course-detail/'+item.id }">{{item.name}}</router-link>
20 <router-link to="/index">首页</router-link>
21
22 # 获取传过来的参数
23 this.$route.params.id
24 # 重定向
25 this.$router.push('/index')
26
View Code
注意:
如果不想在url显示#,可以在路由里面加上这样一个参数
mode: 'history'
5、写组件
1 <template>2
3 <div>
4 <h1>登录页面</h1>
5 <div>
6 <input type="text" v-model="username" placeholder="用户名">
7 <input type="text" v-model="password" placeholder="密码">
8 <a @click="doLogin">提交</a>
9 </div>
10 </div>
11 </template>
12
13 <script>
14
15 export default {
16 # 定义局部字段
17 data () {
18 return {
19 username: '',
20 password: ''
21 }
22 },
23 # 加载时执行
24 mounted:function(){
25 },
26 # 定义局部方法
27 methods:{
28 doLogin() {
29 var that = this
30 this.$axios.request({
31 url: 'http://127.0.0.1:8000/login/',
32 method: 'POST',
33 data: {
34 username: this.username,
35 password: this.password
36 },
37 responseType: 'json'
38 }).then(function (response) {
39 console.log(response.data)
40 // 找到全局变量,把用户名和token赋值到其中。
41 that.$store.commit('saveToken',response.data)
42 // 重定向到index
43 that.$router.push('/index')
44 })
45 }
46 }
47 }
48 </script>
49
50 <!-- Add "scoped" attribute to limit CSS to this component only -->
51 <style scoped>
52
53 </style>
View Code
6、发送ajax请求:axios
#发送ajax请求需要安装axios组件npm install axios
1 npm install axios2
3 main.js
4 import Vue from 'vue'
5 import App from './App'
6 import router from './router'
7
8 import axios from 'axios'
9
10 Vue.prototype.$axios = axios
11
12 Vue.config.productionTip = false
13 ...
14
15 组件使用:
16 this.$axios.request({
17 url: 'http://127.0.0.1:8000/login/',
18 method: 'POST',
19 data: {
20 username: this.username,
21 password: this.password
22 },
23 responseType: 'json'
24 }).then(function (response) {
25 console.log(response.data)
26
27 that.$router.push('/index')
28 })
29
30 PS:重定向 that.$router.push('/index')
View Code
7、vuex:保存所有组件共用的变量
安装npm install vuex
如果想用vuex需要做这么几件事:
- a、先创建一个文件夹,store----store.js
- b、要先使用就先导入
- c、实例化一个对象,并且让别人可以用
- d、这样每一个组件都可以用username和token了
1 npm install vuex2
3 main.js
4 import Vue from 'vue'
5 import App from './App'
6 import router from './router'
7 import axios from 'axios'
8
9 import store from './store/store' # vuex
10
11 Vue.prototype.$axios = axios
12
13 Vue.config.productionTip = false
14
15 /* eslint-disable no-new */
16 new Vue({
17 el: '#app',
18 store, # vuex
19 router,
20 components: { App },
21 template: '<App/>'
22 })
23
24 src/store/store.js
25 import Vue from 'vue'
26 import Vuex from 'vuex'
27 import Cookie from 'vue-cookies'
28
29 Vue.use(Vuex)
30
31 export default new Vuex.Store({
32 // 组件中通过 this.$store.state.username 调用
33 state: {
34 username: Cookie.get('username'),
35 token: Cookie.get('token')
36 },
37 mutations: {
38 // 组件中通过 this.$store.commit(参数) 调用
39 saveToken: function (state, data) {
40 state.username = data.username
41 state.token = data.token
42 Cookie.set('username', data.username, '20min')
43 Cookie.set('token', data.token, '20min')
44
45 },
46 clearToken: function (state) {
47 state.username = null
48 state.token = null
49 Cookie.remove('username')
50 Cookie.remove('token')
51 }
52 }
53 })
View Code
8、vue-cookies:操作cookie
安装npm install vue-cookies
1 npm install vue-cookies2
3
4 Cookie.get('username')
5
6 Cookie.set('username', data.username, '20min')
7 Cookie.remove('username')
8
9
10 src/store/store.js
11 import Vue from 'vue'
12 import Vuex from 'vuex'
13 import Cookie from 'vue-cookies' # vue-cookies
14
15 Vue.use(Vuex)
16
17 export default new Vuex.Store({
18 // 组件中通过 this.$store.state.username 调用
19 state: {
20 username: Cookie.get('username'), # vue-cookies
21 token: Cookie.get('token') # vue-cookies
22 },
23 mutations: {
24 // 组件中通过 this.$store.commit(参数) 调用
25 saveToken: function (state, data) {
26 state.username = data.username
27 state.token = data.token
28 Cookie.set('username', data.username, '20min') # vue-cookies
29 Cookie.set('token', data.token, '20min')
30
31 },
32 clearToken: function (state) {
33 state.username = null
34 state.token = null
35 Cookie.remove('username') # vue-cookies
36 Cookie.remove('token')
37 }
38 }
39 })
View Code
三、代码实现
前端代码:
1 <!DOCTYPE html>2 <html>
3 <head>
4 <meta charset="utf-8">
5 <meta name="viewport" content="width=device-width,initial-scale=1.0">
6 <link rel="stylesheet" href="./static/bootstrap-3.3.7-dist/css/bootstrap.css">
7 <script src="./static/bootstrap-3.3.7-dist/js/bootstrap.js"></script>
8
9 <title>s6vue</title>
10 </head>
11 <body>
12 <div id="app"></div>
13 <!-- built files will be auto injected -->
14 </body>
15 </html>
index.html
1 // The Vue build version to load with the `import` command2 // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3 import Vue from 'vue'
4 import App from './App'
5 import router from './router'
6 import store from './store/store' //
7 import axios from 'axios' // 要是用axios,就得先导入
8 Vue.prototype.$axios = axios //注册,以后就可以用$axios来定义了
9
10 Vue.config.productionTip = false
11
12 /* eslint-disable no-new */
13 new Vue({
14 el: '#app',
15 store,
16 router,
17 components: { App },
18 template: '<App/>'
19 })
main.js
1 <template>2 <div id="app">
3 <!--首页里面永远是固定的东西-->
4 <ul class="nav nav-tabs">
5 <li><router-link to="/index">首页</router-link> <!--用于点击查看组件--></li>
6 <li><router-link to="/micro">学位课</router-link> <!--用于点击查看组件--></li>
7 <li><router-link to="/course">课程</router-link></li> <!--用于点击查看组件-->
8 <li><router-link to="/news">深科技</router-link></li> <!--用于点击查看组件-->
9 <!--如果已经登录了,就不用在登录了,在页面还是显示当前用户和注销,如果没有登录就显示登录-->
10 <li v-if="this.$store.state.username">
11 <span><a>欢迎{{ this.$store.state.username }}登录</a></span>
12 <span><a @click="logout()">注销</a></span>
13 </li>
14 <li v-else=""> <router-link to="/login">登录</router-link></li>
15 </ul>
16 <router-view/> <!--组件显示的位置-->
17 </div>
18 </template>
19
20 <script>
21 export default {
22 name: 'App',
23 methods:{
24 logout(){
25 this.$store.state.username=''
26 this.$store.state.token=''
27 }
28 }
29 }
30 </script>
31
32 <style>
33
34
35 </style>
app.vue
1 import Vue from 'vue'2 import Router from 'vue-router'
3 import HelloWorld from '@/components/HelloWorld'
4 import Index from '@/components/Index'
5 import Login from '@/components/Login'
6 import Micro from '@/components/Micro'
7 import News from '@/components/News'
8 import Course from '@/components/Course'
9 import CourseDetail from '@/components/CourseDetail'
10 import NotFound from '@/components/NotFound'
11
12
13
14 Vue.use(Router)
15
16 export default new Router({
17 routes: [
18 {
19 path: '/',
20 name: 'HelloWorld',
21 component: HelloWorld
22 },
23 {
24 path: '/index',
25 name: 'index',
26 component: Index
27 },
28 {
29 path: '/login',
30 name: 'Login',
31 component: Login
32 },
33 {
34 path: '/course',
35 name: 'Course',
36 component: Course
37 },
38 {
39 path: '/course-detail/:id/',
40 name: 'CourseDetail',
41 component: CourseDetail
42 },
43 {
44 path: '/micro/',
45 name: 'Micro',
46 component: Micro
47 },
48 {
49 path: '/course-detail/:id/',
50 name: 'CourseDetail',
51 component: CourseDetail
52 },
53 {
54 path: '/news/',
55 name: 'News',
56 component: News
57 },
58 {
59 path: '*',
60 component: NotFound
61 }
62 ],
63 mode:'history'
64 })
router ---index.js
组件components
1 <template>2 <div class="hello">
3 <h1>{{ msg }}</h1>
4 </div>
5 </template>
6
7 <script>
8 export default {
9 name: 'index',
10 data () {
11 return {
12 msg:"这里是首页"
13 }
14 }
15 }
16 </script>
17
18 <!-- Add "scoped" attribute to limit CSS to this component only -->
19 <style>
20
21 </style>
Index.vue
1 <template>2 <div class="">
3 <h2>登录页面</h2>
4 <p>用户名:<input type="text" placeholder="username" v-model="username"></p>
5 <p>密码:<input type="text" placeholder="password" v-model="password"></p>
6 <button><a @click="DoLogin()">提交</a></button>
7 </div>
8 </template>
9
10 <script>
11 export default {
12 name: 'index',
13 data () {
14 return {
15 username: "",
16 password: ""
17 }
18 },
19 methods:{
20 DoLogin (){
21 var that = this
22 // console.log(this.$axios);
23 this.$axios.request({ //发送axios请求
24 url:'http://127.0.0.1:8082/login/', //请求路径
25 method:"POST",//请求方式
26 data:{ //要发送 的数据
27 username:this.username,
28 password:this.password
29 },
30 responseType:'json' //期望返回的类型是json的格式
31 }).then(function (response) { //吧返回的结果交给回调函数处理
32 //登录成功之后,找到全局变量,吧用户名和token赋值到其中
33 that.$store.commit('saveToken',response.data);
34 //重定向(登录成功之后让跳转到index页面)
35 that.$router.push('/index')
36 //为什么不直接用this呢?这里的this代表的是$axios,用that他代指的是整个Vue对象
37 })
38 }
39 }
40
41 }
42 </script>
43
44 <!-- Add "scoped" attribute to limit CSS to this component only -->
45 <style>
46
47 </style>
Login.vue
1 <template>2 <div class="">
3 <ul>
4 <li v-for="item in courseList">
5 <router-link :to="{'path':'/course-detail/'+item.id}">{{item.name}}</router-link>
6 </li>
7 </ul>
8 </div>
9 </template>
10
11 <script>
12 export default {
13 name: 'index',
14 data () {
15 return {
16 msg:'课程页面',
17 courseList:[]
18 }
19 },
20 mounted:function () {
21 //当组件一加载的时候就应该去数据库去获取数据
22 this.initCourses()
23 },
24 methods:{
25 initCourses:function () {
26 var that = this
27 this.$axios.request({
28 url:'http://127.0.0.1:8082/course/',
29 method:"GET"
30 }).then(function (response) {
31 console.log(response);
32 that.courseList = response.data.courseList //吧从数据库取的数据赋值到courseList列表里面
33 })
34 }
35 }
36
37 }
38
39 </script>
40
41 <!-- Add "scoped" attribute to limit CSS to this component only -->
42 <style>
43
44 </style>
course.vue
1 <template>2 <div class="hello">
3 <div>课程详细</div>
4 <h3>{{ title }}</h3>
5 <h3>{{ summary }}</h3>
6 </div>
7 </template>
8
9 <script>
10 export default {
11 name: 'HelloWorld',
12 data () {
13 return {
14 title:'',
15 summary:''
16 }
17 },
18 mounted:function () {
19 //当组件一加载就执行的函数
20 this.initCoursesDetail()
21 },
22 methods:{
23 initCoursesDetail(){
24 var nid = this.$route.params.id //获取id
25 var that = this
26 var url = 'http://127.0.0.1:8082/course/' + nid + '.json'
27 this.$axios.request({
28 url:url,
29 methods:'GET',
30 responseType:'json'
31 }).then(function (response) {
32 console.log(response)
33 that.title = response.data.title;
34 that.summary = response.data.summary
35 })
36 }
37 }
38 }
39 </script>
40
41 <!-- Add "scoped" attribute to limit CSS to this component only -->
42 <style scoped>
43
44 </style>
CoursesDetail
1 <template>2 <div class="hello">
3 <h2>欢迎报名学位课</h2>
4 </div>
5 </template>
6
7 <script>
8 export default {
9 name: 'HelloWorld',
10 data () {
11 return {
12 msg: 'Welcome to Your Vue.js App'
13 }
14 }
15 }
16 </script>
17
18 <!-- Add "scoped" attribute to limit CSS to this component only -->
19 <style scoped>
20 h1, h2 {
21 font-weight: normal;
22 }
23 ul {
24 list-style-type: none;
25 padding: 0;
26 }
27 li {
28 display: inline-block;
29 margin: 0 10px;
30 }
31 a {
32 color: #42b983;
33 }
34 </style>
Micro.vue
1 <template>2 <div class="hello">
3 <h2>深科技</h2>
4 </div>
5 </template>
6
7 <script>
8 export default {
9 name: 'HelloWorld',
10 data () {
11 return {
12 msg: 'Welcome to Your Vue.js App'
13 }
14 }
15 }
16 </script>
17
18 <!-- Add "scoped" attribute to limit CSS to this component only -->
19 <style scoped>
20 h1, h2 {
21 font-weight: normal;
22 }
23 ul {
24 list-style-type: none;
25 padding: 0;
26 }
27 li {
28 display: inline-block;
29 margin: 0 10px;
30 }
31 a {
32 color: #42b983;
33 }
34 </style>
News.vue
1 <template>2 <div class="hello">
3 <h1>找不到页面</h1>
4 </div>
5 </template>
6
7 <script>
8 export default {
9 name: 'HelloWorld',
10 data () {
11 return {
12 msg: 'Welcome to Your Vue.js App'
13 }
14 }
15 }
16 </script>
17
18 <!-- Add "scoped" attribute to limit CSS to this component only -->
19 <style scoped>
20 h1, h2 {
21 font-weight: normal;
22 }
23 ul {
24 list-style-type: none;
25 padding: 0;
26 }
27 li {
28 display: inline-block;
29 margin: 0 10px;
30 }
31 a {
32 color: #42b983;
33 }
34 </style>
NotFound
保存全局使用的变量store
1 import Vue from 'vue'2 import Vuex from 'vuex'
3 import Cookie from 'vue-cookies'
4
5 Vue.use(Vuex)
6
7
8 export default new Vuex.Store({
9 //组件中通过this.$store.state.username 调用
10 state:{
11 username:Cookie.get('username'),
12 token:Cookie.get('token')
13 },
14 mutations:{
15 //组件中通过this.$store.commit(参数)调用
16 saveToken:function (state,data) { //存放用户名和token的函数
17 state.username = data.username //data代指从后端返回过来的数据
18 state.token = data.token
19 Cookie.set('username',data.username,'20min') //吧用户名和token存放到cookie中
20 Cookie.set('token',data.token,'20min')
21 },
22 //清空token和cookie
23 clearToken:function (state) {
24 state.username=null
25 state.token= null
26 Cookie.remove('username')
27 Cookie.remove('token')
28 }
29 }
30 })
store.js
后端代码:
1 """day145vue和restful配合 URL Configuration2
3 The `urlpatterns` list routes URLs to views. For more information please see:
4 https://docs.djangoproject.com/en/1.11/topics/http/urls/
5 Examples:
6 Function views
7 1. Add an import: from my_app import views
8 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
9 Class-based views
10 1. Add an import: from other_app.views import Home
11 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
12 Including another URLconf
13 1. Import the include() function: from django.conf.urls import url, include
14 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
15 """
16 from django.conf.urls import url
17 from django.contrib import admin
18 from api import views
19 urlpatterns = [
20 url(r'^admin/', admin.site.urls),
21 url(r'^login/', views.LoginView.as_view()),
22 url(r'^course/$', views.CourseView.as_view()),
23 url(r'^course/(?P<pk>\d+)\.(?P<format>[a-z-9]+)$', views.CourseView.as_view()),
24 ]
urls.py
1 from django.shortcuts import render,HttpResponse2 from rest_framework.views import APIView
3 from rest_framework.response import Response
4 from django.http import JsonResponse
5
6
7 class LoginView(APIView):
8
9 def get(self,request,*args,**kwargs):
10 ret = {
11 'code':111,
12 'data':'在知识的海洋里一路向前'
13 }
14
15 response = JsonResponse(ret)
16 response['Access-Control-Allow-Origin']='*'
17 return response
18
19 def post(self,request,*args,**kwargs):
20 print(request.body) #在body里面有值
21 print(request.POST) #在post里面是没有值的
22 ret = {
23 'code':1000,
24 'username':'haiyn',
25 'token':'sdswr3fdfsdfdxqw2fgh',
26 }
27 response = JsonResponse(ret)
28 response['Access-Control-Allow-Origin'] = "*"
29 return response
30
31 def options(self, request, *args, **kwargs):
32 response = HttpResponse()
33 response['Access-Control-Allow-Origin'] = '*'
34 response['Access-Control-Allow-Headers'] = '*'
35 # response['Access-Control-Allo w-Methods'] = 'PUT'
36 return response
37
38
39 class CourseView(APIView):
40 def get(self,request,*args,**kwargs):
41 print(args,kwargs)
42 pk = kwargs.get('pk')
43 if pk:
44 print(kwargs.get('pk'))
45 ret = {
46 'title': "标题标题标题",
47 'summary': '老师,太饿了。怎么还不下课'
48 }
49 else:
50 ret = {
51 'code':1000,
52 'courseList':[
53 {'name':'人生苦短,来学Python','id':1},
54 {'name':'32天学会java,欢迎报名','id':2},
55 {'name':'人工智能即将统领世界...','id':3},
56 ]
57 }
58 response= JsonResponse(ret)
59 response['Access-Control-Allow-Origin'] = '*'
60 return response
views.py
一、准备
修改源:npm config set registry https://registry.npm.taobao.org
创建脚手架:
vue init webpack Vue项目名称
#Install vue-router? Yes
插件:
npm install axiosaxios,发送Ajax请求
vuex,保存所有组件共用的变量
vue-cookies,操作cookie
二、流程
1、创建脚手架
npm config set registry https://registry.npm.taobao.orgvue init webpack
#吧route的那一个设置为yes,其他的设置为no
2、启动Vue
cd Vue项目名称npm run dev
3、显示组件
# 用于点击查看组件<router-link to="/index">首页</router-link>
# 组件显示的位置
<router-view/>
4、写路由
1 import Vue from 'vue'2 import Router from 'vue-router'
3 import Index from '@/components/Index'
4 import Login from '@/components/Login'
5 import Course from '@/components/Course'
6 import Micro from '@/components/Micro'
7 import News from '@/components/News'
8 import CourseDetail from '@/components/CourseDetail'
9 import NotFound from '@/components/NotFound'
10
11 Vue.use(Router)
12
13 export default new Router({
14 routes: [
15 {
16 path: '/',
17 name: 'index',
18 component: Index
19 },
20 {
21 path: '/index',
22 name: 'index',
23 component: Index
24 },
25 {
26 path: '/course',
27 name: 'course',
28 component: Course
29 },
30 {
31 path: '/course-detail/:id/',
32 name: 'courseDetail',
33 component: CourseDetail
34 },
35 {
36 path: '/micro',
37 name: 'micro',
38 component: Micro
39 },
40 {
41 path: '/news',
42 name: 'news',
43 component: News
44 },
45 {
46 path: '/login',
47 name: 'login',
48 component: Login
49 },
50 {
51 path: '*',
52 component: NotFound
53 }
54 ],
55 mode: 'history'
56 })
View Code
1 # 定义路由2 {
3 path: '/course-detail/:id/',
4 name: 'courseDetail',
5 component: CourseDetail
6 },
7 {
8 path: '/login',
9 name: 'login',
10 component: Login
11 },
12 {
13 path: '*',
14 component: NotFound
15 }
16
17
18 # router-link参数
19 <router-link :to="{'path':'/course-detail/'+item.id }">{{item.name}}</router-link>
20 <router-link to="/index">首页</router-link>
21
22 # 获取传过来的参数
23 this.$route.params.id
24 # 重定向
25 this.$router.push('/index')
26
View Code
注意:
如果不想在url显示#,可以在路由里面加上这样一个参数
mode: 'history'
5、写组件
1 <template>2
3 <div>
4 <h1>登录页面</h1>
5 <div>
6 <input type="text" v-model="username" placeholder="用户名">
7 <input type="text" v-model="password" placeholder="密码">
8 <a @click="doLogin">提交</a>
9 </div>
10 </div>
11 </template>
12
13 <script>
14
15 export default {
16 # 定义局部字段
17 data () {
18 return {
19 username: '',
20 password: ''
21 }
22 },
23 # 加载时执行
24 mounted:function(){
25 },
26 # 定义局部方法
27 methods:{
28 doLogin() {
29 var that = this
30 this.$axios.request({
31 url: 'http://127.0.0.1:8000/login/',
32 method: 'POST',
33 data: {
34 username: this.username,
35 password: this.password
36 },
37 responseType: 'json'
38 }).then(function (response) {
39 console.log(response.data)
40 // 找到全局变量,把用户名和token赋值到其中。
41 that.$store.commit('saveToken',response.data)
42 // 重定向到index
43 that.$router.push('/index')
44 })
45 }
46 }
47 }
48 </script>
49
50 <!-- Add "scoped" attribute to limit CSS to this component only -->
51 <style scoped>
52
53 </style>
View Code
6、发送ajax请求:axios
#发送ajax请求需要安装axios组件npm install axios
1 npm install axios2
3 main.js
4 import Vue from 'vue'
5 import App from './App'
6 import router from './router'
7
8 import axios from 'axios'
9
10 Vue.prototype.$axios = axios
11
12 Vue.config.productionTip = false
13 ...
14
15 组件使用:
16 this.$axios.request({
17 url: 'http://127.0.0.1:8000/login/',
18 method: 'POST',
19 data: {
20 username: this.username,
21 password: this.password
22 },
23 responseType: 'json'
24 }).then(function (response) {
25 console.log(response.data)
26
27 that.$router.push('/index')
28 })
29
30 PS:重定向 that.$router.push('/index')
View Code
7、vuex:保存所有组件共用的变量
安装npm install vuex
如果想用vuex需要做这么几件事:
- a、先创建一个文件夹,store----store.js
- b、要先使用就先导入
- c、实例化一个对象,并且让别人可以用
- d、这样每一个组件都可以用username和token了
1 npm install vuex2
3 main.js
4 import Vue from 'vue'
5 import App from './App'
6 import router from './router'
7 import axios from 'axios'
8
9 import store from './store/store' # vuex
10
11 Vue.prototype.$axios = axios
12
13 Vue.config.productionTip = false
14
15 /* eslint-disable no-new */
16 new Vue({
17 el: '#app',
18 store, # vuex
19 router,
20 components: { App },
21 template: '<App/>'
22 })
23
24 src/store/store.js
25 import Vue from 'vue'
26 import Vuex from 'vuex'
27 import Cookie from 'vue-cookies'
28
29 Vue.use(Vuex)
30
31 export default new Vuex.Store({
32 // 组件中通过 this.$store.state.username 调用
33 state: {
34 username: Cookie.get('username'),
35 token: Cookie.get('token')
36 },
37 mutations: {
38 // 组件中通过 this.$store.commit(参数) 调用
39 saveToken: function (state, data) {
40 state.username = data.username
41 state.token = data.token
42 Cookie.set('username', data.username, '20min')
43 Cookie.set('token', data.token, '20min')
44
45 },
46 clearToken: function (state) {
47 state.username = null
48 state.token = null
49 Cookie.remove('username')
50 Cookie.remove('token')
51 }
52 }
53 })
View Code
8、vue-cookies:操作cookie
安装npm install vue-cookies
1 npm install vue-cookies2
3
4 Cookie.get('username')
5
6 Cookie.set('username', data.username, '20min')
7 Cookie.remove('username')
8
9
10 src/store/store.js
11 import Vue from 'vue'
12 import Vuex from 'vuex'
13 import Cookie from 'vue-cookies' # vue-cookies
14
15 Vue.use(Vuex)
16
17 export default new Vuex.Store({
18 // 组件中通过 this.$store.state.username 调用
19 state: {
20 username: Cookie.get('username'), # vue-cookies
21 token: Cookie.get('token') # vue-cookies
22 },
23 mutations: {
24 // 组件中通过 this.$store.commit(参数) 调用
25 saveToken: function (state, data) {
26 state.username = data.username
27 state.token = data.token
28 Cookie.set('username', data.username, '20min') # vue-cookies
29 Cookie.set('token', data.token, '20min')
30
31 },
32 clearToken: function (state) {
33 state.username = null
34 state.token = null
35 Cookie.remove('username') # vue-cookies
36 Cookie.remove('token')
37 }
38 }
39 })
View Code
三、代码实现
前端代码:
1 <!DOCTYPE html>2 <html>
3 <head>
4 <meta charset="utf-8">
5 <meta name="viewport" content="width=device-width,initial-scale=1.0">
6 <link rel="stylesheet" href="./static/bootstrap-3.3.7-dist/css/bootstrap.css">
7 <script src="./static/bootstrap-3.3.7-dist/js/bootstrap.js"></script>
8
9 <title>s6vue</title>
10 </head>
11 <body>
12 <div id="app"></div>
13 <!-- built files will be auto injected -->
14 </body>
15 </html>
index.html
1 // The Vue build version to load with the `import` command2 // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3 import Vue from 'vue'
4 import App from './App'
5 import router from './router'
6 import store from './store/store' //
7 import axios from 'axios' // 要是用axios,就得先导入
8 Vue.prototype.$axios = axios //注册,以后就可以用$axios来定义了
9
10 Vue.config.productionTip = false
11
12 /* eslint-disable no-new */
13 new Vue({
14 el: '#app',
15 store,
16 router,
17 components: { App },
18 template: '<App/>'
19 })
main.js
1 <template>2 <div id="app">
3 <!--首页里面永远是固定的东西-->
4 <ul class="nav nav-tabs">
5 <li><router-link to="/index">首页</router-link> <!--用于点击查看组件--></li>
6 <li><router-link to="/micro">学位课</router-link> <!--用于点击查看组件--></li>
7 <li><router-link to="/course">课程</router-link></li> <!--用于点击查看组件-->
8 <li><router-link to="/news">深科技</router-link></li> <!--用于点击查看组件-->
9 <!--如果已经登录了,就不用在登录了,在页面还是显示当前用户和注销,如果没有登录就显示登录-->
10 <li v-if="this.$store.state.username">
11 <span><a>欢迎{{ this.$store.state.username }}登录</a></span>
12 <span><a @click="logout()">注销</a></span>
13 </li>
14 <li v-else=""> <router-link to="/login">登录</router-link></li>
15 </ul>
16 <router-view/> <!--组件显示的位置-->
17 </div>
18 </template>
19
20 <script>
21 export default {
22 name: 'App',
23 methods:{
24 logout(){
25 this.$store.state.username=''
26 this.$store.state.token=''
27 }
28 }
29 }
30 </script>
31
32 <style>
33
34
35 </style>
app.vue
1 import Vue from 'vue'2 import Router from 'vue-router'
3 import HelloWorld from '@/components/HelloWorld'
4 import Index from '@/components/Index'
5 import Login from '@/components/Login'
6 import Micro from '@/components/Micro'
7 import News from '@/components/News'
8 import Course from '@/components/Course'
9 import CourseDetail from '@/components/CourseDetail'
10 import NotFound from '@/components/NotFound'
11
12
13
14 Vue.use(Router)
15
16 export default new Router({
17 routes: [
18 {
19 path: '/',
20 name: 'HelloWorld',
21 component: HelloWorld
22 },
23 {
24 path: '/index',
25 name: 'index',
26 component: Index
27 },
28 {
29 path: '/login',
30 name: 'Login',
31 component: Login
32 },
33 {
34 path: '/course',
35 name: 'Course',
36 component: Course
37 },
38 {
39 path: '/course-detail/:id/',
40 name: 'CourseDetail',
41 component: CourseDetail
42 },
43 {
44 path: '/micro/',
45 name: 'Micro',
46 component: Micro
47 },
48 {
49 path: '/course-detail/:id/',
50 name: 'CourseDetail',
51 component: CourseDetail
52 },
53 {
54 path: '/news/',
55 name: 'News',
56 component: News
57 },
58 {
59 path: '*',
60 component: NotFound
61 }
62 ],
63 mode:'history'
64 })
router ---index.js
组件components
1 <template>2 <div class="hello">
3 <h1>{{ msg }}</h1>
4 </div>
5 </template>
6
7 <script>
8 export default {
9 name: 'index',
10 data () {
11 return {
12 msg:"这里是首页"
13 }
14 }
15 }
16 </script>
17
18 <!-- Add "scoped" attribute to limit CSS to this component only -->
19 <style>
20
21 </style>
Index.vue
1 <template>2 <div class="">
3 <h2>登录页面</h2>
4 <p>用户名:<input type="text" placeholder="username" v-model="username"></p>
5 <p>密码:<input type="text" placeholder="password" v-model="password"></p>
6 <button><a @click="DoLogin()">提交</a></button>
7 </div>
8 </template>
9
10 <script>
11 export default {
12 name: 'index',
13 data () {
14 return {
15 username: "",
16 password: ""
17 }
18 },
19 methods:{
20 DoLogin (){
21 var that = this
22 // console.log(this.$axios);
23 this.$axios.request({ //发送axios请求
24 url:'http://127.0.0.1:8082/login/', //请求路径
25 method:"POST",//请求方式
26 data:{ //要发送 的数据
27 username:this.username,
28 password:this.password
29 },
30 responseType:'json' //期望返回的类型是json的格式
31 }).then(function (response) { //吧返回的结果交给回调函数处理
32 //登录成功之后,找到全局变量,吧用户名和token赋值到其中
33 that.$store.commit('saveToken',response.data);
34 //重定向(登录成功之后让跳转到index页面)
35 that.$router.push('/index')
36 //为什么不直接用this呢?这里的this代表的是$axios,用that他代指的是整个Vue对象
37 })
38 }
39 }
40
41 }
42 </script>
43
44 <!-- Add "scoped" attribute to limit CSS to this component only -->
45 <style>
46
47 </style>
Login.vue
1 <template>2 <div class="">
3 <ul>
4 <li v-for="item in courseList">
5 <router-link :to="{'path':'/course-detail/'+item.id}">{{item.name}}</router-link>
6 </li>
7 </ul>
8 </div>
9 </template>
10
11 <script>
12 export default {
13 name: 'index',
14 data () {
15 return {
16 msg:'课程页面',
17 courseList:[]
18 }
19 },
20 mounted:function () {
21 //当组件一加载的时候就应该去数据库去获取数据
22 this.initCourses()
23 },
24 methods:{
25 initCourses:function () {
26 var that = this
27 this.$axios.request({
28 url:'http://127.0.0.1:8082/course/',
29 method:"GET"
30 }).then(function (response) {
31 console.log(response);
32 that.courseList = response.data.courseList //吧从数据库取的数据赋值到courseList列表里面
33 })
34 }
35 }
36
37 }
38
39 </script>
40
41 <!-- Add "scoped" attribute to limit CSS to this component only -->
42 <style>
43
44 </style>
course.vue
1 <template>2 <div class="hello">
3 <div>课程详细</div>
4 <h3>{{ title }}</h3>
5 <h3>{{ summary }}</h3>
6 </div>
7 </template>
8
9 <script>
10 export default {
11 name: 'HelloWorld',
12 data () {
13 return {
14 title:'',
15 summary:''
16 }
17 },
18 mounted:function () {
19 //当组件一加载就执行的函数
20 this.initCoursesDetail()
21 },
22 methods:{
23 initCoursesDetail(){
24 var nid = this.$route.params.id //获取id
25 var that = this
26 var url = 'http://127.0.0.1:8082/course/' + nid + '.json'
27 this.$axios.request({
28 url:url,
29 methods:'GET',
30 responseType:'json'
31 }).then(function (response) {
32 console.log(response)
33 that.title = response.data.title;
34 that.summary = response.data.summary
35 })
36 }
37 }
38 }
39 </script>
40
41 <!-- Add "scoped" attribute to limit CSS to this component only -->
42 <style scoped>
43
44 </style>
CoursesDetail
1 <template>2 <div class="hello">
3 <h2>欢迎报名学位课</h2>
4 </div>
5 </template>
6
7 <script>
8 export default {
9 name: 'HelloWorld',
10 data () {
11 return {
12 msg: 'Welcome to Your Vue.js App'
13 }
14 }
15 }
16 </script>
17
18 <!-- Add "scoped" attribute to limit CSS to this component only -->
19 <style scoped>
20 h1, h2 {
21 font-weight: normal;
22 }
23 ul {
24 list-style-type: none;
25 padding: 0;
26 }
27 li {
28 display: inline-block;
29 margin: 0 10px;
30 }
31 a {
32 color: #42b983;
33 }
34 </style>
Micro.vue
1 <template>2 <div class="hello">
3 <h2>深科技</h2>
4 </div>
5 </template>
6
7 <script>
8 export default {
9 name: 'HelloWorld',
10 data () {
11 return {
12 msg: 'Welcome to Your Vue.js App'
13 }
14 }
15 }
16 </script>
17
18 <!-- Add "scoped" attribute to limit CSS to this component only -->
19 <style scoped>
20 h1, h2 {
21 font-weight: normal;
22 }
23 ul {
24 list-style-type: none;
25 padding: 0;
26 }
27 li {
28 display: inline-block;
29 margin: 0 10px;
30 }
31 a {
32 color: #42b983;
33 }
34 </style>
News.vue
1 <template>2 <div class="hello">
3 <h1>找不到页面</h1>
4 </div>
5 </template>
6
7 <script>
8 export default {
9 name: 'HelloWorld',
10 data () {
11 return {
12 msg: 'Welcome to Your Vue.js App'
13 }
14 }
15 }
16 </script>
17
18 <!-- Add "scoped" attribute to limit CSS to this component only -->
19 <style scoped>
20 h1, h2 {
21 font-weight: normal;
22 }
23 ul {
24 list-style-type: none;
25 padding: 0;
26 }
27 li {
28 display: inline-block;
29 margin: 0 10px;
30 }
31 a {
32 color: #42b983;
33 }
34 </style>
NotFound
保存全局使用的变量store
1 import Vue from 'vue'2 import Vuex from 'vuex'
3 import Cookie from 'vue-cookies'
4
5 Vue.use(Vuex)
6
7
8 export default new Vuex.Store({
9 //组件中通过this.$store.state.username 调用
10 state:{
11 username:Cookie.get('username'),
12 token:Cookie.get('token')
13 },
14 mutations:{
15 //组件中通过this.$store.commit(参数)调用
16 saveToken:function (state,data) { //存放用户名和token的函数
17 state.username = data.username //data代指从后端返回过来的数据
18 state.token = data.token
19 Cookie.set('username',data.username,'20min') //吧用户名和token存放到cookie中
20 Cookie.set('token',data.token,'20min')
21 },
22 //清空token和cookie
23 clearToken:function (state) {
24 state.username=null
25 state.token= null
26 Cookie.remove('username')
27 Cookie.remove('token')
28 }
29 }
30 })
store.js
后端代码:
1 """day145vue和restful配合 URL Configuration2
3 The `urlpatterns` list routes URLs to views. For more information please see:
4 https://docs.djangoproject.com/en/1.11/topics/http/urls/
5 Examples:
6 Function views
7 1. Add an import: from my_app import views
8 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
9 Class-based views
10 1. Add an import: from other_app.views import Home
11 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
12 Including another URLconf
13 1. Import the include() function: from django.conf.urls import url, include
14 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
15 """
16 from django.conf.urls import url
17 from django.contrib import admin
18 from api import views
19 urlpatterns = [
20 url(r'^admin/', admin.site.urls),
21 url(r'^login/', views.LoginView.as_view()),
22 url(r'^course/$', views.CourseView.as_view()),
23 url(r'^course/(?P<pk>\d+)\.(?P<format>[a-z-9]+)$', views.CourseView.as_view()),
24 ]
urls.py
1 from django.shortcuts import render,HttpResponse2 from rest_framework.views import APIView
3 from rest_framework.response import Response
4 from django.http import JsonResponse
5
6
7 class LoginView(APIView):
8
9 def get(self,request,*args,**kwargs):
10 ret = {
11 'code':111,
12 'data':'在知识的海洋里一路向前'
13 }
14
15 response = JsonResponse(ret)
16 response['Access-Control-Allow-Origin']='*'
17 return response
18
19 def post(self,request,*args,**kwargs):
20 print(request.body) #在body里面有值
21 print(request.POST) #在post里面是没有值的
22 ret = {
23 'code':1000,
24 'username':'haiyn',
25 'token':'sdswr3fdfsdfdxqw2fgh',
26 }
27 response = JsonResponse(ret)
28 response['Access-Control-Allow-Origin'] = "*"
29 return response
30
31 def options(self, request, *args, **kwargs):
32 response = HttpResponse()
33 response['Access-Control-Allow-Origin'] = '*'
34 response['Access-Control-Allow-Headers'] = '*'
35 # response['Access-Control-Allo w-Methods'] = 'PUT'
36 return response
37
38
39 class CourseView(APIView):
40 def get(self,request,*args,**kwargs):
41 print(args,kwargs)
42 pk = kwargs.get('pk')
43 if pk:
44 print(kwargs.get('pk'))
45 ret = {
46 'title': "标题标题标题",
47 'summary': '老师,太饿了。怎么还不下课'
48 }
49 else:
50 ret = {
51 'code':1000,
52 'courseList':[
53 {'name':'人生苦短,来学Python','id':1},
54 {'name':'32天学会java,欢迎报名','id':2},
55 {'name':'人工智能即将统领世界...','id':3},
56 ]
57 }
58 response= JsonResponse(ret)
59 response['Access-Control-Allow-Origin'] = '*'
60 return response
views.py
以上是 前后端分离,Vue+restfullframework 的全部内容, 来源链接: utcz.com/z/379996.html