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总结