• VUE创建项目



    Vue Cli项目搭建

    vue项目需要自建服务器:node

    什么是node:

    • 用C++语言编写,用来运行JavaScript语言
    • node可以为前端项目提供server (包含了socket)

    一、环境搭建

    1、官网下载安装包,傻瓜式安装:https://nodejs.org/zh-cn/

    2、装完了后在cmd输入node即可启动一个命令行交互环境,运行javascript代码

           

    3、可以更换国内源,加速下载:npm install -g cnpm --registry=https://registry.npm.taobao.org

          在更换源后,所有的npm命令都可以替换为cnpm。

          改完后npm的源还是国外的源,cnpm的源是淘宝的源。

    4、安装vue cli环境:脚手架,命令行快速创建项目

          cnpm install -g @vue/cli

    5、安装脚手架报错的时候,需要清空缓存处理

          npm cache clean --force

    二、项目创建

    以管理员的身份运行cmd ,否则可能出现一些不必要的麻烦

    1. 首先cd切换到目标目录
    2. 执行:vue create 项目名
    3. 选择自定义方式创建项目,选取Router, Vuex插件
    4. 选择第二个进入自定义配置:

              

        5. 执行时,会提示下载源,选择淘宝镜像即可。(有大写的选大写,大写是建议的选项)

              

        6. 具体配置:上下键切换,空格键选择,回车键进入下一步

            勾选Babel、Router、Vuex、Formatter

            Babel :jsES6语法转换ES5

            Router:路由

            Vuex:组件数据交互

            Formatter:格式化代码

           

           下一步选Y,接下来的配置都是提示选项有大写选大写,没有默认选第一个配置就行

        

    安装完后的目录如下:

     三、终端启动项目

    1. cd到你的项目:cd vue_proj
    2. npm run serve
    3. 访问:http://localhost:8080/ 

    四、pycharm配置

    • 在使用pycharm开发时,打开后,vue文件会有提示需要安装插件,直接点击下载即可。
    • 如果没有提示,那么就要在settings的plugins里面搜索vue.js插件,然后安装。
    • 安装完后需要重启ide。
    • 如果命令行启动的,在你更改一些代码后,页面没有刷新,这时候在命令行按ctrl+c就可以刷新。但是连续在命令行按两次ctrl+c就会提示你是否退出,选择退出或不退就行。
    • 需要在pycharm配置npm启动项:先点击下拉菜单的Edit,然后点击小+号,选择npm

    接着需要指定json文件,运行的脚本等。项目名可以起也可以不起。

     

     上面配置完成后,即可在pycharm启动项目。 

    我们把上面的项目可以当作一个模板,以后有需要,直接就把除了node_modules的其他文件夹及文件全部复制到新项目

    然后再到相应的目录下执行:cnpm install

    这样,就会根据电脑环境,项目需求重新下载依赖(node_modules)了。

    五、项目目录

    来看一下main.js主脚本文件:

    import Vue from 'vue'
    //./代表的是相对路径
     import App from './App.vue'
    //我可以把它改成下面的形式,@就代表src的绝对路径
    //@后就可以采用相对于src的相对路径
    import App from '@/App.vue'
    import router from './router'
    import store from './store'
    //这个是禁用提示,比如你第一次下载某个app,刚进去会有操作指南
    Vue.config.productionTip = false;
    //下面是ES6的写法
    // new Vue({
    // router,
    // store,
    // render: h => h(App)
    // }).$mount('#app');
    //改成ES5的看看
    new Vue({
    el: '#app',
    router: router,
    store: store,
    render: function (h) {
    return h(App)
    }
    });

    .vue文件

    router.js的路由配置部分:

     
    {
    path: '/',
    name: 'home',
    // 路由的重定向
    redirect: '/home'
    }
    {
    // 一级路由, 在根组件中被渲染, 替换根组件的<router-view/>标签
    path: '/one-view',
    name: 'one',
    component: () => import('./views/OneView.vue')
    }
    {
    // 多级路由, 在根组件中被渲染, 替换根组件的<router-view/>标签
    path: '/one-view/one-detail',
    component: () => import('./views/OneDetail.vue'),
    // 子路由, 在所属路由指向的组件中被渲染, 替换该组件(OneDetail)的<router-view/>标签
    children: [{
    path: 'show',
    component: () => import('./components/OneShow.vue')
    }]
    }

    <router-link to="/">Home</router-link>        router-link渲染为a标签

    store.js:vuex

     

    // 在任何一个组件中,均可以通过this.$store.state.msg访问msg的数据

    // state永远只能拥有一种状态值
    state: {
    msg: "状态管理器"
    },
    // 让state拥有多个状态值
    mutations: {
    // 在一个一个组件中,均可以通过this.$store.commit('setMsg', new_msg)来修改state中的msg
    setMsg(state, new_msg) {
    state.msg = new_msg
    }
    },
    // 让mutations拥有多个状态值
    actions: {
    }

     六、案例

    6.1、在根组件中渲染页面组件

    我们要在views中创建一个Main.vue,用来作为主页:

    <template>
    <div class="main">
    <h1>{{ title }}</h1>
    </div>
    </template>
    <script>
    export default {
    name: "Main",
    data:function () {
    return{
    title:'主页'
    }
    }
    }
    </script>
    <!-- 局部的要写scoped-->
    <style scoped>
    .main {
    /*vh:相对于视窗的高度,那么vw:则是相对于视窗的宽度*/
    height: 100vh; /*100vh代表网页撑满一个屏*/
    background-color: orange;
    }
    h1 {
    margin: 0; /*去除h1标签自带的margin边距*/
    color: red;
    }
    </style>

    接下来我们要考虑的就是如何在页面中显示它,怎么现实呢?这时候就要到App.vue文件中去注册渲染。

     
    <template>
    <div id="app">
    <!--3:注册完的组件就可以在这里用了-->
    <Main></Main>
    </div>
    </template>
    <script>
    // 1:要渲染主页的内容,首先要在逻辑中导入
    import Main from '@/views/Main'
    export default {
    //2:导入的是局部组件,需要注册
    components:{
    Main:Main
    }
    }
    </script>
    <!-- 根组件这里不用写scoped-->
    <style>
    html, body {
    margin: 0;
    }
    </style>

     

    1. 6.2、路由:单页面实现页面之间转跳

    先来准备三个文件(局部组件):

    Main.vue

     
    <template>
    <div class="main">
    <h1>{{ title }}</h1>
    </div>
    </template>
    <script>
    export default {
    name: "Main",
    data:function () {
    return{
    title:'主页'
    }
    }
    }
    </script>
    <!-- 局部组件要写scoped-->
    <style scoped>
    .main {
    /*vh:相对于视窗的高度,那么vw:则是相对于视窗的宽度*/
    height: 100vh; /*100vh代表网页撑满一个屏*/
    background-color: orange;
    }
    h1 {
    margin: 0; /*去除h1标签自带的margin边距*/
    color: red;
    }
    </style>

     

    User.vue

     
    <template>
    <!--类名一般就是文件名小写-->
    <div class="user">
    <h1>个人页</h1>
    </div>
    </template>
    <script>
    export default {
    name: "User"
    }
    </script>
    <style scoped>
    </style>

     

    Goods.vue

     
    <template>
    <div class="goods">
    <h1>商品页</h1>
    </div>
    </template>
    <script>
    export default {
    name: "Goods"
    }
    </script>
    <style scoped>
    .goods {
    height: 100vh;
    background-color: blue;
    }
    </style>

     

     

    接下来要到router.js中注册

     
    import Vue from 'vue'
    import Router from 'vue-router'
    //导入
    import Goods from './views/Goods'
    import User from './views/User'
    import Main from './views/Main'
    Vue.use(Router);
    export default new Router({
    mode: 'history',
    base: process.env.BASE_URL,
    routes: [
    //注册
    {
    path: '/',
    name: 'main',
    component: Main
    },
    {
    path: '/goods',
    name: 'goods',
    component: Goods
    },
    {
    path: '/user',
    name: 'user',
    component: User
    },
    ]
    })

     

     

    最后到App.vue中调用:<router-view /> <!--相当于每个页面要渲染的内容-->

     
    <template>
    <div id="app">
    <!--注册完的组件就可以在这里用了-->
    <ul class="nav">
    <li>
    <router-link to="/">主页</router-link>
    </li>
    <li>
    <router-link to="/goods">商品页</router-link>
    </li>
    <li>
    <router-link to="/user">个人页</router-link>
    </li>
    </ul>
    <router-view />
    </div>
    </template>
    <script>
    export default {
    }
    </script>
    <!-- 根组件这里不用写scoped-->
    <style>
    html, body,ul,h1 {
    margin: 0;
    }
    .nav {
    height: 60px;
    background-color: #d2a1ab;
    }
    .nav li{
    list-style: none;
    float: left;
    /*垂直居中*/
    line-height: 60px;
    width: 120px;
    /*水平居中*/
    text-align: center;
    }
    .nav li:hover{
    background-color: aqua;
    }
    .nav li a{
    /*去掉a标签的下划线*/
    text-decoration: none;
    /*字体大小及样式*/
    font: bold 20px/60px 'STSong';
    }
    ul {
    list-style: none;
    }
    </style>

     

    至此就实现了单页面的局部组件切换了。

    1. 6.3、前后台交互(基于6.2的页面Goods)

     上面我们已经实现了单页面的切换,那么我们肯定每个页面都要到后台拿数据,比如我点击商品页后就要动态从数据库获取信息,然后展示到前端页面,这就涉及到了前后台的交互问题。 

    我们以Goods为例来看一下生命周期钩子

    1. 钩子表示一个vue实例从创建到销毁的这个过程,将这个过程的一些时间节点赋予了对应的钩子函数
    2. 钩子函数: 满足特点条件被回调的方法

    我们在Goods.vue的script中加入钩子

     当点击商品页时,会触发钩子:

     了解了这个,下面我们以django作为后台,来实现以下交互

    因为交互是vue自己完成的,我们拿不到csrf的认证字符串,所以直接去配置文件中把这个中间件注释掉。

    然后我们通过axios向后台发请求。

    注意,在前后台交互的时候,会产生跨域的问题

    1. 什么是跨域问题?

    通常情况下,A网页访问B服务器资源时,不满足以下三个条件其一就是跨域访问
    1. 协议不同
    2. 端口不同
    3. 主机不同

    1. django解决跨域问题: 

    安装django-cors-headers模块

    在settings.py中配置
    # 注册app
    INSTALLED_APPS = [
        ...
        'corsheaders'
    ]
    # 添加中间件
    MIDDLEWARE = [
        ...
        'corsheaders.middleware.CorsMiddleware'
    ]
    # 允许跨域源
    CORS_ORIGIN_ALLOW_ALL = True

     然后前端vue这边需要安装axios(ajax):

    cnpm install axios --save

    接着要去main.js里对axios进行全局配置:

    import Axios from 'axios'
    
    Vue.prototype.$ajax = Axios;
    //配置完后在任何地方都能通过this.$ajax拿到它

     具体的Goods的代码如下:

     
    <template>
    <div class="goods">
    <h1>商品页</h1>
    <h2>{{ msg }}</h2>
    </div>
    </template>
    <script>
    export default {
    name: "Goods",
    data:function(){
    return {
    msg: '123'
    }
    },
    beforeCreate () {
    window.console.log("开始创建Goods组件");
    },
    created () {
    window.console.log("Goods组件创建成功, data, methods已拥有");
    },
    mounted () {
    window.console.log("页面已被vue实例渲染, data, methods已更新");
    //我们选择渲染完成后拿数据
    //请求后台
    let _this = this;
    this.$ajax({
    url:'http://127.0.0.1:8000/goods/',
    method:'post',
    params:{
    info:'前台数据'
    }
    }).then(function (result) { //then就是回调函数,相当于ajax的success
    // this代表的是回调then这个方法的调用者(axios插件),也就是发生了this的重指向
    // 要更新页面的title变量,title属于vue实例
    // res为回调的对象,该对象的data属性就是后台返回的数据
    let data = result.data;
    //this指向的是then的function,我们前面定义的_this才是全局
    _this.msg = data;
    })
    }
    }
    </script>
    <style scoped>
    .goods {
    height: 100vh;
    background-color: blue;
    }
    </style>

     

    后台的视图函数:

     
    def goods(request):
    print(request.method)
    # axios的请求,原生Django都在GET字典中拿前台数据
    print(request.GET)
    print(request.POST)
    return HttpResponse('后台数据')

     

    阅读目录

    Vue项目开发:

    前后端完全分离

    后端:提供接口数据

    前端:页面转跳、页面布局、页面数据渲染全部由前端做

    中间交互:请求

    搭建Vue项目环境:

    Vue项目需要自建服务器:node

    node介绍:

    1.用C++语言编写,用来运行JavaScript语言
    2.node可以为前端项目提供server (包含了socket)

    node下载安装:https://nodejs.org/zh-cn/

    一路点击下一步就可以。

    npm:包管理器 - 为node拓展功能的

    # 换国内源,加速下载,通过命令行换源:
    # 管理员命令行:npm install -g cnpm --registry=https://registry.npm.taobao.org
    # MacOS: sudo npm install -g cnpm --registry=https://registry.npm.taobao.org

    # 索引npm的指令都可以换成cnpm
    # npm install vuex => cnpm install vuex

    vue cli环境:脚手架 - 命令行快速创建项目

    # cnpm install -g @vue/cli

    # 如果报错:npm cache clean --force

    创建Vue项目

    起步
    1.cd 到目标目录
    2.创建项目:vue create 目录名

    创建项目的过程
    提示下载原:选择淘宝镜像

    具体配置:上下键切换,空格键选择,回车键进入下一步
    1.第二个选项进入自定义配置

    2.Babel jsES6语法转换ES5,Router路由 Vuex组件数据交互 Formatter格式化代码

    3...有提示选择大写,没提示默认第一个即可
    选y

    开始下载:

    启动项目

    两种启动方式:

    ①终端启动
    1.进入项目:cd到项目目录
    2.启动项目:npm run serve

     ②pycharm配置启动
    1.安装vue.js插件,重启
    2.配置项目的npm启动项
    3.启动node搭建的socket

    如果项目环境搭建失败,可以将搭建成功的项目中的相关文件及文件夹:

    然后打开管理员打开cmd命令

    cd e:vue-proj进入项目文件目录下

    cnpm install  对自己电脑的当前环境进行重新安装依赖,重构项目环境,这样就可以用了,使用pycharm打开该文件夹就行了

    该方法可以用于快速创建和搭建项目环境使用,这样就不用每次vue create进行下一步下一步了

    项目目录

    打开main.js

     修改后按ctrl+s保存后页面会实时刷新,且文件后缀都可以省略不写

     

    页面组件开发

    组件创建:

     创建新组件之后的基本页面情况:

    复制代码
    <template>
        <!-- 只能有一个根标签 -->
    </template>
    
    <script>
        export default {
            name: "Main",
            data: function() {
                return {
                    
                }
            },
            ...
        }
    </script>
    
    <style scoped>
        /* scoped  可以让样式实现局部化*/
        /* 如果让样式实现全局化,则应该写在根组件样式中*/
    </style>
    复制代码

     组件渲染

    复制代码
    <!-- Main.vue 主页组件 -->
    <template>
        <div class="main">
            <h1>{{ title }}</h1>
        </div>
    </template>
    
    <script>
        export default {
            name: "Main",
            data:function () {
                return {
                    title:'主页'
                }
            }
        }
    </script>
    
    <style scoped>
        .main {
            height: 100vh;
            background-color: beige;
        }
        h1 {
            margin: 0;
            color: darkred;
        }
    </style>
    复制代码
    复制代码
    <!-- App.vue根组件 -->
    <template>
      <div id="app">
        <Main></Main>
    
      </div>
    </template>
    
    <script>
      import Main from '@/views/Main'
      export default {
          components:{
            Main:Main
          }
      }
    </script>
    
    <style>
      html, body {
          margin: 0;
      }
    </style>
    复制代码

    说明:

    路由:router.js

    在根组件中设计转跳页面的导航栏

    复制代码
    <template>
      <div id="app">
        <ul class="nav">
          <li>主页</li>
          <li>商品页</li>
          <li>个人页</li>
        </ul>
      </div>
    </template>
    
    <script>
      import Main from '@/views/Main'
      export default {
          components:{
            Main:Main
          }
      }
    </script>
    
    <style>
      .nav {
        height: 60px;
        background-color: silver;
      }
      .nav li {
        float: left;
        height: 60px;
        width: 123px;
        text-align: center;
        line-height: 60px;
      }
      .nav li:hover {
        background-color: aquamarine;
      }
    
      html, body, ul {
          margin: 0;
      }
      ul {
        list-style: none;
      }
    </style>
    复制代码

    创建三个页面组件

    复制代码
    <!--Main.vue-->
    <template>
        <div class="main">
            <h1>{{ title }}</h1>
        </div>
    </template>
    
    <script>
        export default {
            name: "Main",
            data:function () {
                return {
                    title:'主页'
                }
            }
        }
    </script>
    <style scoped>
        .main {
            height: 100vh;
            background-color: beige;
        }
        h1 {
            margin: 0;
            color: darkred;
        }
    </style>
    复制代码
    复制代码
    <!--Goods.vue-->
    <template>
        <div class="goods">
            <h1>商品页</h1>
        </div>
    </template>
    
    <script>
        export default {
            name: "Goods"
        }
    </script>
    
    <style scoped>
    
    </style>
    复制代码
    复制代码
    <!--User.vue-->
    <template>
        <div class="user">
            <h1>个人页</h1>
        </div>
    </template>
    
    <script>
        export default {
            name: "User"
        }
    </script>
    
    <style scoped>
    
    </style>
    复制代码

    配置路由(router.js中)

    复制代码
    import Vue from 'vue'
    import Router from 'vue-router'
    import Main from '@/views/Main.vue'
    import Goods from '@/views/Goods.vue'
    import User from '@/views/User.vue'
    
    Vue.use(Router)
    
    export default new Router({
        mode: 'history',
        base: process.env.BASE_URL,
        routes: [
            {
                path: '/',
                name: 'main',
                component: Main
            },
            {
                path: '/goods',
                name: 'goods',
                component: Goods
            },
            {
                path: '/user',
                name: 'user',
                component: User
            },
            //第二种方式
            // {
            //   path: '/about',
            //   name: 'about',
            //   // route level code-splitting
            //   // this generates a separate chunk (about.[hash].js) for this route
            //   // which is lazy-loaded when the route is visited.
            //   component: () => import(/* webpackChunkName: "about" */ './views/About.vue')
            // }
        ]
    })
    复制代码

    根组件中:

    复制代码
    <template>
      <div id="app">
        <ul class="nav">
          <li>
            <router-link to="/">主页</router-link>
          </li>
          <li>
            <router-link to="/goods">商品页</router-link>
          </li>
          <li>
            <router-link to="/user">个人页</router-link>
          </li>
        </ul>
        <!--<router-view></router-view>-->
        <router-view/>
      </div>
    </template>
    
    <script>
      import Main from '@/views/Main'
      export default {
          components:{
            Main:Main
          }
      }
    </script>
    
    <style>
      .nav {
        height: 60px;
        background-color: silver;
      }
      .nav li {
        float: left;
        height: 60px;
        width: 123px;
        text-align: center;
        line-height: 60px;
      }
      .nav li:hover {
        background-color: aquamarine;
      }
    
      html, body, ul, h1 {
          margin: 0;
      }
      ul {
        list-style: none;
      }
      a {
        text-decoration: none;
        font: bold 20px/60px 'STSong';
      }
    </style>
    复制代码

    前后台交互

    axios

    // 安装 axios(ajax)的命令
    // npm install axios --save
    // 为项目配置全局axios(main.js中)
    import Axios from 'axios'
    Vue.prototype.$ajax = Axios

    goods组件中设置ajax给后台发送数据(在组件渲染完毕时候发送)

    复制代码
    <!--Goods.vue-->
    <template>
        <div class="goods">
            <h1>商品页</h1>
        </div>
    </template>
    <script>
        export default {
            name: "Goods",
            beforeCreate() {
                window.console.log("开始创建Goods组件");
            },
            created() {
                window.console.log("创建Goods组件完毕");
            },
            mounted() {
                window.console.log("Goods组件渲染完毕");
                // 请求后台
                this.$ajax({
                    method:'post',
                    url:'http://127.0.0.1:8000/goods/',
                    params:{
                        info:'前台数据'
                    }
    
                }).then(function (res) {
                    window.console.log(res)
                })
            }
        }
    
    </script>
    <style scoped>
    
    </style>
    复制代码

     新建一个Django项目,作为后台接收、返回数据

     settings.py中手动将csrf中间件注释掉(这里需要注意真正项目中前后端分离时,Django的csrf中间件时通过代码层面禁用并手写安全认证,这里注释掉主要方便我们测试)

    路由配置:

    复制代码
    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^goods/', views.goods),
    ]
    复制代码

     视图函数

    复制代码
    def goods(request):
        print(request.method)
        print(request.POST)
        print(request.GET)
    
        return HttpResponse('后台数据')
    复制代码

     发现跨域问题:后台能收到前台发送的请求数据,但是由于跨域问题,只要前台端给后端发送数据,后端都会接收,来者不拒,但是由于跨域问题,导致Django不认识它,所以

    不给它返回数据。

    复制代码
    ## Django跨域问题
    
    #### 什么是跨域
    
    ```python
    '''
    通常情况下,A网页访问B服务器资源时,不满足以下三个条件其一就是跨域访问
    1. 协议不同
    2. 端口不同
    3. 主机不同
    '''
    ```
    
    #### Django解决跨域
    
    ```python
    '''
    安装django-cors-headers模块
    
    在settings.py中配置
    # 注册app
    INSTALLED_APPS = [
        ...
        'corsheaders'
    ]
    # 添加中间件
    MIDDLEWARE = [
        ...
        'corsheaders.middleware.CorsMiddleware'
    ]
    # 允许跨域源
    CORS_ORIGIN_ALLOW_ALL = True
    '''
    ```
    复制代码

     解决跨域:

    ①在pycharm中安装django-cors-headers

    ②在Django配置文件中:

     

     然后前端进行处理数据:

    这样渲染msg后发现报错:

    发现msg没有被定义,但是在data中明明已经定义了msg,所以错误不在data中,最后发现在then的回调函数中的this

    问题解析:

    ① 在this.ajax上先声明个变量_this=this将vue实例存起来,然后在then的回调函数中打印this和_this

    从以上结果来看,在生命周期钩子函数下的this指向的是当前创建的vue实例,而在这些函数内部使用例如axios与后台交互后回调函数的内部的this并非指向当前的vue实例;

    若想拿到后台回传的数据更新data里的数据,不能在回调函数中直接使用this,而要用在外部函数定义的变量存储的this,也就是当前vue的实例。
    以上是一种解决方式,这里再补充另一种解决方法:使用es6语法箭头函数自动解决此类问题:

     

    箭头函数相当于匿名函数,并且简化了函数定义。看上去是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。此时this在箭头函数中已经按照词法作用域绑定了。很明显,使用箭头函数之后,箭头函数指向的函数内部的this已经绑定了外部的vue实例了.

     vue-cookie

    复制代码
    // 安装cookie的命令
    // npm install vue-cookie --save
    // 为项目配置全局vue-cookie(在main.js中)
    import VueCookie from 'vue-cookie'
    // 将插件设置给Vue原型,作为全局的属性,在任何地方都可以通过this.$cookie进行访问
    Vue.prototype.$cookie = VueCookie
    复制代码
    // 持久化存储val的值到cookie中
    this.$cookie.set('val', this.val)
    // 获取cookie中val字段值
    this.$cookie.get('val')
  • 相关阅读:
    无规矩不成方圆,聊一聊 Spring Boot 中 RESTful 接口设计规范
    一次SQL查询优化原理分析(900W+数据,从17s到300ms)
    重磅!GitHub官方开源新命令行工具
    JVM调优的反思与总结
    SpringMVC 进阶版
    《四大点,搞懂Redis到底快在哪里?》
    《Docker基础与实战,看这一篇就够了》
    带你从头到尾捋一遍MySQL索引结构
    MySQL信息提示不是英文问题
    完美解决windows+ngnix+phpcgi自动退出的问题
  • 原文地址:https://www.cnblogs.com/lakei/p/11115512.html
Copyright © 2020-2023  润新知