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>

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>

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

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

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

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

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

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

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

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

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

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

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

什么是跨域问题?

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

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('后台数据')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值