标题
- 环境
- VUE2目录
- public
- assets
- components
- main.js
- babel.config.js
- package.json
- vue.config.js
- 项目路由分析
- Header与Footer非路由组件完成
- Header示例
- 路由组件的搭建
- 声明式导航
- 编程式导航
- Footer组件的显示与隐藏
- 路由传递参数
- 重写push和replace
- 三级联动组件拆分
- 附件
环境
前提要有node.js
和webpack
环境,同时需要安装VUE-CLI,我的版本是@vue/cli 5.0.8
Vue CLI是一个基于Vue.js的快速开发工具,可以帮助开发者快速创建Vue.js项目。运行Vue CLI项目有以下步骤:
1.安装Vue CLI:使用npm或yarn安装Vue CLI,可以使用以下命令:
npm install -g @vue/cli
2.创建Vue项目:使用Vue CLI创建一个新的Vue项目,可以使用以下命令:
vue create app
其中,app是项目名称。
3.运行Vue项目:进入项目目录,并使用以下命令运行Vue项目:
cd app
npm run serve
4.访问Vue应用程序:在浏览器中访问运行Vue项目的地址,可以在终端中看到。默认情况下,应用程序地址为:http://localhost:8080/。
如果需要打包项目,可以使用以下命令:
npm run build
这将生成一个dist目录,其中包含打包的应用程序,具体的安装步骤可以查看vue-cli
加载出来的目录:
VUE2目录
public
放置静态资源文件,此文件夹中的静态文件资源在webpack打包的时候,会原封不动的打包到dist文件夹中。
assets
放置各个组件公用的静态资源,打包时,将其视作一个模块,打包到JS文件里面。
components
放置非路由组件,就是全局组件。
main.js
程序入口文件,最先执行。
babel.config.js
babel的配置文件。Babel 是一个 JavaScript 编译器。
package.json
项目引入的依赖信息 vue-cli-service serve --open
配置这个可以启动直接打开浏览器。
"scripts": {
"serve": "vue-cli-service serve --open",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
}
vue.config.js
自动加载的一个可选配置的VUE配置文件,项目启动就加载,使用module.exports
暴露所配的配置,例如关闭eslint检测:
module.exports = defineConfig({
// 关闭eslint检测
lintOnSave: false
})
具体可以参照:vue-config-js
项目路由分析
VUE中的路由通过vue-router
实现,核心根据路由地址去找路由组件,相当于key-value
的操作。此项目使用上中下的结构,上部,底部的样式不变中间改变,中间的搜索部分可以拆出一个公共组件。
上部:
底部:
这两部分不变可以做成一个公共的组件。
头部与底部组件:Header与Footer作为非路由组件,Home(主页)与Search(搜索),Login登录作为路由组件。
Header与Footer非路由组件完成
完成一个VUE项目的逻辑,先画页面,拆分组件,数据动态展示,数据动态业务处理。同时创建一个组件,需要找准它的结构,样式,以及静态资源。
Header示例
项目使用less控制css样式需要安装less与less-loader,直接执行命令:npm install --save less less-loader@5
或者package.json
文件中直接加依赖,然后npm install
下:
在components
文件夹下新建目录Header:
注意,识别less样式需要加lang="less"
<style scoped lang="less">
.footer {
background-color: #eaeaea;
.footer-container {
width: 1200px;
margin: 0 auto;
padding: 0 15px;
.footerList {
padding: 20px;
border-bottom: 1px solid #e4e1e1;
border-top: 1px solid #e4e1e1;
overflow: hidden;
padding-left: 40px;
.footerItem {
width: 16.6666667%;
float: left;
h4 {
font-size: 14px;
}
.footerItemCon {
li {
line-height: 18px;
}
}
&:last-child img {
width: 121px;
}
}
}
.copyright {
padding: 20px;
.helpLink {
text-align: center;
li {
display: inline;
.space {
border-left: 1px solid #666;
width: 1px;
height: 13px;
background: #666;
margin: 8px 10px;
}
}
}
p {
margin: 10px 0;
text-align: center;
}
}
}
}
</style>
但是发现样式错乱了,需要使用reset.css清除之前默认的样式:
reset.css
@import "./iconfont.css";
/* 清除内外边距 */
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote,
dl, dt, dd, ul, ol, li,
pre,
fieldset, lengend, button, input, textarea,
th, td {
margin: 0;
padding: 0;
}
/* 设置默认字体 */
body,
button, input, select, textarea { /* for ie */
/*font: 12px/1 Tahoma, Helvetica, Arial, "宋体", sans-serif;*/
font: 12px/1.3 "Microsoft YaHei",Tahoma, Helvetica, Arial, "\5b8b\4f53", sans-serif; /* 用 ascii 字符表示,使得在任何编码下都无问题 */
color: #333;
}
h1 { font-size: 18px; /* 18px / 12px = 1.5 */ }
h2 { font-size: 16px; }
h3 { font-size: 14px; }
h4, h5, h6 { font-size: 100%; }
address, cite, dfn, em, var, i{ font-style: normal; } /* 将斜体扶正 */
b, strong{ font-weight: normal; } /* 将粗体扶细 */
code, kbd, pre, samp, tt { font-family: "Courier New", Courier, monospace; } /* 统一等宽字体 */
small { font-size: 12px; } /* 小于 12px 的中文很难阅读,让 small 正常化 */
/* 重置列表元素 */
ul, ol { list-style: none; }
/* 重置文本格式元素 */
a { text-decoration: none; color: #666;}
/* 重置表单元素 */
legend { color: #000; } /* for ie6 */
fieldset, img { border: none; }
button, input, select, textarea {
font-size: 100%; /* 使得表单元素在 ie 下能继承字体大小 */
}
/* 重置表格元素 */
table {
border-collapse: collapse;
border-spacing: 0;
}
/* 重置 hr */
hr {
border: none;
height: 1px;
}
.clearFix::after{
content:"";
display: block;
clear:both;
}
/* 让非ie浏览器默认也显示垂直滚动条,防止因滚动条引起的闪烁 */
html { overflow-y: scroll; }
a:link:hover{
color : rgb(79, 76, 212) !important;
text-decoration: underline;
}
/* 清除浮动 */
.clearfix::after {
display: block;
height: 0;
content: "";
clear: both;
visibility: hidden;
}
然后在index.html页面:<link rel="stylesheet" href="./reset.css">
使用Header组件
在App.vue
注册这个组件使用:
App.vue代码:
<template>
<div>
<!--使用组件-->
<Header></Header>
<router-view></router-view>
<Footer v-show="$route.meta.show"></Footer>
</div>
</template>
<script>
// 导入组件
import Header from './components/Header';
import Footer from './components/Footer';
export default {
name: 'App',
components: {
Header,
Footer
},
mounted(){
// 只发一次
this.$store.dispatch('categoryList');
}
}
</script>
<style>
</style>
操作Footer组件的步骤与Header一致。
路由组件的搭建
项目的路由组件分为四个,Home,Search,Login,Register,需要安装vue-router
路由npm install --save vue-router
。路由组件一般放在pages或views文件夹下。
在router中的index.js需要引入这些路由组件,并对外暴露。
// 导入路由组件
import Vue from 'vue';
import VueRouter from 'vue-router';
// 使用插件
Vue.use(VueRouter);
// 引入路由组件
import Home from '@/pages/Home';
import Search from '@/pages/Search';
import Login from '@/pages/Login';
import Register from '@/pages/Register';
// 配置路由
export default new VueRouter({
// 配置路由
routes: [
{
path: "/home",
component: Home,
meta: {
show: true
}
},
{
path: "/search/:keyword?",
component: Search,
meta: {
show: true
},
name: 'search'
},
{
path: "/login",
component: Login,
meta: {
show: false
}
},
{
path: "/register",
component: Register,
meta: {
show: false
}
},
{
// 页面重定向,访问/重定向到首页
path: "*",
redirect: "/home"
},
]
});
上面只是暴露了这些组件,还需将这些组件在main.js
中进行注册:
声明了router之后,只要组件注册了,组件就会有$route
属性,主要接收路由所携带的参数信息,对于$router
来说,$router
是用于进行路跳转并携带参数的。
关于路由的信息可参照vue-router官网。
最后要想路由生效需要在App.vue中加入:<router-view/>
声明式导航
用图中三个链接来做一下声明式导航的例子,点击对应的链接进入到相应的页面中,如点击图片进入首页。
具体实现:使用router-link
中的to标签进行路由跳转。
编程式导航
编程式导航主要是用于携带参数跳转的路由。比如关键字搜索:
搜索按钮中定义,goSearch()
方法
实现这个方法:内部实现后面细说。
Footer组件的显示与隐藏
希望在登录或者注册情况下将底部组件隐藏,可以在 路由配置文件index.js使用路由元信息meta
进行配置:
在应用此Footer组件的地方使用$route.meta.show
获取值即可。
路由传递参数
路由传参主要有两种写法,params
与query
区别官网说的很详细,主要就是params
可以占位,query
不可占位。
上面简单说了编程式导航,接下来看看编程式导航如何进行传参。
以关键字查询为例:
字符串传参与模板传参
// 字符串传参
this.$router.push("/search/"+this.keyword+"?k="+this.keyword.toUpperCase())
.catch(err => err)
// 模板传参
this.$router.push(`/search/${this.keyword}?k=${this.keyword.toUpperCase()}`)
.catch(err => err)
对象传参
对象传参的方式最常见。
// 对象传参
this.$router.push({
name: "search",
params: {
keyword: this.keyword
},
query: {
k: this.keyword.toUpperCase()
}
})
需要在对应的路由中声明参数name: "search"
,标识这是/search
路由,不可使用直接使用path
。
使用$route.params.keyword
与$route.query.k
获取指定的值。
重写push和replace
直接使用Vue自带的push或repalce方法,当你多次点击同一个路由时,控制台就会报NavigationDuplicated
的错,虽然不影响代码实现的功能,但是忍不了红色的错误。
这里一般是固定的写法,拿来用即可解决上述问题。
// 先把VueRouter原型对象的push,先保存一份
let originPush = VueRouter.prototype.push;
let originReplace = VueRouter.prototype.replace;
// 重写push|replace
// 第一个参数:告诉原来push方法,你往哪里跳转(传递哪些参数)
// 第二个参数:成功的回调
// 第三个参数:失败的回调
// call || apply区别
// 相同点,都可以调用函数一次,都可以篡改函数的上下文一次
// 不同点:call与apply传递参数:call传递参数用逗号隔开,apply方法执行,传递数组
VueRouter.prototype.push = function (location, resolve, reject) {
if (resolve && reject) {
originPush.call(this, location, resolve, reject);
} else {
originPush.call(this, location, () => {
}, () => {
})
}
}
VueRouter.prototype.replace = function (location, resole, reject) {
if (resole && reject) {
originReplace.call(this, location, resole, reject);
} else {
originReplace.call(this, location, () => {
}, () => {
})
}
}
三级联动组件拆分
三级联动组件在Home、Search、Detail等组件会用到,可以将其弄成一个公共的全局组件TypeNav
。
参考Header组件导入静态资源之后,将其在main.js
注册为一个全局的组件,好处就是无需import
即可在项目中任意地方使用,Header之前import了因为没有在main.js
注册成一个全局的组件。
// 三级联动全局组件
import TypeNav from '@/components/TypeNav';
// 注册为全局组件 arg1: 组件名称 arg2: 当前组件
Vue.component(TypeNav.name,TypeNav)
随后,我们在Home组件的index.vue注册<TypeNav/>
即可。
随后我们可以按照之前的步骤将首页剩下的页面拆成一个个组件进行注册:
导入这些组件并注册:
附件
最后展示的截图信息是这样的: