1. vue-cli 脚手架
2. vue-router 路由
3. vuex 多组件状态管理
它是vue提供的一个用于构建vue项目的脚手架,目前它的版本已经到了4.x
版本
安装
$ cnpm/npm i @vue/cli @vue/cli-init -g
创建项目
$ vue create 项目名称
$ vue ui
$ vue init webpack 项目名称
$ vue init webpack-simple 项目名称
项目启动
yarn vs npm
vue-cli
版本不同
四中vue-cli不同创建项目形式总结
熟悉脚手架构建的目录【 2以上版本 】
yarn run serve -> node_modules/@vue/cli-service/bin/vue-cli-service.js
调用webpack功能
node_modules/@vue/cli-service 会有临时文件来启动一个界面
src 源代码开发目录【 工作目录 】
vue-cli 使用了 es6 模块化规范
单文件组件
使用vue-cli
stylus
简化了样式需要符号
严格要求缩进
scoped
vue-cli 配置 - vue.config.js
配置文件修改了,必须重启
module.exports = {
devServer:{
open:true,
proxy:{
'/ajax:{
target:'http://m.maoyan.com',
changeOrigin:true
}
}
}
}
const path=require('path')
module.exports = {
chainWebpack: config => {
config.resolve.alias
.set('assets',path.join(__dirname,'./src/assets'))
.set('components',path.join(__dirname,'./src/components'))
.set('@',path.join(__dirname,'./src'))
}
}
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/essential',
'eslint:recommended'
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
},
parserOptions: {
parser: 'babel-eslint'
}
}
webapp 项目
移动端自适应配置
/*
* 配置rem
*/
function font () {
document.documentElement.style.fontSize = document.documentElement.clientWidth / 3.75 + 'px'
}
font() // 表示页面一开启就转换单位
window.onresize = font // 表示页面尺寸发生改变时,再次计算rem
/*
通过js来动态添加rem
*/
(function(designWidth, maxWidth) {
var doc = document,
win = window,
docEl = doc.documentElement,
remStyle = document.createElement("style"),
tid;
function refreshRem() {
var width = docEl.getBoundingClientRect().width;
maxWidth = maxWidth || 540;
width>maxWidth && (width=maxWidth);
var rem = width * 100 / designWidth;
remStyle.innerHTML = 'html{font-size:' + rem + 'px;}';
}
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(remStyle);
} else {
var wrap = doc.createElement("div");
wrap.appendChild(remStyle);
doc.write(wrap.innerHTML);
wrap = null;
}
//要等 wiewport 设置好后才能执行 refreshRem,不然 refreshRem 会执行2次;
refreshRem();
win.addEventListener("resize", function() {
clearTimeout(tid); //防止执行两次
tid = setTimeout(refreshRem, 300);
}, false);
win.addEventListener("pageshow", function(e) {
if (e.persisted) { // 浏览器后退的时候重新计算
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
}, false);
if (doc.readyState === "complete") {
doc.body.style.fontSize = "16px";
} else {
doc.addEventListener("DOMContentLoaded", function() {
doc.body.style.fontSize = "16px";
}, false);
}
})(375, 750);
// 备注: 这里的375本身就应该写成750 ,但是写成750之后,我们设计稿的尺寸要/50,不好算,我就想,除以100更好算,所以我改成了375
(function(doc, win) {
const docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function() {
const clientWidth = docEl.clientWidth;
if (!clientWidth) return;
let max = 24;
let min = 9.3125;
let size = 20 * (clientWidth / 320);
size = Math.min(size, max);
size = Math.max(size, min);
docEl.style.fontSize = size + 'px';
console.log(docEl.style.fontSize, 'em= =====')
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
构建项目目录
数据请求封装 request.js (src/utils/request.js) --在该文件引入import axios from ‘axios’
创建路由配置文件夹 router (src/router)
引入需要的模块(使用前安装 yarn add vue-router)
import Vue from 'vue'
import VueRouter from 'vue-router
import routerTable from './routes.js' //引入路由表
安装插件
Vue.use( VueRouter )
创建路由表
const routerTable=[] --可以将它当作一个模块放入一个routes.js文件中
创建路由模块
const router=new VueRouter({
mode:'history'
routes:routes --此属性名固定为routes
})
export default router
const routerTable=[
{
path:'/',
redirect:'/home' //重定向
},
{
path:'/home',
component:Home, //组件名
meta:{ //元信息
include:Home //include:组件名
}
children:{ //二级路由
{
path:'hot', //不用带斜杠 /
component:HotMovieComp
name:'hot' //给二级路由取别名, <router-link :to="{name:'hot'}"></router-link>使用
}
}
}
]
export default routerTable
新建文件夹 pages/views , 它是路由路径对应的组件
新建文件夹 store 它是状态管理 vuex 的配置文件夹
新建文件夹mock.serveice, 用于数据模拟
创建项目样式全局变量文件
在public/index.html中引入fontawesome cdn
Tab.vue构建
TabBar.vue
1px 线兼容问题 ?
vue路由模式中 hash 和 history
一级路由、子路由、元信息、router-view 、router-link
项目中配置组件库
总结:
动态路由中的路由传参 - 路由接参
<router-link :to="{
name: 'list',
//通过id跳转指定列表
params:{
id:elm.api_cid
},
query:{
a:1
}
}">
<img :src="elm.img" alt="">
<span>{{ elm.name }}</span>
</router-link>
<router-link :to="{
name:'detail',
params:{
id:item.id
},
query:{
...item
}
}">
//同时还要再请求数据
const result=await request({
url:'/index.php',
params:{
r: 'class/cyajaxsub',
page: 1,
cid: this.$route.params.id, //$route传过来的id
px: 't',
}
})
编程式导航
组件身上添加原生事件,要加native修饰符
别名
导航守卫作用
类型
使用
router.beforeEach(( to,from,next ) => {
console.log("jwj: to", to)
console.log("jwj: from", from)
if ( to.path == '/home/hot' ) {
next()
}
const token = getCookie(' _token')
console.log('token',token)
if ( token || to.path == '/login') {//对所有页面进行拦截
next()
} else {
next('/login')
}
async beforeRouteEnter(to,from,next){
//数据预载
console.log(to,from,next)
const res= await request({
url: '/ajax/search',
params: {
kw: '万达',
cityId: 1,
stype: 2
}
})
console.log(res.data.cinemas.list)
next(vm => {
//vm就是当前组件,解决没有this的问题
//因为只有data选项中的数据是数据绑定的,将data中的cinemas对象和请求到的数据进行合并
// Vue.set/this.$set(属性,属性值),原理:Object.assign()
// console.log(vm.cinemas)
vm.$set(vm.cinemas,JSON.stringify(res.data.cinemas.list))
})
<transition
mode = "out-in"
enter-active-class="animated slideInLeft"
leave-active-class="animated slideOutLeft"
>
<router-view></router-view>
</transition>