安装NodeJS
可以直接在官方网站中下载安装.
网址: http://nodejs.cn/download/
npm install -g cnpm --registry=https://registry.npm.taobao.org
这样就可以使用 cnpm 命令来安装模块了:
cnpm install [name]
Vue.js官方脚手架工具就使用了webpack模板
对所有的资源会压缩等优化操作
它在开发过程中提供了一套完整的功能,能够使得我们开发过程中变得高效。
npm install webpack -g
安装Vue脚手架
npm install -g @vue/cli
vue init webpack my-project
vue create my-project
Runtime-Compiler:
template -> ast -> render -> vdom -> 真实DOM
Runtime-only:(1.性能更高 2.下面的代码量更少)
render -> vdom -> UI
main.js代码:
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false // 消息提示的环境配置,设置为开发环境或者生产环境
/* eslint-disable no-new */
/*
// runtime-compiler
new Vue({
el: '#app',
components: { App },
template: ' ',
})
*/
// const cpn = { // 组件
// template: '{{message}}',
// data() {
// return {
// message: '我是组件message'
// }
// }
// }
// 也可以用下面这个方案 runtime-only
new Vue({
el: '#app',
render: function (createElement) { // createElement是一个函数
// 1.使用方式一: createElement('标签', {标签的属性}, ['内容'])
// 1.1 基本使用
// return createElement('h2', {
// class: 'box'
// },
// ['Hello World'])
// 1.2 嵌套render函数
// return createElement('h2', {
// class: 'box'
// },
// ['Hello World', createElement('button', ['按钮'])])
// 2.传入组件对象:
// return createElement(cpn)
return createElement(App)
}
})
// runtime-compiler(v1)
// template -> ast -> render -> vdom -> UI
// runtime-only(v2)(1.性能更高 2.下面的代码量更少)
// render -> vdom -> UI
那么.vue文件中的template是由谁处理的了?
是由vue-template-compiler
vue-cli 3 与 2 版本有很大区别
vue-cli 3 是基于 webpack 4 打造,vue-cli 2 还是 webapck 3
vue-cli 3 的设计原则是“0配置”,移除的配置文件根目录下的,build和config等目录
vue-cli 3 提供了 vue ui 命令,提供了可视化配置,更加人性化
移除了static文件夹,新增了public文件夹,并且index.html移动到public中
箭头函数: 也是一种定义函数的方式
定义函数的方式
function
const aaa = function () {
}
// 2.对象字面量中定义函数
const obj = {
bbb() {
}
}
// 3.ES6中的箭头函数
// const ccc = (参数列表) => {
//
// }
const ccc = () => {
}
// 1.参数问题:
// 1.1.放入两个参数
const sum = (num1, num2) => {
return num1 + num2
}
// 1.2.放入一个参数
const power = num => {
return num * num
}
// 2.函数中
// 2.1.函数代码块中有多行代码时
const test = () => {
// 1.打印Hello World
console.log('Hello World');
// 2.打印Hello Vuejs
console.log('Hello Vuejs');
}
// 2.2.函数代码块中只有一行代码
// const mul = (num1, num2) => {
// return num1 + num2
// }
const mul = (num1, num2) => num1 * num2
console.log(mul(20, 30));
// const demo = () => {
// console.log('Hello Demo');
// }
const demo = () => console.log('Hello Demo')
console.log(demo());
当把一个函数作为参数传到另外一个函数
setTimeout(function () {
console.log(this);
}, 1000)
setTimeout(() => {
console.log(this);
}, 1000)
问题: 箭头函数中的this是如何查找的了?
答案: 向外层作用域中, 一层层查找this, 直到有this的定义.
const obj = {
aaa() {
setTimeout(function () {
console.log(this); // window
})
setTimeout(() => {
console.log(this); // obj对象
})
}
}
obj.aaa()
const obj = {
aaa() {
setTimeout(function () {
setTimeout(function () {
console.log(this); // window
})
setTimeout(() => {
console.log(this); // window
})
})
setTimeout(() => {
setTimeout(function () {
console.log(this); // window
})
setTimeout(() => {
console.log(this); // obj
})
})
}
}
obj.aaa()
- 认识路由
- vue-router基本使用
- vue-router嵌套路由
- vue-router参数传递
- vue-router导航守卫
- keep-alive
早期的网站开发整个HTML页面是由服务器来渲染的.
服务器直接生产渲染好对应的HTML页面, 返回给客户端进行展示.
前后端分离阶段:
随着Ajax的出现, 有了前后端分离的开发模式.
后端只提供API来返回数据, 前端通过Ajax获取数据, 并且可以通过JavaScript将数据渲染到页面中.
这样做最大的优点就是前后端责任的清晰, 后端专注于数据上, 前端专注于交互和可视化上.
并且当移动端(iOS/Android)出现后, 后端不需要进行任何处理, 依然使用之前的一套API即可.
目前很多的网站依然采用这种模式开发.
URL的hash
URL的hash也就是锚点(#), 本质上是改变window.location的href属性.
我们可以通过直接赋值location.hash来改变href, 但是页面不发生刷新
history接口是HTML5新增的, 它有五种模式改变URL而不刷新页面.
history.pushState()
因为我们已经学习了webpack, 后续开发中我们主要是通过工程化的方式进行开发的.
我们这里还有一个不太好的实现:
默认情况下, 进入网站的首页, 我们希望
但是我们的实现中, 默认没有显示首页组件, 必须让用户点击才可以.
我们前面说过改变路径的方式有两种:
URL的hash
HTML5的history
默认情况下, 路径的改变使用的URL的hash.
在前面的
有时候, 页面的跳转可能需要执行对应的JavaScript代码,
这个时候, 就可以使用第二种跳转方式了 比如, 我们将代码修改如下:
router里的index.js
// 配置路由相关的信息
// 导入路由对象
import VueRouter from 'vue-router'
import Vue from 'vue'
import Home from '../components/Home'
import About from '../components/About'
// 1.通过Vue.use(插件), 安装插件
Vue.use(VueRouter)
// 2.创建VueRouter对象
const routes = [
{
path: '',
// redirect重定向
redirect: '/home'
},
{
path: '/home',
component: Home
},
{
path: '/about',
component: About
}
]
// 创建路由实例,并且传入路由映射配置
const router = new VueRouter({
// 配置路由和组件之间的应用关系
routes,
mode: 'history',
linkActiveClass: 'active'
})
// 3.将router对象传入到Vue实例
export default router
App.vue
我是APP组件
首页
关于
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
new Vue({
el: '#app',
// 在Vue实例中挂载创建的路由实例
router,
render: h => h(App)
})
在某些情况下,一个页面的path路径可能是不确定的,比如我们进入用户界面时,希望是如下的路径:
/user/aaaa或/user/bbbb
除了有前面的/user之外,后面还跟上了用户的ID
这种path和Component的匹配关系,我们称之为动态路由(也是路由传递数据的一种方式)。
代码:
我是用户界面
我是用户的相关信息, 嘿嘿嘿
计算属性userId:{{userId}}
$route.params.id:{{$route.params.id}}
...
const routes = [
...
{
path:'/user/:id',
component:User
}
]
const router = new VueRouter({
routes,
mode:'history',
linkActiveClass:'active'
})
export default router
我是APP组件
首页
关于
用户
懒加载打包
方式一: 结合Vue的异步组件和Webpack的代码分析.
const Home = resolve => {
require.ensure(['../components/Home.vue'], () => {
resolve(require('../components/Home.vue'))
})
};
const About = resolve => require(['../components/About.vue'], resolve);
const Home = () => import('../components/Home.vue')
定义两个组件:
嵌套路由也可以配置默认的路径, 配置方式如下:
传递参数主要有两种类型:
params和query
$route和$router是有区别的
$router为VueRouter实例,想要导航到不同URL,则使用$router.push方法
$route为当前router跳转对象里面可以获取name、path、query、params等
我是Profile组件
{{$route.query.name}}
{{$route.query.age}}
{{$route.query.height}}
我是APP组件
首页
关于
档案
“导航”表示路由正在发生改变。
正如其名,
vue-router
提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。
// Home.vue
mounted() {
console.log('home mounted');
document.title='首页'
},
// About.vue
mounted() {
console.log('home mounted');
document.title='关于'
},
// ...
// 其他页面也是这样写
我们可以利用beforeEach来完成标题的修改.
首先, 我们可以在钩子当中定义一些标题, 可以利用meta来定义
其次, 利用导航守卫,修改我们的标题.
// ...
const routes = [
{
path: '',
// redirect重定向
redirect: '/home'
},
{
path: '/home',
component: Home,
// meta元数据(描述数据的数据)
meta: {
title: '首页'
},
// 嵌套路由
children: [
// {
// path: '',
// redirect: 'news'
// },
{
path: 'news',// 没有斜杠 /
component: HomeNews
},
{
path: 'message',
component: HomeMessage
}
]
},
{
path: '/about',
component: About,
meta: {
title: '关于'
},
},
{
path: '/user/:id',
component: User,
meta: {
title: '用户'
},
},
{
path: '/profile',
component: Profile,
meta: {
title: '档案'
},
}
]
const router = new VueRouter({
// ...
})
// 1. 全局导航守卫
// 1.1 前置守卫(guard) 路由跳转之前
// beforeEach()注册一个全局前置守卫,本身是一个函数,又传入一个函数guard,有三个参数
router.beforeEach((to, from, next) => {
// 从from跳转到to
// // to 和 from都是route对象
// document.title = to.meta.title
// 上面这样写的话如果有嵌套路由的话是undefined,要使用matched(匹配)获取
document.title = to.matched[0].meta.title
console.log(to);// 到哪个页面去?
console.log(from);// 从哪个页面来?
// 调用该方法后,才能进入下一个钩子
// 如果是后置钩子,也就是afterEach,不需要主动调用next()函数
// 这里其实可以判断用户登陆权限之类的,拦截访问 ,权限不符调用next(false)拦截
next()
})
// 1.2 后置钩子(hook) 不需要主动调用next()函数
router.afterEach((to, from) => {
console.log('----');
})
// 钩子->回调
export default router
const routes = [
// ...
{
path: '/about',
component: About,
meta: {
title: '关于'
},
// 2.路由独享的守卫
beforeEnter: (to, from, next) => {
console.log('about beforeEnter');
next()
}
},
// ...
]
const router = new VueRouter({
//...
})
// Home.vue
我是首页
我是首页内容, 哈哈哈
新闻
消息
{{message}}
App.vue
首页
关于
Home.vue
我是首页
我是首页内容, 哈哈哈
新闻
消息
{{ message }}
Profile.vue
User.vue
分析:
(1)基本结构的搭建(无封装组件)
body{
margin: 0;
padding: 0;
}
(2) TabBar和TabBarItem组件封装
复习知识点:(十一)插槽
首页
分类
购物车
我的
(3)给TabBarItem传入active图片
首页
分类
购物车
我的