????Vue-cli 创建项目

引入

1.单文件组件

在很多 Vue 项目中,我们使用 Vue.component 来定义全局组件,紧接着用 new Vue({ el: '#container '}) 在每个页面内指定一个容器元素

????Vue-cli 创建项目

????Vue-cli 创建项目

Vue-cli 创建项目

一.安装 Node.js

1.Node.js 介绍

  • Node.js 是一个新的后端(后台)语言, 它的语法和JavaScript类似, 所以可以说它是属于前端的后端语

2.前后端语言的区别

  • 运行环境 : 后端语言一般运行在服务器端,前端语言运行在客户端的浏览器上
  • 功能 : 后端语言可以操作文件,可以读写数据库,前端语言不能操作文件,不能读写数据库

3.Node.js 版本选择

????Vue-cli 创建项目

4.Node.js 版本两大分支

  • 官方发布的node.js版本 : 0.xx.xx 这种版本号就是官方发布的版本
  • 社区发布的node.js版本 : xx.xx.x 就是社区开发的版本

5.添加到环境变量

????Vue-cli 创建项目

  • 在 cmd 窗口输入 node -v 查看当前 Node.js 版本

????Vue-cli 创建项目

二.npm

1.npm 介绍

  • 在安装 node.js 完成后,在 node.js 中会同时帮我们安装一个 npm 包管理器 npm
  • 我们可以借助 npm 命令来安装 node.js 的包; 这个工具相当于 python 的 pip 管理器

2.npm 常用命令

npm install -g [包名]      # 安装模块   -g表示全局安装,如果没有-g,则表示在当前项目安装
npm list                   # 查看当前目录下已安装的node包
npm view [包名] engines     # 查看包所依赖的Node的版本 
npm outdated                # 检查包是否已经过时,命令会列出所有已过时的包
npm update [包名]           # 更新node包
npm uninstall [包名]        # 卸载node包
npm [命令] -h               # 查看指定命令的帮助文档

3.常用选项

选项 说明
-g 全局安装, 写入系统环境变量
-S --save, 把依赖加入到 package.json中
-register= 指定镜像仓库安装

三.cnpm

1.cnpm 介绍

  • 因为npm的服务器位于国外可能会影响安装 (下载速度慢)
  • 于是淘宝团队自己做了个国内的镜像, 淘宝镜像与官方同步频率目前为 10分钟 一次以保证尽量与官方服务同步

2.安装 cnpm

  • cmd 窗口执行命令
npm install cnpm -g --registry=https://registry.npm.taobao.org
  • cnpm -v 来测试是否成功安装

3.改变 npm 的下载地址

  • 如果要使用淘宝的镜像我们可以将 npm 的下载地址进行更换, 以此来达到不安装 cnpm 也能使用淘宝镜像的目的
# npm的默认地址是 : https://registry.npmjs.org/

# 换成淘宝
npm config set registry http://registry.npm.taobao.org/

# 换成官方(换回来)
npm config set registry https://registry.npmjs.org/
  • 使用npm config get registry 命令查看 npm 的仓库地址

????Vue-cli 创建项目

四.Vue-CLI 脚手架

1.Vue-CLI 介绍

  • 通过 @vue/cli 实现的交互式的项目脚手架
  • 通过 @vue/cli + @vue/cli-service-global 实现的零配置原型开发
  • 一个运行时依赖 (@vue/cli-service),该依赖:

>- 可升级
>- 基于 webpack 构建,并带有合理的默认配置
>- 可以通过项目内的配置文件进行配置
>- 可以通过插件进行扩展

  • 一个丰富的官方插件集合,集成了前端生态中最好的工具
  • 一套完全图形化的创建和管理 Vue.js 项目的用户界面

2.安装 cli 脚手架

  • cmd 窗口执行
npm install -g @vue/cli
  • 查看是否安装成功 / 版本
vue --version

????Vue-cli 创建项目

五.命令行创建Vue项目

1.进入到目标目录

vue create [项目名]

# 示例
vue create vue_test

2.选择配置

  • 第一次一般选择手动配置 Manually select features
  • 键盘上下键选择, 回车键确认并进行下一步

????Vue-cli 创建项目

3.选择项目所需要的功能

  • 空格进行选中和取消, 回车确认并进行下一步
  • 额外添加 Router(路由,用于页面跳转) 和 Vuex(状态管理器)功能

????Vue-cli 创建项目

3.选择 Vue 的版本

  • 选择 2.x 版本

????Vue-cli 创建项目

4.询问是否使用历史路由模式

  • 选择 n 不使用

5.选择依赖管理文件

  • 选择 package.json 这个文件

????Vue-cli 创建项目

6.是否保存本次配置

  • 如果想让下次创建项目的时候使用本次配置, 那么就可以保存此次配置并取一个名字, 下次可以直接选择
  • 等待创建:

????Vue-cli 创建项目

  • 创建成功:

????Vue-cli 创建项目

7.启动 / 停止项目

# 启动,需要进入项目根目录
npm run serve

# 停止
ctrl+c

8.打包项目

# 需要在项目根目录下进行打包操作
npm run build

六.UI 界面创建Vue项目

1.cmd 窗口输入命令

vue ui

2.自动跳转到网页

????Vue-cli 创建项目

3.点击创建, 按照提示创建

????Vue-cli 创建项目

????Vue-cli 创建项目

  • 等待其创建成功(1~3分钟)

七.Pycharm打开Vue项目

1.左上角File---->open---->选择你的Vue项目

2.设置Vue项目启动按钮

  • Pycharm打开Vue项目后默认是没有启动按钮的, 需要到Terminal中手动启动
  • 我们可以进行添加配置, 让其支持启动按钮

????Vue-cli 创建项目

3.选择 npm

????Vue-cli 创建项目

4.设置启动命令及名字

????Vue-cli 创建项目

5.启动按钮变绿说明设置成功

????Vue-cli 创建项目

6.点击按钮启动Vue项目

????Vue-cli 创建项目

????Vue-cli 创建项目

八.Vue项目目录介绍

????Vue-cli 创建项目

dist:  # 打包的项目目录(打包后会生成:npm run build)
node_modules:  # 项目依赖(上传到git或者将项目拷贝给别人的时候删掉,不然下载慢,使用npm install命令可以重新安装)
public:  # 共用资源
	--favicon.ico0:  # 图标
	--index.html:  # 项目入口页面,单页面
src:  # 项目目标,书写代码的地方
	-- assets:  # 资源
	-- components:  # 小组件
	-- views:  # 视图组件
	-- App.vue:  # 根组件
	-- main.js:   # 入口js
	-- router.js:  # 路由文件
	-- store.js:  # 状态库文件
vue.config.js:  # 项目配置文件(没有可以自己新建)
package.json: # 项目配置依赖(等同于python项目的reqirement.txt,npm安装包时指定的"-S"选项就是保存到这里面)
  • 项目配置依赖文件 : package.json
"scripts": {
    "serve": "vue-cli-service serve",  # 运行项目,可以修改serve成别的名字,启动项目时就需要使用你指定的名字
    "build": "vue-cli-service build",  # 编译项目成html,css,js
},
  • 配置文件 vue.config.js (是一个可选的配置文件)
// 官网配置参考 : https://cli.vuejs.org/zh/config/
  • vue 后缀文件
<template>
    <!-- 模板区域 -->
</template>

<script>
    // 逻辑代码区域
    // 该语法和script绑定出现
  	//export default-->es6的默认导出(导出一个对象),模拟commonJS的导出方式制定的
    export default {
        
    }
</script>

<style scoped="">
    /* 样式区域 */
    /* scoped表示这里的样式只适用于组件内部, scoped与style绑定出现 */
</style>

九.vue 项目中集成 axios

1.安装 axios 模块

npm install -S axios  # -S 选项会将该模块加到package.json中去
npm install --save axios

2.为项目配置全局 axios

  • 在入口 js 文件中书写
import axios from 'axios'  
// 导入安装的模块不用加相对路径

Vue.prototype.$axios = axios
// 向Vue的原型中放一个属性(key)为$axios,值为:axios
// 注意 $axios 是你自己取的名字还可以叫xxxx,尽量不要重复
  • 使用
// 加入到Vue原型中以后之需要通过 this 就可以拿到axios发送请求了
methods:{
    handle(){
      // 发送请求获取数据
      this.$axios.get('/ajax/moreClassicList?').then(res =&gt;{
        console.log(res.data) 
      })
    }
  }

3.非全局配置使用

  • 在某个组件中直接导入 axios
// 名字自己取$axios或者xxxx,不要重名
import $axios from 'axios'
  • 然后直接使用你定义的名字来发送请求
methods:{
    handle(){
      // 发送请求获取数据
      $axios.get('/ajax/moreClassicList?',{}).then(res =&gt;{
        console.log(res.data) 
      })
    }
  }

十.设置vue前端代理解决跨域问题

1.原理图

????Vue-cli 创建项目

2.配置代理

module.exports = {
  devServer: {
    proxy: {
      '/ajax': {
        target: 'https://m.maoyan.com/',
        changeOrigin: true
      }
    }
  }
}
  • 在组件中发送请求时
import $axios from 'axios'
mounted () {
  // ajax/ 就是 'https://m.maoyan.com/ajax/'
  $axios.get('ajax/moreClassicList?sortId=1&amp;showType=3').then(res =&gt; {
    console.log(res.data)
  })
}

十一.补充 ES6 版本的导入导出

为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令

1.示例

  • export-default.js 文件
export default function () {  // 导出一个函数
  console.log('foo');
}
  • import-from.js 文件
import custom_test from './export-default';  // 导入这个文件导出的内容
custom_test(); // 'foo', 导出的就是上面的一个函数,输出"foo"

十二.实战 : 使用 Vue-cli 创建项目并与后端联通

1.需求

  • 与后端联通(使用Django), 并可以进行登入, 返回token
  • 可以获取到猫眼电影的电影数据(需要设置前端代理解决跨域问题)

ps : 后端虚拟环境搭建去看路飞学城项目

2.Vue项目代码示例

  • router ---> index.js 添加路由
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Order from '../views/Order.vue'
import Login from '../views/Login.vue'

Vue.use(VueRouter)

const routes = [
  {  // 登入
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: () =&gt; import('../views/About.vue') // 就是About
  },
  {  // 猫眼电影数据获取
    path: '/order',
    name: 'Order',
    component: Order
  },
]

const router = new VueRouter({
  routes
})

export default router
  • 在项目根路径下的 vue.config.js 文件设置代理
module.exports = {
    devServer:{
        proxy:{
            '/api':{  // 代理Django后端
                target:'http://127.0.0.1:8000/',
            },
            '/ajax':{  // 代理猫眼
                target:'https://m.maoyan.com/'
            },
        }
    }
}
  • axios 添加到 Vue 原型中去, 让其可以全局使用 : main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// 导入'axios'
import axios from 'axios'
Vue.config.productionTip = false
//向Vue的原型中放一个 属性为:$axios,值为:axios,其他组件页面使用直接this.$axios
Vue.prototype.$axios = axios
new Vue({
  router,
  store,
  render: h =&gt; h(App)
}).$mount('#app')
  • views ----> Home.vue
<template>
  <div class="about">
    <h1 class="title">This is an home page</h1>
    <p>用户名: <input type="text" v-model="username"></p>
    <p>密码: <input type="password" v-model="password"></p>
    <hr>
    <button @click="submit">登入</button>
    <p>返回的token:<br>{{ token }}</p>
  </div>
</template>

<script>
// 名字自己取$axios或者xxxx,不要重名
import $axios from 'axios'

export default {
  name: 'Home',
  data() {
    return {
      username: '',
      password: '',
      token: '',
    }
  },
  methods: {
    submit() {
      console.log(this.username)
      console.log(this.password)
      // 发送ajax请求, 使用代理接口
      // '/api/' 就等同于 'http://127.0.0.1:8000/api/'
      $axios.post('/api/login/', {
        username: this.username,  // 将输入框的名字个密码发送给后端
        password: this.password,
      }).then(
          res => {
            if (res.data.status === 200) {
              this.token = res.data.token
            }
          }
      ).catch(res => {
        alert('登入失败')
      })
    }
  },
}
</script>

<style>
.title {
  background-color: darkcyan;
}
</style>
  • views ----> Order.vue
<template>
  <div class="about">
    <h1 @click="handle">点击获取数据</h1>
    <div v-html="res"></div>
  </div>
</template>

<script>
export default {
  name:'Order',
  data(){
    return{
      res:''
    }
  },
  methods:{
    handle(){
      // 发送ajax请求获取数据,前缀在代理里面设置
      this.$axios.get('/ajax/moreClassicList?sortId=1&showType=3').then(res =>{
        console.log(res.data)  // 是一个HTML格式的数据
        this.res = res.data  // 可以直接使用v-html进行数据渲染
      })
    },
  },
}
</script>
  • src ---> App.vue (根组件)
<template>
  <div >
    <div class="nav">
      <!--router-link 进行路由跳转-->
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link> |
      <router-link to="/order">Order</router-link>
    </div>
    <router-view>  <!--路由跳转必须要书写这个-->
  </router-view></div>
</template>

<script>
export default {
  name: 'App',
  components: {}
}
</script>

<!--这下面的都是样式, 不需要的可以删除-->
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
#nav {
  padding: 30px;
}
#nav a {
  font-weight: bold;
  color: #2c3e50;
}
#nav a.router-link-exact-active {
  color: #42b983;
}
</style>

3.django代码示例

写一个简单的登入接口+签发token就可以

  • models.py
from django.db import models

class UserInfo(models.Model):
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
    phone = models.BigIntegerField()

    def __str__(self):
        return self.username
  • serializer.py 多方式登入
from django.db.models import Q  # 用来构建或与非
from rest_framework.exceptions import ValidationError
from rest_framework import serializers
# 导入 jwt 配置文件
from rest_framework_jwt.settings import api_settings

# 将获取 payload 的方法以及签发 token 的方法内存地址赋值给两个变量
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

from user import models

# 多登入方式序列化类
class VariousLoginModelSerializer(serializers.ModelSerializer):
    # 重写 username 字段让其时区字段自己的校验规则, 不然会出现required错误
    username = serializers.CharField()

    class Meta:
        model = models.UserInfo
        fields = ['username', 'password']

    def validate(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        # 多登入方式,username可能是用户名、邮箱、手机号,分情况操作
        if username.isdigit():
            user = models.UserInfo.objects.filter(Q(phone=int(username)) &amp; Q(password=password)).first()
        else:
            user = models.UserInfo.objects.filter(
                (Q(email=username) | Q(username=username)) &amp; Q(password=password)).first()

        if user:
            # 登入成功,签发token
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            # context是上下文,是视图类和序列化类沟通的桥梁(管道)
            self.context['token'] = token
            self.context['username'] = username
            self.context['user_obj'] = user  # 将当前user对象也放进去
            return attrs
        else:
            raise ValidationError('用户名或密码错误!!')
  • views.py
from rest_framework.generics import CreateAPIView
from user import models
from user import serializer
from rest_framework.response import Response
from rest_framework.viewsets import ViewSetMixin

# 多种登入方式(继承ViewSetMixin自动生成路由)
class VariousLoginView(ViewSetMixin, CreateAPIView):
    queryset = models.UserInfo.objects.all()
    serializer_class = serializer.VariousLoginModelSerializer

    def create(self, request, *args, **kwargs):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            # 从 context 中取出序列化类传过来的数据
            token = ser.context['token']
            username = ser.context['username']
            user_obj = ser.context['user_obj']  # 拿到user对象
            return Response({'status': 200, 'msg': '登入成功!!', 'token': token, 'username': user_obj.username})
        else:
            return Response({'status': 100, 'msg': ser.errors})

    def get(self, request, *args, **kwargs):
        return Response({'status': 200, 'msg': 'ok', })
  • urls.py
from django.contrib import admin
from django.urls import path,include
from user import views
from rest_framework.routers import SimpleRouter  # 自动添加路由
router = SimpleRouter()
router.register('api/login',views.VariousLoginView)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),
]

4.测试

  • 登入返回token + 获取猫眼电影数据

????Vue-cli 创建项目

  • 多方式登入返回 token

????Vue-cli 创建项目