vue04

Vue项目环境

"""
vue ~~ Django  框架
node ~~ Python  通过node就可以给电脑下载Vue环境,node解释执行js语法
npm ~~ pip  node自带npm商城,下载
"""
node语言是C++写的,python语言是C写的

首先,下载node环境:

下载node解释器:点我下载

​ 安装时选择AddtoPath,添加环境变量,其他无需操作,直接next即可;

查看node版本号:
	C:\Users\Administrator>node --version
    v12.14.0
查看node安装的所有包:
	C:\Users\Administrator>npm list
    C:\Users\Administrator
	`-- (empty)	
    
查看npm的版本号:
	C:\Users\Administrator>npm --version
	6.13.4

更改镜像源(npm走的是国外的源,现在改成cnpm,走国内的淘宝源;):
    npm install -g cnpm --registry=https://registry.npm.taobao.org
查看cnpm的版本号:
	C:\Users\Administrator>cnpm --version
===============================================================================
cnpm@6.1.1 (C:\Users\Administrator\AppData\Roaming\npm\node_modules\cnpm\lib\parse_argv.js)
npm@6.13.4 (C:\Users\Administrator\AppData\Roaming\npm\node_modules\cnpm\node_modules\npm\lib\npm.js)
node@12.14.0 (C:\Program Files\nodejs\node.exe)
npminstall@3.25.2 (C:\Users\Administrator\AppData\Roaming\npm\node_modules\cnpm\node_modules\npminstall\lib\index.js)
prefix=C:\Users\Administrator\AppData\Roaming\npm
win32 x64 6.1.7601
registry=https://r.npm.taobao.org
=================================================================================

安装脚手架:
	cnpm install -g @vue/cli
清空缓存:
	npm cache clean --force
    
如果安装脚手架失败,基本上是网络原因,可以清空缓存,再安装一次;

C:\Users\Administrator>vue ui
Starting GUI...
Ready on http://localhost:8000  # 在浏览器页面访问Vue 8000端口  是一个可视化界面可以创建vue项目;
    

项目的创建

创建项目

vue create 项目名 
// 要提前进入目标目录(项目应该创建在哪个目录下)
// 选择自定义方式创建项目,选取Router, Vuex插件
各插件的用途:
	*Babel:将ES6语法解析成ES5语法;现在写项目是以ES6语法为主,但是项目形成的时候要把ES6语法解析成ES5语法给浏览器,虽然浏览器对ES6的语法支持几乎100%,但并不是100%的兼容,但ES5是100%的兼容
	TypeScript:TS编程使用时,需要勾选,TS对js作了更多层的封装;
    Progressive WebApp(PWA)Support  做前台配置,可以优化项目;
    *Router:前台的路由,控制页面跳转;
    *Vuex:仓库,相当于全局的单例,完成组件之间的传参,为移动端做辅助的;页面刷新时会加载仓库,仓库设置的是默认值,后期逻辑修改了默认值,刷新页面会重新变回默认值,PC端存的值就丢了。主要是给移动端使用的,移动端加载的是app,没有刷新,只能退出、重开;
	CSS Pre-processors(CSS预编译器):需要安装less,sass;内部可以写CSS逻辑,定义变量,并将逻辑解析为标准的CSS样式。
    Linter/Formatter:格式化代码,统一前台编码规范;做项目的时候安装,2个缩进是对的,4个就是错的。   # 这个默认是选中的,要取消掉。
    Unit Testing:测试用
	E2E Testing:测试用

创建项目的配置情况:

创建的vue项目,内部文件夹:

启动/停止项目

npm run serve / ctrl+c
// 要提前进入项目根目录

> day62_vproj@0.1.0 serve G:\Python代码日常\day62_vproj
> vue-cli-service serve
 INFO  Starting development server...
...
...
...
 DONE  Compiled successfully in 25230ms

  App running at:
  - Local:   http://localhost:8080/  # 使用该端口就可以用浏览器访问Vue项目
  - Network: http://192.168.13.73:8080/ #   使用该端口也可以用浏览器访问Vue项目

  Note that the development build is not optimized.
  To create a production build, run npm run build.

打包项目

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

vue根据配置重新构建依赖

创建一个新文件夹,将原项目中的public、src文件夹、以及package.json文件放入新建文件夹中,启动cmd窗口,并进入进件文件夹内,输入如下命令:
		cnpm install
 然后新项目会根据package.json文件构建项目依赖
如果发现创建的依赖(node_modules)中,缺少某些插件可以自己手动安装:
	进入重新新建依赖的项目中,输入如下命令:
    	cnpm install 插件名(比如ajax)

pycharm管理vue项目

之后,直接在pycharm中启动项目就可以了,直接点击终端链接,就可在浏览器页面打开站点;

vue项目目录结构分析

├── v-proj
|	├── node_modules  	// 当前项目所有依赖,一般不可以移植给其他电脑环境
|	├── public			
|	|	├── favicon.ico	// 标签图标
|	|	└── index.html	// 当前项目唯一的页面
|	├── src
|	|	├── assets		// 静态资源img、css、js
|	|	├── components	// 小组件
|	|	├── views		// 页面组件
|	|	├── App.vue		// 根组件
|	|	├── main.js		// 全局脚本文件(项目的入口)
|	|	├── router
|	|	|	└── index.js// 路由脚本文件(配置路由 url链接 与 页面组件的映射关系)
|	|	└── store	
|	|	|	└── index.js// 仓库脚本文件(vuex插件的配置文件,数据仓库)
|	├── README.md
└	└── package.json等配置文件

vue项目生命周期

1.启动项目,加载主脚本文件 main.js
	加载Vue环境,创建根组件完成渲染;
    加载系统已有的第三方环境:router、store;
    加载自定义的第三方环境与自己配置的环境,后期项目不断添加;
    
2.router被加载,就会解析router文件夹下的index.js脚本文件,完成路由---组件的映射关系;
3.新建视图组件.vue(在views文件夹中),在路由中配置(在router的index.js中),设置路由跳转(在App.vue文件的导航栏中)
在main.js文件中导入js或者vue后缀的文件可以省略文件的后缀名,在导入img或者css文件时后缀名不能省略;

App.vue中的template内的<router-view></router-view>, 给views文件夹内的.vue组件占位的占位符 多一个views中的文件内容就会在页面中多渲染一次;
public文件夹中的index.html文件中的:
	  <div id="app">  </div>
	  给跟组件(App.vue)中的<template></template>占位
      

views文件夹内的.vue文件介绍

1)template标签负责组件的html结构,有且只有一个标签;
2).vue内的script标签负责组件的js逻辑,逻辑固定导出export default {组件内容}  (外界才可以导入);
3)style标签负责组件的css样式,scoped参数保证样式的组件化,样式只在该组件内部起作用;
<!--home.vue-->
<template>
  <div class="home">

    <h1>首页</h1>
    <hr>
    <Nav></Nav>
  </div>
</template>

<script>

import Nav from '../components/Nav'

export default {
    data () {
        return {}
    },
    methods:{},
    components:{
       Nav,
    }

}
</script>

<style scope>
  h1 {
    color:red;
  }
</style>
<!--components文件夹下面的Nav.vue文件-->
<template>
    <div class="nav">
        <h1>导航栏</h1>
    </div>
</template>

<script>
    export default {
        name: "Nav"
    }
</script>

<style scoped>
    h1 {
        color:green;
    }
</style>

配置自定义全局样式

全局样式可以写在src>assets文件夹下面自定义的文件夹下面,自己创建一个全局的css样式文件然后在main.js中导入该文件,样式即可生效。

// 配置全局样式:@符号代表src的绝对路径
方式1:
import './assets/css/global.css'  // css文件的后缀一定要写
方式2:
import abc from  '@/assets/css/global.css'  // 把css文件加载成变量abc,然后使用这个变量;如果创建项目时插件Linter/Formatter没被取消掉,因为abc变量没被使用,会报错,这种方法就没办法使用了;
方式3:
require('@/assets/css/global.css' ) //官方建议加载静态文件使用require

导航栏组件及路由逻辑跳转

this.$router  # 控制路由跳转
(this.$route)  # 控制路由数据


# 方式1:
this.$router.push('/路由名')
# 方式2:
this.$router.push({name: '路由名', query: {拼接的参数}})  # 逻辑跳转 往下再跳转一页
this.$router.go(number)  # go是历史记录前进后退,正为前进,负为后退,数字为步数;


# 路由的两种书写方式:
<router-link to="/course">课程页</router-link>  # 标签跳转  在html代码内部解析成a标签,href='/course'
'''
<a data-v-65af85a3="" href="/course" class="router-link-exact-active router-link-active">课程页</a>
'''
<router-link :to="{name:'course'}">课程页</router-link>
# src>components>Nav.vue  导航栏组件(小组件)

<template>
    <div class="nav">
       <div class="content">
            <ul>
                <li class="logo">
                    <img src="@/assets/img/aaa.svg" alt="" @click="goHome">
                </li>
                <li class="route">
                    <router-link to="/">主页</router-link>
                </li>
                <li class="route">
                    <router-link to="/course">课程页</router-link>
                    <!--<router-link :to="{name:'course'}">课程页</router-link>-->
                </li>
            </ul>
       </div>
    </div>
</template>

<script>
    export default {
        name: "Nav",
        methods:{
            goHome () {
                // console.log('去主页');
                // console.log(this.$router);  // 控制路由跳转
                console.log(this.$route); // 控制路由数据
                if (this.$route.path !== '/') {
                     // this.$router.push('/');  // 再跳转一页
                     this.$router.go(15); // go是历史记录前进后退,正为前进,负为后退,数字为步数;
                }
            }
        }
    }
</script>    
<style scoped>
   .nav {
       width: 100%;
       height: 60px;
       background-color: #eee;
   }
    .content {
        width: 1200px;
        margin: 0 auto;
        /*background-color: green;*/
        line-height: 60px;
    }
    .content ul li {
        float: left;
        cursor:pointer;
    }
    a {
        color:black;
        text-decoration: none;
    }
    .logo {
        /*padding-left: 0;*/
        padding-top: 10px;
        padding-right: 50px;
    }

    .route {
        padding:0 10px 0;
    }

    .route a {
        border-bottom: 3px solid transparent;
    }
    .route a.router-link-exact-active {
        color: orange;
        border-bottom-color: orange;
    }
</style>
this.$router  # 控制路由跳转
'''
VueRouter {app: Vue, apps: Array(1), options: {…}, beforeHooks: Array(0), resolveHooks: Array(0), …}
afterHooks: []
app: Vue {_uid: 2, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
apps: [Vue]
beforeHooks: []
fallback: false
history: HTML5History {router: VueRouter, base: "", current: {…}, pending: null, ready: true, …}
matcher: {match: ƒ, addRoutes: ƒ}
mode: "history"
options: {mode: "history", base: "/", routes: Array(2)}
resolveHooks: []
currentRoute: (...)
__proto__: Object
'''
(this.$route)  # 控制路由数据
'''
{name: "course", meta: {…}, path: "/course", hash: "", query: {…}, …}
fullPath: "/course"
hash: ""
matched: [{…}]
meta: {}
name: "course"
params: {}
path: "/course"
query: {}
__proto__: Object
'''

路由重定向

# router>index.js
const routes = [  // 组件的配置
 {
    path: '/',
    name: 'home',
    component: Home
 },
{
    path: '/home',
    redirect:'/'
},
           ];

组件的生命周期钩子

====>官方文档“生命周期钩子”

1).一个组件从创建到销毁的众多时间节点回调的方法;
2).这些方法都是vue组件实例的成员;
3).生命周期钩子的作用就是满足在不同时间节点需要完成的事;
<script>
    import Nav from '../components/Nav'
    export default {
        data(){
            return {
                back_data: ''
            }
        },
        methods: {},
        components: {
            Nav,
        },
        beforeCreate() {
            console.log('Home组件要创建了');
            console.log(this.back_data);
        },
        created() { // 重要方法:在该钩子中完成后台数据的请求
            console.log('Home组件创建成功了');
            console.log(this.back_data);
        },
        beforeMount() {
            console.log('Home组件准备加载')
        },
        mounted() {  // 特别耗时的数据请求,可以延后到组件初步加载成功后,再慢慢请求
            console.log('Home组件加载完成')
        },
        destroyed() {
            console.log('Home组件销毁成功了')
        }
    }
</script>

课程主页渲染

# views>Course.vue文件

<template>
    <div class="course">
        <Nav/>
        <div class="wrap">
            <CourseTag v-for="course in courses" :course="course" />  # 变量course(对象)在小组件的CourseTag中能拿到
        </div>
    </div>
</template>

<script>
    import Nav from '../components/Nav'
    import CourseTag from '../components/CourseTag'

    export default {
        name: "Course",
        data() {
            return {
                courses: [],
            }
        },
        components: {
            Nav,
            CourseTag,
        },
        beforeCreate() {
            console.log('Course组件要创建了')
        },
        created() {
            console.log('Course组件创建成功了');
            // 前后台开发时,是从后台请求数据
            this.courses = [
                {
                    id: 1,
                    title: '西游记',
                    // img: 'http://...',  // 实际是后台图片链接
                    img: require('@/assets/img/001.jpg'),  // 前台逻辑中加载静态资源采用require
                },
                {
                    id: 3,
                    title: '西厢记',
                    // img: 'http://...',  // 实际是后台图片链接
                    img: require('@/assets/img/002.jpg'),  // 前台逻辑中加载静态资源采用require  前台一个组件加载样式,再传给其他组件用,不能通过标签直接去加载,要通过逻辑加载,就是使用require。
                },
            ]
        },
        destroyed() {
            console.log('Course组件销毁成功了')
        }
    }
</script>

<style scoped>
    .wrap {
        width: 1100px;
        margin: 0 auto;
    }

    .wrap:after {
        content: '';
        display: block;
        clear: both;
    }
</style>
# components>CourseTag.vue文件
<template>
    <div class="course-tag">
        <img :src="course.img" alt="">
        <h2>{{ course.title }}</h2>
    </div>
</template>

<script>
    export default {
        name: "CourseTag",
        props: ['course'],
        
</script>

<style scoped>
    .course-tag {
        width: 200px;
        border-radius: 10px;
        overflow: hidden;
        background-color: #eee;
        float: left;
        margin: 10px;
    }

    .course-tag img {
        width: 100%;
        height: 240px;
    }

    .course-tag a {
        text-align: center;
        font-weight: normal;
        font-size: 20px;
        display: block;
    }
</style>

路由传参

路由知识点概况:
	1)路由配置:router/index.js
	2)路由跳转与路由渲染:router-link、router-view、$router.push、$router.go
	3)路由传参:两种传参
// index.js文件 的路由配置

// 第一种路由传参
path: '/course/detail',

// 第二种路由传参
path: '/course/:pk/detail',
name: 'course-detail',
component: CourseDetail
<!--CourseTag.vue文件-->

<template>
    <div class="course-tag">
        <img :src="course.img" alt="" @click="goDetail(course.id)">

        <!--第一种路由传参-->
        方式一:
        <router-link :to="`/course/detail?pk=${course.id}`">{{ course.title }}</router-link>
		方式二:
        <router-link :to="{
            name: 'course-detail',
            query: {pk: course.id}
        	}">{{ course.title }}
        	</router-link>

        <!--第二种路由传参-->
        <router-link :to="`/course/${course.id}/detail`">{{ course.title }}</router-link>


    </div>
</template>

<script>
    export default {
        name: "CourseTag",
        props: ['course'],
        methods: {
            goDetail(pk) {
                // this.$router.push(`/course/detail?pk=${pk}`);
                this.$router.push({
                    name: 'course-detail',
                    query: {pk: pk}
                });
            }
        }
    }
</script>
<!--CourseDetail.vue文件-->

<template>
    <div class="course-detail">
        <button @click="$router.go(-1)">返回课程主页</button>
        <hr>
        <h1>第{{ pk }}个课程的详情</h1>
    </div>
</template>

<script>
    export default {
        name: "CourseDetail",
        data() {
            return {
                pk: 0
            }
        },
        created() {
            // 获取路由传递的参数:课程的id
            // console.log(this.$route);
            // console.log(this.$route.query.pk);
            this.pk = this.$route.query.pk || this.$route.params.pk;
        }
    }
</script>

<style scoped>

</style>

====>vue04总结

posted on 2019-12-23 01:51  jueyuanfengsheng  阅读(374)  评论(0编辑  收藏  举报