尚硅谷VUE项目-前端项目问题总结01
项目重点:分页—注册登录页—支付
前端需要掌握的技术:分页—轮播图—日历
1 创建项目
vue create app
vue cli 版本在3以下的,需要升级,create是3的用法
npm uninstall -g vue-cli
npm install -g @vue/cli
npm install -g @vue/cli@4.5.13
注意:要用Vue CLI v4.5.13
视频里Vue CLI v4.5.13 我安装时是Vue CLI v5.0.1,配置自动打开浏览器–open时有问题,所以还是用视频中的版本吧
2 打开项目,自动打开浏览器
$ cd app
$ npm run serve
在package.json -->scripts中 添加–open
// "serve": "vue-cli-service serve",
"serve": "vue-cli-service serve --open",//浏览器自动打开
3 脚手架使用
创建项目的两种方法:
vue init webpack 项目的名字
vue create 项目名称
脚手架目录:public + assets文件夹区别
node_modules:放置项目依赖的地方
public:一般放置一些共用的静态资源,打包上线的时候,public文件夹里面资源原封不动打包到dist文件夹里面
src:程序员源代码文件夹
-----assets文件夹:经常放置一些静态资源(图片),assets文件夹里面资源webpack会进行打包为一个模块(js文件夹里面)
-----components文件夹:一般放置非路由组件(或者项目共用的组件)
App.vue 唯一的根组件
main.js 入口文件【程序最先执行的文件】
babel.config.js:babel配置文件
package.json:看到项目描述、项目依赖、项目运行指令
README.md:项目说明文件
脚手架下载下来的项目稍微配置一下
3.1:浏览器自动打开
在package.json文件中
"scripts": {
"serve": "vue-cli-service serve --open",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
3.2关闭eslint校验工具
创建vue.config.js文件:需要对外暴露
module.exports = {
lintOnSave:false,
}
3.3 src文件夹的别名的设置
(jsconfig.json 是给 vscode 配置的,如果有 Vetur 插件的话,也会读这个文件。项目里的路径别名是在 webpack 里配置的)
因为项目大的时候src(源代码文件夹):里面目录会很多,找文件不方便,设置src文件夹的别名的好处,找文件会方便一些
创建jsconfig.json文件,放在根目录
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": [
"src/*"
]
}
},
"exclude": [
"node_modules",
"dist"
]
}
如果报错 将设置中的check JS勾上
左下角齿轮->设置->JS/TS Strict Null Checks???
重启
4 项目介绍
4.1静态页面、样式、清除默认样式引入
复制静态资源页面(HTML+CSS)到项目中,项目中用的是less,需要安装less和less-loader
cnpm install --save less less-loader@5
并在style上添加
<style lang="less" scoped></style>
reset.css文件一般放在public下,并引入
5 路由组件的搭建
安装vue-router
//视频中用的版本3.5.3
cnpm install --save vue-router
cnpm install --save vue-router@3.5.3
cnpm install --save vue-router@3
pages或者assets中写路由组件
router中配置路由
//配置路由的地方
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:'*',
redirect:'/home',
},
{
path:'/home',
component:Home,
},
{
path:'/search',
component:Search,
},
{
path:'/login',
component:Login,
},
{
path:'/register',
component:Register,
},
]
})
在入门文件main.js注册router
//注册路由信息,当这里书写router时,组件身上都拥有$route, $router属
import Vue from 'vue'
import App from './App.vue'
// Vue.config.productionTip = false
import router from '@/router'
new Vue({
render: h => h(App),
//注册路由:底下的写法是kv一致省略v,切router小写
//注册路由信息,当这里书写router时,组件身上都拥有$route,$router属性
router,
}).$mount('#app')
在app.vue中加入路由出口 router-view
注意:路由组件以router-view出现,非路由以标签形式(Header) 出现
<template>
<div id="app">
<Header></Header>
<!-- 路由出口 -->
<router-view></router-view>
<Footer></Footer>
</div>
</template>
<script>
// 非组件路由在这里引入,组件路由在router引入
import Header from './components/Header'
import Footer from './components/Footer'
export default {
name: 'App',
components: {
Header,
Footer,
}
}
</script>
<style scoped>
</style>
6 路由组件,路由-----跳转 总结
//声明式导航
<router-link to="/login">登录</router-link>
<router-link class="register" to="/register">免费注册</router-link>
<router-link class="logo" to="/home">
<img src="./images/logo.png" alt="" />
</router-link>
//编程式导航
<button class="sui-btn btn-xlarge btn-danger" type="button" @click="goSearch"> 搜索 </button>
goSearch(){ this.$router.push('/home')},
7 v-if 和v-show
路由元信息:配置路由时,meta
<Footer v-show="$route.meta.show"></Footer>
这里如果v-show不生效,可在footer上套一个div来进行v-show就可以正常显示了
首页|搜索底部是有Footer组件,而登录注册是没有Footer组件
Footer组件显示|隐藏,选择v-show|v-if
路由元信息meta
面试题:v-show与v-if区别?
v-show:通过样式display控制
v-if:通过元素上树与下树进行操作
面试题:开发项目的时候,优化手段有哪些?
1:v-show|v-if
2:按需加载
8 路由-----传参
8.1 字符串传参(params和query)
<button class="sui-btn btn-xlarge btn-danger" type="button" @click="goSearch" > 搜索</button>
goSearch() {
//字符串params传参,路由配置path加占位/:keyword(name可不写,因为没用name)
// this.$router.push('/search/'+this.keyword);
//字符串query传参
// this.$router.push('/search/?joan='+this.keyword.toUpperCase());
// this.$router.push('/search/'+'?joan='+this.keyword.toUpperCase());
//字符串params,query混合传参
this.$router.push('/search/'+this.keyword+'?joan='+this.keyword.toUpperCase());
},
//search接收参数
<h1>params参数======{{$route.params.keyword}}</h1>
<h1>query参数======{{$route.query.joan}}</h1>
8.2 第二种:模板字符串传参
this.$router.push(`/search/${this.keyword}?joan=${this.keyword.toUpperCase()}`)
//search接收参数
<h1>params参数======{{$route.params.keyword}}</h1>
<h1>query参数======{{$route.query.joan}}</h1>
8.3对象形式传参(最常用,重点)
推荐用query,不用写name
params不能用path
//第三种:对象形式(最常见的形式) params需要路由配置name (切记:传参为对象形式,并且用query,要用name,不能用path!!!!!)
{
path:'/search/:keyword',
component:Search,
meta:{
show:true,
},
name:'search'//传参方式为对象,用params传参
},
this.$router.push({name:'search',params:{keyword:this.keyword},query:{joan:this.keyword.toUpperCase()}})
//search接收参数
<h1>params参数======{{$route.params.keyword}}</h1>
<h1>query参数======{{$route.query.joan}}</h1>
9 路由传参,及路由传参props等面试题
//params参数:路由需要占位,程序就崩了,属于URL当中一部分
//query参数:路由不需要占位,写法类似于ajax当中query参数
//路由传递参数先关面试题
// 1:路由传递参数(对象写法)path是否可以结合params参数一起使用?
this.$router.push({path:'/search',params:{keyword:this.keyword},query:{joan:this.keyword.toUpperCase()}})
// 不可以:不能这样书写,程序会崩掉
// 2:如何指定params参数可传可不传?
//路由要求传递params参数(已占位),但是没传,那么url会出错(缺少search)
this.$router.push({name:'search',query:{joan:this.keyword.toUpperCase()}})
// 可在路由中加?
{
path:'/search/:keyword?',//:params传参的占位;?参数可传可不传
component:Search,
meta:{
show:true,
},
name:'search'//传参方式为对象,用params传参
},
// 3:params参数可以传递也可以不传递,但是如果传递是空串,如何解决?
//不传url上没有search
this.$router.push({name:'search',params:{keyword:''},query:{joan:this.keyword.toUpperCase()}})
//解决:加undefined
this.$router.push({name:'search',params:{keyword:''||undefined},query:{joan:this.keyword.toUpperCase()}})
// 4:如果指定name与params配置, 但params中数据是一个"", 无法跳转,路径会出问题
// 5: 路由组件能不能传递props数据?
//可以。三种(***推荐第三种函数形式***)
// 第一种方法:布尔值写法-只能是params
this.$router.push({name:'search',params:{keyword:this.keyword},query:{joan:this.keyword.toUpperCase()}})
{
path:'/search/:keyword?',//:params传参的占位;?参数可传可不传
component:Search,
meta:{
show:true,
},
name:'search',//传参方式为对象,用params传参
props:true, //路由组件传props数据 第一种方法:布尔值写法-只能是params
},
<h1>路由组件传参-params======{{keyword}}</h1>
<script>
export default {
props:['keyword'],
name: "Search",
};
// 第二种方法:对象 额外的给路由组件传递一些props
{
path:'/search/:keyword?',//:params传参的占位;?参数可传可不传
component:Search,
meta:{
show:true,
},
name:'search',//传参方式为对象,用params传参
// props:true, //路由组件传props数据 第一种方法:布尔值写法-只能是params
props:{a:1,b:2}, //路由组件传props数据 第二种方法:对象
},
props:['keyword','a','b'],
<h1>路由组件传参2======{{a}}----{{b}}</h1>
//第三种方法:函数 可以把params和query参数,通过props传递给路由组件
props:($route)=>{//路由组件传props数据 第三种方法:函数 可以把params和query参数,通过props传递给路由组件
return {keyword:$route.params.keyword,joan:$route.query.joan}
},
// 简写
props:($route)=>({keyword:$route.params.keyword,joan:$route.query.joan }),
props:['keyword','joan'],
<h1>路由组件传参2======{{keyword}}----{{joan}}</h1>