vue-cli创建项目

  1. 前端工程化,项目>>>(vue-cli),创建处vue项目,单页面应用(spa)
  2. vue-cli创建项目开发,在项目中开发,最后上线,一定要编译
  3. '纯粹的html,js,css'

vue-cli工具由于是nodejs编写的,所以我们需要node安装环境
1.下载node解释器

  1. 官网下载对应平台的nodejs解释器,一路下一步
  2. -安装后会自动添加环境变量:可执行文件路径 就在环境变量
  3. -下载完成后我们打开cmd,就可以运行node,他的使用和安装模块的命令,类似python的两个命令(这两个命令来自两个可执行文件):
  4. -node 类似cmdpython命令
  5. -npm 类似cmd中的pip命令

nodejs官网:http://nodejs.cn/

vue-cli项目创建

  1. vue版本不同可以使用不同的项目脚手架
  2. 2.x 使用vue-cli https://cli.vuejs.org/zh/
  3. 3.x 使用vue-cli
  4. 3.x版本的vue项目还可以使用vite创建,vite 效率非常高,但不支持2.x版本的vue项目

1.安装cnpm工具

  • 我们的nodejs自带的npm工具,npm会从国外的站点下载,速度慢
  • cnpm是淘宝出的工具,下载的时候,去淘宝镜像下载,速度快,
  • 以后使用cnpm 代替npm
    npm install -g cnpm --registry=https://registry.npm.taobao.org

2.安装脚手架(vue-cli)
cnpm install -g @vue/cli

-g表示全局(全局变量)
安装完成后,cmd控制台就可以输入 vue 命令了(类似装了djagno可以使用django-admin创建django项目

  • 如果遇到速度特别慢的情况,可以使用 清空缓存处理(如果安装失败,需要执行清除缓存,再重新安装,创建项目时也是一样的流程)
    npm cache clean --force

3.使用vue-cli创建项目

  • 在输入命令执行之前需要自行选择创建项目的路径
  • 速度可能会很慢,可以等,也可以ctrl+c停止(停止后如果需要重新创建,需要执行npm cache clean --force)
  • 很慢的原因:
    1.因为vue-cli需要很多依赖(下载的东西比较多)
    2.需要从github上拉空项目

输入命令:
vue create myfirstvue

如果出现上图情况,y继续即可
执行命令结束会进入到选择界面

  • 上下键进行选择,回车键确定
  • 这里我们选择最后一个选项,前面两个默认选项由于使用了eslint会对代码进行格式化,比如我们如果漏写了分号,会报错,但是运行的时候其实并不影响
  • 如果我们之前选择自定义并且进行了保存,这里也会展示出来的

配置选择

  • 选择vue版本

  • 历史模式选择

  • 选择项目依赖安装位置

  • 是否保存当前配置

  • 输入保存后名称

  • 创建成功如下图所示

博客参考:https://www.cnblogs.com/zhihuanzzh/p/17137995.html

vue项目目录介绍

  1. # vue 项目目录介绍
  2. myfirstvue # 项目名
  3. node_modules # 非常多第三方模块,以后把项目复制给别人时【上传git要忽略掉】,这个文件夹删掉,很多小文件,项目的依赖,项目要运行,没有它不行 如果没有只需要执行 cnpm install,根据package.json的依赖包,按装好依赖、
  4. public # 文件夹
  5. -favicon.ico # 网站小图标(浏览器上方的略缩图)
  6. -index.html # spa 单页面应用,以后整个vue项目都是用这一个html,但你不用动他
  7. src # 文件夹--以后咱们都动这里面的
  8. -assets # 静态资源,以后前端用的图片,js,css。。都放在这里
  9. logo.png # 图片(我们访问的欢迎页面中的那个图片就是这个)
  10. -components # 以后在这里放组件, xx.vue, 小组件
  11. HelloWorld.vue # 提供的展示组件
  12. -router # 安装了Router,就会有这个文件夹,下面有个index.js
  13. index.js
  14. -store # 安装了Vuex,就会有这个文件夹,下面有个index.js
  15. -index.js
  16. -views # 页面组件
  17. -AboutView.vue
  18. -HomeView.vue
  19. -App.vue # 根组件,new Vue实例管理了 div,以后原来写在div中的东西,现在都写在App.vue
  20. -main.js # 项目的启动入口
  21. .gitignore # git的忽略文件,后面学了git就会了
  22. babel.config.js # bable配置文件,不用动
  23. jsconfig.json # 配置文件,不用动
  24. package.json
  25. # 不用动,安装了第三方模块,它自动增加
  26. # 内部的信息中有name属性,这就是我们项目的名称,项目启动后可以在浏览器的上方看到
  27. # name属性的下方,还有一个scripts属性,内部有一个serve键值对,这个serve就是对应:npm run serve中的serve的,如果我们在这里进行了更改,启动项目的命令也需要更改
  28. # 下方的dependencies中配置了项目所需模块的版本信息,版本前面的‘^’号表示的是可以往更高版本兼容,但实际使用的时候通常不这么设置(高版本容易出兼容性问题)
  29. package-lock.json # 锁定文件,忽略掉
  30. README.md # 用户手册
  31. vue.config.js # vue的配置文件

es6导入导出语法

App.vue,main.js是什么

  1. ### 看xx.vue 组件学到的重点#########
  2. # 记住,以后开发vue项目,都按照这个模式来
  3. 1 新建xx.vue(创建新的组件页面组件)
  4. 2 xx.vue中就三块内容
  5. #1 以后组件的html内容,都写在这里
  6. <template>
  7. </template>
  8. #2 以后该组件使用的样式,都写在这
  9. <style>
  10. </style>
  11. # 3 以后js的东西,都写在这
  12. <script>
  13. </script>
  14. #### main.js 学到的
  15. # 找到index.html 中的id为app的div,以后都在App.vue中写(相当于我们之前在html中编写vue时的el属性)
  16. new Vue({
  17. render: h => h(App)
  18. }).$mount('#app')
  • python中创建包,可以在其他py文件中导入
  • js 从es6开始,也支持包的导入和导出
  • 我们编写下方的代码时需要创建一个文件夹,在文件夹内创建一个js文件,在他的内部编写vue代码,为了使这个代码生效我们需要在main.js中进行导入

默认导出语法(使用的多)

  1. -导出语法
  2. export default 一般是个对象
  3. -导入语法
  4. import 别名 from '路径'
  5. 以后 别名 就是 导出的对象

命名导入导出语法(了解)
命名导出语法可以写多个,这样就可以导出多个变量
导出的导入的时候需要用大括号包裹导入的变量,并用逗号隔开,需要什么变量就导入什么变量
ps:导出的时候需要注意,const定义的导出的变量名不能跟前面代码中的变量名重复,会报错

导入的简写形式

  • 包下的 index.js 导入的时候,不用具体到index.js的路径
  • 它等同于ptyhon的init.py
  1. -例如:
  2. # 包是
  3. xiaoming
  4. -index.js
  5. #导入的时候
  6. import xiaoming from './xiaoming'
vue项目编写步骤
  1. # 1 以后只需要写xx.vue
  2. -页面组件(views文件夹内创建)
  3. -小组件 给页面组件用的(components文件夹内创建)
  4. # 2 组件中导出
  5. 'HelloWorld.vue组件导出后,导入到HomeView.vue组件中(小组件导入到页面组件中)'
  6. '如果组件内部定义了变量需要用data来接收,但是要写成方法return值'
  7. export default {
  8. name: 'HelloWorld',
  9. data() {
  10. return {
  11. xx: '彭于晏'
  12. }
  13. },
  14. props: {
  15. msg: String
  16. }
  17. }
  18. '如果外面有自定义属性就需要用props来接收'
  19. <HelloWorld msg="Welcome to Your Vue.js App"/>
  20. # 3 组件如果要在别的组件中使用,需要导入、注册
  21. '这里也是以HelloWorld.vue组件导入到HomeView.vue组件中为例子'
  22. # 导入
  23. import HelloWorld from '@/components/HelloWorld.vue'
  24. # 这里的@符号就是指代src文件夹
  25. import HelloWorld from '../components/HelloWorld.vue'
  26. # 注册
  27. export default {
  28. components: {
  29. HelloWorld
  30. }
  31. }
  32. # 4 注册以后,在这个组件中就可以使用导入的组件 ,写在<template>
  33. # 自定义属性
  34. '可以写但个标签,也可以写两个标签进行包裹,包裹后内部可以用更多的操作,比如插值语法'
  35. <HelloWorld msg="传进来的p"/>

props配置项

  1. props配置项在里面写接受父传子自定义的属性
  2. # props配置项有三种写法:
  3. -1 数组写法
  4. -2 对象对象写法
  5. -3 对象套对象写法
  6. # 写法总结
  7. # 方式一:使用数组
  8. props: ['msg'],
  9. # 方式二:使用对象
  10. props: {msg: String}, // 属性验证
  11. # 方式三:使用对象,指定类型、默认值和必填
  12. props: {
  13. msg: {
  14. type: String, //类型
  15. required: true, //必要性
  16. default: '老王' //默认值
  17. }
  18. }
props使用
  • 新建组件child.vue
  • 在根组件app中引入child.vue,并注册(在components中)
  • 根组件可以通过自定属性进行父传子(可以写多个自定义属性)
  • 子组件通过props配置项接收数据(数组写法/对象写法)
  • 可以进行属性的验证,虽然会在前端控制台报错(不影响正常显示)

Mixin混入

  1. # mixin(混入) 可以把多个组件共用的配置提取成一个混入对象
  2. -把多个组件中公用的东西,抽取出来,以后可以全局使用和局部使用
  3. # 使用步骤
  4. -1 定义混入对象,新建mixin包,下新建index.js
  5. -2 index.js中写代码(组件中会用到的,比如datamethods、配置项)
  6. export const hunhe = {
  7. data() {
  8. return {
  9. name: '彭于晏'
  10. }
  11. },
  12. methods: {
  13. handlePrintName() {
  14. alert(this.name)
  15. }
  16. },
  17. }
  18. -3 局部导入:在组件中
  19. import {hunhe} from "@/mixin";
  20. # 配置项:
  21. mixins:[hunhe,]
  22. -4 全局使用,在main.js 以后所有组件都可以用
  23. import {hunhe} from "@/mixin";
  24. Vue.mixin(hunhe)
  25. // Vue.mixin(lqz2) 多个混入需要注册多次
  26. // Vue.mixin(lqz3)
  27. -5 在组件中,直接使用即可
局部使用mixins
  • 新建组件并将其导入到根组件中
  • 编写根组件代码/编写子组件代码
  • 根组件和子组件有相同的(数据/方法)
  • 在src目录下新建mixin文件夹并且在其中新建index.js编写相同的(数据/方法)
  • 我们就可以在子组件/父组件 中配置项配置mixin,导入共同拥有的(数据/方法)

注意:如上示例中,混入导入的和methods中的函数都是同一个名字。
直接说结论:先使用methods中的函数,如果在methods中找不到,再用mixins的。
扩展:
混入不仅仅可以抽取methods中的函数,还可以抽取data()数据。
查找顺序和之前的一样,先使用组件自己的数据,如果没有数据,再去mixins中找数据。
create()这种生命周期钩子函数也可以抽取到mixins。

全局引用mixin

需要在main.js中导入mixin包:

全局引入之后,相当于在所有组件中都加入了mixins配置项,所有组件就都可以使用混入的函数和数据了。
mixins具体使用情景:
比如有一个记录用户浏览记录的功能,通过引入mxins,可以实现在每个组件都可以使用这个功能。

插件

  1. # 功能:用于增强Vue
  2. 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据
  3. - elementui相当于是Vue的插件
  4. # 使用步骤
  5. -新建包plugins,新建index.js
  6. import Vue from "vue";
  7. import axios from "axios";
  8. import {hunhe} from '@/mixin'
  9. export default {
  10. install(miVue) {
  11. // console.log(miVue)
  12. // 1 vue 实例上放个变量
  13. // Vue.prototype.$name = 'lqz' // 类比python,在类上放了一个属性,所有对象都能取到
  14. // Vue.prototype.$ajax = axios
  15. // 2 使用插件,加入混入
  16. // 全局使用混入
  17. // Vue.mixin(hunhe)
  18. // 3 定义全局组件
  19. // 4 定义自定义指令 v-lqz
  20. Vue.directive("fbind", {
  21. //指令与元素成功绑定时(一上来)
  22. bind(element, binding) {
  23. element.value = binding.value;
  24. },
  25. //指令所在元素被插入页面时
  26. inserted(element, binding) {
  27. element.focus();
  28. },
  29. //指令所在的模板被重新解析时
  30. update(element, binding) {
  31. element.value = binding.value;
  32. },
  33. });
  34. }
  35. }
  36. 2 main.js 中使用插件
  37. import plugins from '@/plugins'
  38. Vue.use(plugins) // 本子,使用use,会自动触发插件对象中得install
  39. 3 以后再组件中可以直接用插件中写的东西
  40. # 插件可以做的事:
  41. 1 了解,自定义指令(不了解没关系)
  42. 2 定义全局变量,以后在任何组件中都可以使用到,借助于Vue.prototype往里放 ,以后所有组件只要this.$ajax 就是axios对象
  43. 3 使用全局混入
  44. 4 自定义全局组件
使用插件给Vue对象添加属性
  • 在src目录中新建plugings文件夹,并且新建index.js文件在其中
  • 在index.js文件中编写代码

插件是包含install方法的一个对象。如上图我们在index.js导出这个对象。install方法的第一个参数是Vue实例,第二个以后的参数是插件使用者传递的数据
需求:在Vue实例上存放一个变量,在任意位置通过this.变量名就可以获取到这个变量的数据。(本质上增强了Vue的功能)
导入Vue,这里的Vue是源码中的Vue构造函数(把他当作python中的类)

在Vue类上存放了一个属性$name,以后Vue类产生的对象,都可以拿到这个属性。
使用插件,在main.js中导入插件

并且使用对插件使用Vue.use(),相当于自动触发插件对象中的install方法。Vue.use()会给自动插件的第一个参数传入Vue构造方法(相当于python中的类)。
还可以给插件传更多的参数如:Vue.use(plugins, 1, '你好')
在插件中接收参数

在根组件里打印this:

这个this是当前的组件对象。查看控制台,发现并没有我们添加的$name属性。
那到底如何使用插件,给Vue对象添加属性呢?使用原型prototype。
修改插件代码:

这里有个类似python中属性查找属性的问题。我们使用Vue.prototype.$name='lqz'将属性放入prototype。Vue对象查找属性时,会先在自己身上找,如果找不到,就会去prototype找$name属性。prototype类比python中的类。
使用插件引入axios:

这样写,在任意页面都可以通过this.$ajax直接使用axios,不用每次使用都导入了

为什么属性的名字前,都需要加一个$?

防止和组件内部的属性名冲突。

插件配合混入

之前我们是在main.js使用Vue.mixin()实现全局混入。
通过插件实现全局混入:
也相当于所有组件都添加了mixin配置项。

在插件定义全局组件


elementui插件定义很多全局组件,我们可以直接使用:

scoped

  1. # 父组件写了style,子组件都会使用父组件的style
  2. 如果在根组件中写了样式,会在所有页面组件都生效,这样不太好,所有需要使用scoped
  3. # 父组件的样式,在子组件中会生效,在style上写 <style scoped>
  4. # </style>让该样式只在当前组件中生效
  5. # 示例
  6. <style scoped>
  7. h1 {
  8. background-color: chartreuse;
  9. }
  10. </style>

localStorage和sessionStorage

  1. # 是window浏览器对象(BOM)有的东西
  2. localStoragesessionStorageVue没有必然联系。
  3. # 如果想在浏览器中存储数据:
  4. 有三个地方:
  5. 1.永久存储:localStorage 不登录加购物车,没登录 搜索过的商品
  6. 2.临时存储:sessionStorage 关闭页面数据就没了
  7. 3.设定一个时间,到时候就过期:cookie
  8. # 补充:序列化和反序列化
  9. // 对象转json字符串
  10. // JSON.stringify(person)
  11. // json字符串转对象
  12. // JSON.parse()
  13. # 都是在浏览器存储数据的--》存数据有什么用?
  14. -登录成功 token存在本地
  15. -不登录加入购物车功能,迪卡侬存在了localStorage
  16. -组件间通信----》 跨组件
  17. # localStorage
  18. -永久存储,除非清空缓存,手动删除,代码删除
  19. -localStorage.setItem('userinfo', JSON.stringify(this.userInfo))
  20. -localStorage.getItem('userinfo')
  21. -localStorage.clear() // 清空全部
  22. -localStorage.removeItem('userinfo')
  23. # sessionStorage
  24. -关闭浏览器,自动清理
  25. -sessionStorage.setItem('userinfo', JSON.stringify(this.userInfo))
  26. -sessionStorage.getItem('userinfo')
  27. -sessionStorage.clear() // 清空全部
  28. -sessionStorage.removeItem('userinfo')
  29. # cookie
  30. -有过期时间,到过期时间自动清理
  31. -借助于第三方 vue-cookies
  32. -cookies.set('userinfo', JSON.stringify(this.userInfo))
  33. -cookies.get('userinfo')
  34. -cookies.delete('userinfo')
cookies操作
  1. # 安装Vue cookies第三方插件:
  2. cnpm install vue-cookies -S
  3. # 导入:
  4. import cookies from 'vue-cookies'
  1. <template>
  2. <div id="app">
  3. <h1>localStorage操作</h1>
  4. <button @click="saveStorage">点我向localStorage放数据</button>
  5. <button @click="getStorage">点我获取localStorage数据</button>
  6. <button @click="removeStorage">点我删除localStorage放数据</button>
  7. <h1>sessionStorage操作</h1>
  8. <button @click="saveSessionStorage">点我向localStorage放数据</button>
  9. <button @click="getSessionStorage">点我获取localStorage数据</button>
  10. <button @click="removeSessionStorage">点我删除localStorage放数据</button>
  11. <h1>cookie操作</h1>
  12. <button @click="saveCookie">点我向localStorage放数据</button>
  13. <button @click="getCookie">点我获取localStorage数据</button>
  14. <button @click="removeCookie">点我删除localStorage放数据</button>
  15. </div>
  16. </template>
  17. <script>
  18. import cookies from 'vue-cookies'
  19. export default {
  20. name: 'App',
  21. data() {
  22. return {}
  23. },
  24. methods: {
  25. saveStorage() {
  26. var person = {
  27. name: '彭于晏',
  28. age: 38
  29. }
  30. localStorage.setItem('userinfo', JSON.stringify(person))
  31. },
  32. getStorage() {
  33. let userinfo = localStorage.getItem('userinfo')
  34. console.log(userinfo)
  35. console.log(typeof userinfo)
  36. },
  37. removeStorage() {
  38. // localStorage.clear()
  39. localStorage.removeItem('userinfo')
  40. },
  41. saveSessionStorage() {
  42. var person = {
  43. name: '彭于晏',
  44. age: 38
  45. }
  46. sessionStorage.setItem('userinfo', JSON.stringify(person))
  47. },
  48. getSessionStorage() {
  49. let userinfo = sessionStorage.getItem('userinfo')
  50. console.log(userinfo)
  51. console.log(typeof userinfo)
  52. },
  53. removeSessionStorage() {
  54. // localStorage.clear()
  55. sessionStorage.removeItem('userinfo')
  56. },
  57. saveCookie() {
  58. cookies.set('name','lqz','7d') // 按秒计
  59. },
  60. getCookie() {
  61. console.log(cookies.get('name'))
  62. },
  63. removeCookie() {
  64. cookies.remove('name')
  65. }
  66. }
  67. }
  68. </script>
  69. <style scoped>
  70. h1 {
  71. background-color: aqua;
  72. }
  73. </style>

element-ui

  1. # 在vue上,css样式,用的最多的是elementui,但是还有其他的
  2. -elementui 做网页端 样式用的多 vue2 饿了吗团队开发的
  3. -elementui-plus 第三方团队继续基于vue3写的
  4. -vant app的样式 基于Vue3
  5. -iview pc端用www.iviewui.com 基于Vue3
element-ui使用

  1. # 使用步骤
  2. 1 安装
  3. cnpm i element-ui -S
  4. 2- main.js中引入插件
  5. - 完整引入 (导致项目过大)
  6. - 按需引入 (专业前端)
  7. 2.1 配置完整引入 main.js 中写入以下内容
  8. import ElementUI from 'element-ui';
  9. import 'element-ui/lib/theme-chalk/index.css';
  10. Vue.use(ElementUI) // 以后在咱们组件中直接使用elementui提供的全局组件即可
  11. 3 在组件中使用
  12. -去官网看到好的,复制贴到你的项目中

练习

1.创建vue项目

使用导入导出语法,把 登录功能的发送请求,抽取到一个包中

  • 对项目文件中的的路由部分进行配置

  1. # loginView组件页面
  2. <template>
  3. <div>
  4. <h2 class="top">登录页面</h2>
  5. <br>
  6. <p>用户名:<input type="text"></p>
  7. <p>密码:<input type="text"></p>
  8. <p><button>登录</button></p>
  9. </div>
  10. </template>
  11. <script>
  12. export default {
  13. name: 'loginView',
  14. components: {
  15. }
  16. }
  17. </script>
  18. <style>
  19. .top {
  20. align-content: center;
  21. }
  22. </style>
  • 我们需要绑定给按钮点击事件,给后端发送登录请求..

后端部分编写(django-drf)

  1. 因为我们等下会用到django authuser
  2. 所以需要我们在 settings文件中配置
  3. AUTH_USER_MODEL = 'app01.UserInfo'
  4. 数据库部分我们使用默认的即可
  5. INSTALLED_APPS = [
  6. ...
  7. 'rest_framework' #需要注册app进行使用Drf
  8. ]
  1. model层创建表
  2. from django.db import models
  3. from django.contrib.auth.models import AbstractUser
  4. # Create your models here.
  5. class UserInfo(AbstractUser):
  6. mobile = models.CharField(max_length=32,null=True)
  7. class CarModel(models.Model):
  8. name = models.CharField(max_length=32)
  9. price = models.CharField(max_length=32)
  10. car_factory = models.ForeignKey(to='CarFactory',on_delete=models.CASCADE)
  11. distributors = models.ManyToManyField(to='Distributors')
  12. class CarFactory(models.Model):
  13. name = models.CharField(max_length=32)
  14. addr = models.CharField(max_length=32)
  15. phone = models.CharField(max_length=32)
  16. class Distributors(models.Model):
  17. name = models.CharField(max_length=32)
  18. phone = models.CharField(max_length=32)
  19. addr = models.CharField(max_length=32)
  • 终端中进行 makemigrations,migrate数据库迁移操作
  • 创建超级管理员create superuser
  • 填充数据
  • 编写视图函数(登录功能)
  1. from rest_framework.viewsets import ModelViewSet, ViewSetMixin
  2. from rest_framework.generics import CreateAPIView
  3. from .models import CarModel, UserInfo, CarFactory, Distributor
  4. from .serializer import UserSerializer, CarFactorySerializer, CarModelSerializer, DistributorSerializer
  5. from rest_framework.response import Response
  6. from rest_framework_jwt.settings import api_settings
  7. from django.contrib import auth
  8. jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
  9. jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
  10. class UserView(ViewSetMixin, CreateAPIView):
  11. # queryset = UserInfo.objects.all()
  12. # serializer_class = UserSerializer
  13. def login(self, request, *args, **kwargs):
  14. username = request.data.get('username')
  15. password = request.data.get('password')
  16. user_obj = auth.authenticate(request,username=username,password=password)
  17. if user_obj:
  18. payload = jwt_payload_handler(user_obj)
  19. # 通过payload得到token
  20. token = jwt_encode_handler(payload)
  21. return Response({
  22. 'code': 100,
  23. 'msg': '登录成功',
  24. 'token': token,
  25. 'username': user_obj.username,
  26. 'url': ''
  27. })
  28. return Response({'msg': '用户名或密码错误', 'code': 101})
  29. class CarModelView(ModelViewSet):
  30. queryset = CarModel.objects.all()
  31. serializer_class = CarModelSerializer
  32. class CarFactoryView(ModelViewSet):
  33. queryset = CarFactory.objects.all()
  34. serializer_class = CarFactorySerializer
  35. class DistributorView(ModelViewSet):
  36. queryset = Distributor.objects.all()
  37. serializer_class = DistributorSerializer
  1. 路由层:
  2. from django.contrib import admin
  3. from django.urls import path, include
  4. from app01 import views
  5. from rest_framework.routers import SimpleRouter
  6. router = SimpleRouter()
  7. router.register('car_factory', views.CarFactoryView, 'car_factory')
  8. router.register('car_model', views.CarModelView, 'car_model')
  9. router.register('distributor', views.DistributorView, 'distributor')
  10. urlpatterns = [
  11. path('admin/', admin.site.urls),
  12. path('login/', views.UserView.as_view({'post':"login"})),
  13. path('user/', include(router.urls)),
  14. ]
  1. 序列化类:
  2. from rest_framework.serializers import ModelSerializer
  3. from .models import CarModel, UserInfo,CarFactory,Distributor
  4. class UserSerializer(ModelSerializer):
  5. class Meta:
  6. model = UserInfo
  7. fields = "__all__"
  8. class CarModelSerializer(ModelSerializer):
  9. class Meta:
  10. model = CarModel
  11. fields = ['name','price','distributors','car_factory','distributor_list','car_factory_detail','id']
  12. extra_kwargs = {
  13. 'distributors': {"write_only": True},
  14. 'car_factory': {"write_only": True},
  15. }
  16. class CarFactorySerializer(ModelSerializer):
  17. class Meta:
  18. model = CarFactory
  19. fields = '__all__'
  20. class DistributorSerializer(ModelSerializer):
  21. class Meta:
  22. model = Distributor
  23. fields = '__all__'
  • 后端代码编写完后我们在回到前端部分
  • 绑定给button按钮点击事件,向后端发送post请求
  1. <template>
  2. <div>
  3. <h2 class="top">登录页面</h2>
  4. <br>
  5. <p>用户名:<input type="text" v-model="username"></p>
  6. <p>密码:<input type="password" v-model="password"></p>
  7. <p>
  8. <button @click="handleLogin">登录</button>
  9. </p>
  10. </div>
  11. </template>
  12. <script>
  13. import axios from "axios"
  14. export default {
  15. name: 'loginView',
  16. components: {},
  17. data(){
  18. return{
  19. username:"",
  20. password:"",
  21. token:''
  22. }
  23. },
  24. methods: {
  25. handleLogin(){
  26. axios.post('http://127.0.0.1:8000/login/',{username:this.username,password:this.password}).then(
  27. res=>{
  28. if (res.data.code === 100){
  29. this.token = res.data.token
  30. }else {
  31. alert(res.data.msg)
  32. }
  33. }
  34. )
  35. }
  36. }
  37. }
  38. </script>
  39. <style>
  40. .top {
  41. align-content: center;
  42. }
  43. </style>

前端代码修改

效果:


我们可以将登录功能抽取出来,放到src下面的文件夹中

  • 新建文件夹method,并创建js文件index

  • 在index文件中编写代码
  1. import axios from "axios"// 这里必须导入axios,因为别的包会直接调用下面的函数,而下面的函数需要使用这个axios
  2. // 默认导出
  3. export default {
  4. handleLogin() {
  5. axios.post('http://127.0.0.1:8000/login/', {username: this.username, password: this.password}).then(
  6. res => {
  7. if (res.data.code === 100) {
  8. console.log(res.data)
  9. this.token = res.data.token
  10. } else {
  11. alert(res.data.msg)
  12. }
  13. }
  14. )
  15. }
  16. }
  17. export const ajaxfunc = function handleLogin () { // 这里如果使用匿名函数,由于匿名函数没有this,在别的组件中使用会导致获取不了数据。
  18. axios.post('http://127.0.0.1:8000/login/', {username: this.username, password: this.password}).then(
  19. res => {
  20. if (res.data.code === 100) {
  21. console.log(res.data)
  22. this.token = res.data.token
  23. } else {
  24. alert(res.data.msg)
  25. }
  26. }
  27. )
  28. }

2.创建一个组件,显示一张图片,图片地址通过父组件传入 aboutView 中使用这个组件

  1. <template>
  2. <img :src="imgaddr" alt="">
  3. </template>
  4. <script>
  5. export default {
  6. name: "imgShow",
  7. data(){
  8. return {
  9. imgaddr:""
  10. }
  11. }
  12. }
  13. </script>
  1. <template>
  2. <div class="about">
  3. <h1>父传子图片</h1>
  4. <br>
  5. <button @click="handleSend">点击按钮将图片地址发送到子组件上</button>
  6. <br>
  7. <hr>
  8. <imgShow ref="myimg"></imgShow>
  9. <hr>
  10. </div>
  11. </template>
  12. <script>
  13. import imgShow from '@/components/imgShow'
  14. export default {
  15. data(){
  16. return {
  17. addr:"http://img.pconline.com.cn/images/upload/upc/tx/ladyproduct/1703/14/c0/39464462_1489489032090_medium.jpg"
  18. }
  19. },
  20. components:{
  21. imgShow
  22. },
  23. methods:{
  24. handleSend(){
  25. this.$refs.myimg.imgaddr = this.addr
  26. }
  27. }
  28. }
  29. </script>

3. 在图片页组件,加一个button,点击把图片地址显示在父组件中 (子传父)

  1. <template>
  2. <div class="about">
  3. <h1>父传子图片</h1>
  4. <br>
  5. <button @click="handleSend">点击按钮将图片地址发送到子组件上</button>
  6. <br>
  7. <hr>
  8. <imgShow ref="myimg" @myevent="eventFunc"></imgShow>
  9. <hr>
  10. <h1>子传父图片</h1>
  11. <img :src="text" alt="">
  12. </div>
  13. </template>
  14. <script>
  15. import imgShow from '@/components/imgShow'
  16. export default {
  17. data(){
  18. return {
  19. addr:"http://img.pconline.com.cn/images/upload/upc/tx/ladyproduct/1703/14/c0/39464462_1489489032090_medium.jpg",
  20. text:''
  21. }
  22. },
  23. components:{
  24. imgShow
  25. },
  26. methods:{
  27. handleSend(){
  28. this.$refs.myimg.imgaddr = this.addr
  29. },
  30. eventFunc(info){
  31. console.log(info)
  32. this.text = info
  33. }
  34. }
  35. }
  36. </script>
  1. <template>
  2. <div>
  3. <img :src="imgaddr" alt="">
  4. <br>
  5. <button @click="handleFsend">点击按钮给父组件发送图片地址</button>
  6. </div>
  7. </template>
  8. <script>
  9. export default {
  10. name: "imgShow",
  11. data(){
  12. return {
  13. imgaddr:"",
  14. imgsrc:"http://img.pconline.com.cn/images/upload/upc/tx/ladyproduct/1703/14/c0/39464462_1489489037173_medium.jpg"
  15. }
  16. },
  17. methods:{
  18. handleFsend(){
  19. this.$emit('myevent',this.imgsrc)
  20. }
  21. }
  22. }
  23. </script>

Vue急速入门-5的更多相关文章

  1. Vue.js 入门指南之“前传”(含sublime text 3 配置)

    题记:关注Vue.js 很久了,但就是没有动手写过一行代码,今天准备入手,却发现自己比菜鸟还菜,于是四方寻找大牛指点,才终于找到了入门的“入门”,就算是“入门指南”的“前传”吧.此文献给跟我一样“白痴 ...

  2. vue框架入门和ES6介绍

    vue框架入门和ES6介绍 vue-mvvm模式,vue是一种轻量级的前端框架,主要为模板渲染,数据同步,组件化,模块化,路由等. https://cn.vuejs.org/ 源码:https://g ...

  3. Vue.js 入门教程

    Vue.js 入门教程:https://cn.vuejs.org/v2/guide/index.html

  4. 免费的 Vue.js 入门与进阶视频教程

    这是我免费发布的高质量超清「Vue.js 入门与进阶视频教程」. 全网最好的.免费的 Vue.js 视频教程,课程基于 Vue.js 2.0,由浅入深,最后结合实际的项目进行了最棒的技术点讲解,此课程 ...

  5. vue从入门到女装??:从零开始搭建后台管理系统(二)用vue-docute生成线上文档

    教程 vue从入门到女装??:从零开始搭建后台管理系统(一)安装框架 一个系统开发完成了总要有操作说明手册,接口文档之类的东西吧?这种要全部纯手写就很麻烦了,可以借助一些插件,比如: vue-docu ...

  6. Vue.js入门系列(一)

    Vue官网: https://cn.vuejs.org/v2/guide/forms.html#基础用法 [入门系列] (一)  http://www.cnblogs.com/gdsblog/p/78 ...

  7. Vue.js入门(一)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <meta htt ...

  8. VUE从入门到放弃(项目全流程)————VUE

    VUE从入门到放弃(第一天)--整体流程 先想想一个项目,vue项目是从什么到什么,然后再什么的?那是什么呢? 搭建 ( vue-cli) 代码内容 运行 封装 成品 一.搭建(脚手架vue-cli) ...

  9. Vue CLi3入门

    摘自:https://www.jianshu.com/p/cf9b56efd3b8 Vue CLi3入门 12018.11.15 14:16:17字数 1222阅读 8895 地址 Vue CLi3 ...

  10. Vue.js 入门:从零开始做一个极简 To-Do 应用

    Vue.js 入门:从零开始做一个极简 To-Do 应用 写作时间:2019-12-10版本信息:Vue.js 2.6.10官网文档:https://cn.vuejs.org/ 前言  学习 Vue ...

随机推荐

  1. 爬虫笔记之xpath

    目录 xpath如何取包含多个class属性 xpath获取当前标签下的所有文本(包括子标签) xpath如何取包含多个class属性 如果HTML结构是这样 <div class=" ...

  2. 【算法题型总结】--6、BFS

    // 计算从起点 start 到终点 target 的最近距离 int BFS(Node start, Node target) { Queue<Node> q; // 核心数据结构 Se ...

  3. 【大数据面试】【框架】Flume:Source的断点续传、重复数据、Channel选择

    〇.用途 流式结构 获取磁盘日志,拦截器过滤后,传递指定数据,写入HDFS或kafka 一.组成-Source.Channel.Sink 事务(put/take) 1.Source---taildir ...

  4. python自然语言处理(NLP)1------中文分词1,基于规则的中文分词方法

    python中文分词方法之基于规则的中文分词 目录 常见中文分词方法 推荐中文分词工具 参考链接 一.四种常见的中文分词方法: 基于规则的中文分词 基于统计的中文分词 深度学习中文分词 混合分词方法 ...

  5. C语言条件语句中调用函数并赋值时的一个小坑

    在C语言中,如果在条件语句中赋值,一定要注意符号优先级的问题,比较符号是比赋值符号先执行的.如果同时还调用函数,并将返回值赋给变量,更容易产生错误. 看下面的代码: int increase(int ...

  6. Docker容器入门到精通

    Docker 容器 快速入门 第一章:Docker容器 第二章:Dockerfile指令与Docker-compose容器编排-搭建docker私有仓库 h1 { color: rgba(0, 60, ...

  7. 彻底弄懂Javascript模块导入导出

    笔者开始学习Javascript的时候,对模块不太懂,不知道怎么导入模块,导出模块,就胡乱一通试 比如 import xx from 'test.js' 不起作用,就加个括号 import {xx} ...

  8. .NET周报【12月第4期 2022-12-31】

    祝大家新年快乐! 国内文章 『 再看.NET7』数值类型 https://mp.weixin.qq.com/s/ctiBMPY6Hditk81AzHSRng 在C#中,有int16,用short来定义 ...

  9. 重新捋一捋React源码之更新渲染流程

    前言 前些天在看Dan Abramov个人博客(推荐阅读,站在React开发者的角度去解读一些API的设计初衷和最佳实践)里的一篇文章,其重点部分的思想就是即使不使用Memo(),也可以通过组合的方式 ...

  10. Spark详解(06) - SparkSQL

    Spark详解(06) - SparkSQL Spark SQL概述 什么是Spark SQL Spark SQL是Spark用于结构化数据(Structured Data)处理的Spark模块. ( ...