1.环境搭建
安装node.js
vue-cli脚手架初始化项目
vue create [项目名称]
选择vue2版本
2.项目基本配置
package.json设置项目启动时自动打开浏览器运行
"scripts":{
"server":"vue-cli-server server --open"
}
之后在npm run serve的时候就会自动打开
vue.config.js关闭eslint自动校验工具
module.exports = defineConfig({
lintOnSave:false
})
不关闭会有很多语法错误导致项目无法运行
jsconfig.json给src文件夹配置别名
"paths": {
"@/*": [
"src/*"
]
},
3.一般项目开发时的步骤
- 书写静态页面Html+css
- 拆分组件
- 调用接口获取服务器数据动态展示到页面
- 完成相应动态业务逻辑功能
4.vue-router安装及使用
npm install vue-router@3
由于项目是基于vue2的,因此vue-router不能安装4.X的版本
//main.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import router from "./router"
Vue.use(VueRouter)
new Vue({
el: "#app",
render: (h) => h(App),
// 配置路由
router: router
});
如果在一个模块化工程中使用它,必须要通过 Vue.use() 明确地安装路由功能
import Home from '@/pages/Home'
import Search from '@/pages/Search'
//定义路由
const routes = [
{ path: '/home', component: Home },
{ path: '/search', component: Search }
]
// 创建 router 实例,然后传 `routes` 配置
const router = new VueRouter({
routes, // (缩写) 相当于 routes: routes
// 滚动行为,让每次路由跳转后页面从顶端显示
scrollBehavior(to, from, savedPosion) {
//返回的这个y=e,代表的滚动条在最上方
return { y: 0 };
},
})
// 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能,
//其他组件身上都会有$route和$router属性并且可以使用他们身上的方法
const app = new Vue({
router
}).$mount('#app')
用<router-view></router-view>标签定义路由组件的出口
路由组件与非路由组件区别
- 路由组件一般存放于pages/views文件夹下,非路由组件一般存放于components文件夹下
- 路由组件需要在router文件夹下进行注册,注册时一般使用组件的名字。非路由组件在使用的时候一般都是通过标签的形式使用
- 注册完路由后,不管是不是路由组件,它们身上都会有
$route和$router属性
$route:一般用于获取路由信息(路由、query以及params等等)
$router:一般用于编程式导航进行路由跳转(push和replace)
路由跳转的两种方式
声明式导航
通过router-link组件来导航
<p>
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
编程式导航
一般用于通过点击按钮触发事件进行路由跳转
注意:在 Vue 实例内部,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push。
// 字符串
router.push('/home')
// 对象
router.push({ path: '/home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
路由元信息的使用
定义路由的时候可以配置 meta 字段:
const routes = [
{ path: '/home', component: Home,meta:{show:true} },
{ path: '/search', component: Search ,meta:{show:true}}
]
通过给show字段一个布尔值并用v-show控制一个在不同路由下的组件显示与隐藏
<Footer v-show="$route.meta.show"></Footer>
路由传参
方式一:通过 params 传参
编程式:
data:{
username: ''
},
login() {
...
this.$router.push({
name: 'home', //注意使用 params 时一定不能使用 path
params: { username: this.username||{} },//至少传递一个undefinde否则空串会使url出错
})
}
声明式:
<router-link :to="{ name: 'home', params: { username: username } }">
params 传参后,刷新页面会失去拿到的参数。所以路由参数要修改为 '/home/:username'(官方称为动态路由)
const routes = [
{
path: '/login',
component: Login
},
{
path: '/home/:username?',//占位params却未传递params参数跳转后会导致url出错,因此需要加'?'
name: 'home',
component: Home
}
]
在组件中通过this.$route.params.username取值
方式二:通过 query 传参
编程式:
data:{
username: ''
},
login() {
this.$router.push({
name: 'home',
query: { username: this.username },
})
}
声明式:
<router-link :to="{ path: '/home', query: { username: username } }">
路由传递props参数:
const routes = [
{
path: '/login',
component: Login
},
{
path: '/home/:username?',//占位params却未传递params参数跳转后会导致url出错,因此需要加'?'
name: 'home',
component: Home,
//布尔值写法:如果 `props` 被设置为 `true`,`route.params` 将会被设置为组件属性。
//props:true,
//对象式写法:props会被按原样设置为组件属性。当 `props` 是静态的时候有用。
//props:{a:1}
//函数式写法
props: ($route) => ({
keyword: $route.query.keyword,
k:$route.params.k
})
}
]
重写replace和push方法
由于push是一个promise,promise需要传递成功和失败两个参数,而我们的push中没有传递。所以多次执行编程式路由跳转时会抛出异常。
方法:
this.$router.push({name:‘Search’,params:{keyword:"this.keyword"||undefined}},()=>{},()=>{})
后面两项分别代表执行成功和失败的回调函数。
这种写法治标不治本,将来在别的组件中push|replace,编程式导航还是会有类似错误
//1、先把VueRouter原型对象的push,保存一份
let originPush = VueRouter.prototype.push;
let originReplace = VueRouter.prototype.replace;
//2、重写push
//第一个参数:告诉原来的push,跳转的目标位置和传递了哪些参数
VueRouter.prototype.push = function (location, resolve, reject) {
if (resolve && reject) {
originPush.call(this, location, resolve, reject);
} else {
originPush.call(
this,//改变this指向之后调用push方法的那个VueRouter实例,否则会指向window
location,//传入一个对象告诉原来的push,跳转的目标位置和传递了哪些参数
() => {},//成功的回调
() => {}//失败的回调
);
}
};
//3.重写replace
VueRouter.prototype.replace = function (location, resolve, reject) {
if (resolve && reject) {
originReplace.call(this, location, resolve, reject);
} else {
originReplace.call(
this,//改变this指向之后调用push方法的那个VueRouter实例,否则会指向window
location,
() => {},
() => {}
);
}
};