django vue 实战


django vue 实战


1. vue部分

1.1. 项目创建

创建vue项目
在django_vue项目根目录下,新建一个前端工程目录:

vue-init webpack frontend

奇怪的是win+R打开cmd命令行可以找到vue,在当前路径下打开cmd找不到vue

在创建项目的过程中会弹出一些与项目相关的选项需要回答,按照真实情况进行输入即可。

安装 vue 依赖模块

cd frontend
cnpm install
cnpm install vue-resource
cnpm install element-ui

django项目目录下新增frontend目录
此处是为了方便,一般前端项目与后端项目位于各自单独的代码仓库。

项目结构释义
在frontend目录src下包含入口文件main.js,入口组件App.vue等。后缀为vue的文件是Vue.js框架定义的单文件组件,其中标签中的内容可以理解为是类html的页面结构内容。

1.2. 代码编辑

在src/component文件夹下新建一个名为Home.vue的组件,通过调用之前在Django上写好的api,实现添加书籍和展示书籍信息的功能。在样式组件上我们使用了饿了么团队推出的element-ui,这是一套专门匹配Vue.js框架的功能样式组件。由于组件的编码涉及到了很多js、html、css的知识,并不是本文的重点,因此在此只贴出部分代码:

Home.vue文件代码:

  
  

  

  
  

在src/router目录的index.js中,把新建的Home组件,配置到vue-router路由中:

  
import Vue from 'vue'  
import Router from 'vue-router'  
import Home from '@/components/Home'  

Vue.use(Router)  

export default new Router({  
  routes: [  
    {  
      path: '/',  
      name: 'Home',  
      component: Home  
    }  
  ]  
})  

在src/main.js文件中,导入element-ui、vue-resource库。

  
// The Vue build version to load with the `import` command  
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.  
import Vue from 'vue'  
import App from './App'  
import router from './router'  

import ElementUI from 'element-ui'  
import VueResource from 'vue-resource'  
import 'element-ui/lib/theme-chalk/index.css'  
Vue.use(ElementUI)  
Vue.use(VueResource)  
Vue.config.productionTip = false  

/* eslint-disable no-new */  
new Vue({  
  el: '#app',  
  router,  
  components: { App },  
  template: ''  
})  

跨域问题
因为端口不一,不同源,会出现跨域问题,需要在Django层注入header,用Django的第三方包django-cors-headers来解决跨域问题:

  
pip install django-cors-headers  

MIDDLEWARE = [  
    'django.middleware.security.SecurityMiddleware',  
    'django.contrib.sessions.middleware.SessionMiddleware',  
    'corsheaders.middleware.CorsMiddleware',  # cros 跨域 注意位置  
    'django.middleware.common.CommonMiddleware',  
    'django.middleware.csrf.CsrfViewMiddleware',  
    'django.contrib.auth.middleware.AuthenticationMiddleware',  
    'django.contrib.messages.middleware.MessageMiddleware',  
    'django.middleware.clickjacking.XFrameOptionsMiddleware',  
]  

CORS_ORIGIN_ALLOW_ALL = True  

PS: 注意中间件的添加顺序。

1.3. 运行测试

前端项目frontend目录下,输入npm run dev启动node自带的服务器,访问
http://localhost:8080/#/

功能验证:
在默认的nodejs下方会出现书藉列表
新增书藉 vue项目实战 成功。新增的书籍信息会实时反映到页面的列表中,这得益于Vue.js的数据双向绑定特性。

PS:如果不启动django后端,前端获取不到项目并不会报错,只是列表为空;实际是前后端分别运行于不同server下。

2. 前端项目部署

在前端工程frontend目录下,执行
npm run build

如果项目没有错误的话,就能够看到所有的组件、css、图片等都被webpack自动打包到dist目录下了:

3. 整合Django和Vue.js前端

目前已经分别完成了Django后端和Vue.js前端部分,但实际上它们是运行在各自的服务器上。需要让Django直接使用相应的模板及静态文件。

找到project目录的urls.py,使用通用视图创建最简单的模板控制器,访问 『/』时直接返回 index.html:

  
# settings.py  
# 声明扩展模板路径  
TEMPLATES = [  
    {  
        'BACKEND': 'django.template.backends.django.DjangoTemplates',  
        'DIRS': [os.path.join(BASE_DIR, 'templates'), os.path.join(BASE_DIR, 'frontend/dist')],  
        'APP_DIRS': True,  
# 声明扩展静态文件路径  
STATICFILES_DIRS = [  
    os.path.join(BASE_DIR, "frontend/dist/static"),  
]  

# app_demo下的路由urls.py  
urlpatterns = [  
    path(route='', view=views.index, name='index'),  
    path(route='hello/', view=views.hello, name='hello_page'),  
    path(r'f', view=views.index),  
    path('add/', view=views.add, name='add'),  
    path(r'ajax_list/', views.ajax_list, name='ajax_list'),  
    path(r'ajax_dict/', views.ajax_dict, name='ajax_dict'),  
    path('add_book', views.add_book),  
    path('show_books', views.show_books),  
    path(r'show', TemplateView.as_view(template_name='index.html'))  
]  

访问http://127.0.0.1:9001/demo/show#/
结果正常

web