很敬佩黄轶老师,涵盖了非常多的知识点。跟着敲还是需要一些vue基础的。
扫码访问
我把它部署到了自己的服务器 ╮(╯▽╰)╭由于没有备案 直接用的服务器ip
请查看另一篇文章 ✌点击传送门
<meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0, user-scalable=no">
属性 | 值 |
---|---|
width | 设置layout viewport 的宽度,为一个正整数,或字符串"width-device"设备宽度 |
initial-scale | 设置页面的初始缩放值,为一个数字,可以带小数 |
minimum-scale | 允许用户的最小缩放值,为一个数字,可以带小数 |
maximum-scale | 允许用户的最大缩放值,为一个数字,可以带小数 |
height | 设置layout viewport 的高度,这个属性并不重要,很少使用 |
user-scalable | 是否允许用户进行缩放,值为"no"或"yes", no 代表不允许,yes代表允许 |
根据上面这个表格不难看出:width为设备宽度,初始缩放为1,最大及最小缩放都为1,不允许缩放
babel默认只换新的javascript语法,不转换新的api,所以要安装babel-polyfill,但是会污染全局变量
为了不污染全局变量和内置对象原型,又想使用ES6新语法和api就需要配合使用babel-runtime,可以避免重复代码
cnpm i babel-runtime --save
cnpm i babel-polyfill --save-dev
然后需要在入口文件main.js中
imprort 'bable-polyfill'
cnpm i fastclick --save
fastclick的实现原理是在检测到touchend事件的时候,会通过DOM自定义事件立即出发模拟一个click事件,并把浏览器在300ms之后的click事件阻止掉。
然后在入口文件引入
import fastclick from 'fatclick'
fastclick.attach(document.body)
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'@': resolve('src'),
'common': resolve('src/common')
}
}
这样页面import某个在src/common下的对象时可以直接写 import music from 'common/music'
// 在router文件夹内的index.js
import Vue from 'vue'
import Router from 'vue-router'
// 以上是脚手架搭建项目已经写好的
// 假如现在有三个页面 先导入
import Test1 from 'src/components/test1'
import Test2 from 'src/components/test2'
import Test3 from 'src/components/test3'
Vue.use(Router)
export default new Router({
routes:[
{
path: '/',
redirect: '/test1'
// 重定向path'/test1'
},
{
path: '/test1',
component: Test1
},
{
path: '/test2',
component: Test2
},
{
path: '/test3',
component: Test3
}
]
})
完成了基本的路由配置 App.vue里的router-view就会渲染对应path的component
最好是使用路由按需加载,请查看另一篇文章
✌ 点击传送
<router-link tag="div" class="tab-item" to="/test1">
<span class="tab-link">测试</span>
</router-link>
// tag是渲染的标签 to对应点击以后的path
// router会默认有一个class router-link-active 可以覆盖自定义样式
引入使用首字母大写加驼峰
使用小写 - 连接
// 父组件 test2中引入test1
improt TestOne from 'components/test1'
// template中使用时
<test-one></test-one>
// 尽量语义化 我这里随意写的就没有语义化...
原理请查看另一篇文章✌点击传送
项目中引入了jsonp插件
cnpm i jsonp --save
因多处会使用到jsonp对它进行一层封装
import originJSONP from 'jsonp'
export default function jsonp(url, data, option) {
// url与处理后的data拼接
url += (url.indexOf('?') < 0 ? '?' : '&') + param(data)
// 返回一个promise
return new Promise((resolve, reject) => {
originJSONP(url, option, (err, data) => {
// 插件默认返回第一个参数为null第二个参数为数据 所以会接收两个参数
if (!err) {
resolve(data)
} else {
reject(err)
}
})
})
}
// 对data数据进行处理
function param(data) {
let url = ""
for (var k in data) {
let value = data[k] !== undefined ? data[k] : ''
url += `&${k}=${encodeURIComponent(value)}`
}
return url ? url.substring(1) : ''
}
因为使用promise封装了 所以调用时要用到.then
import jsonp from 'common/js/jsonp'
jsonp(url, data, option).then((res) => {console.log(res)})
那么问题来了 ↓
A通过jsonp请求获取,B拿到A返回的数据作为参数通过jsonp请求获取,C拿到B返回的数据作为参数通过jsonp请求获取
我们的做法一般都是,执行jsonp({Aparams})并在A回调里拿到B需要的参数并且执行jsonp({Bparams})然后在B的回调里拿到C需要的参数并且执行jsonp({Cparams})
一两层回调的嵌套其实也觉得还好,但如果业务逻辑复杂需要嵌套100层呢
?这样就非常不便于阅读和维护,也就是常听到的“回调地狱”
还是上面那个应用场景,我们用以上封装的jsonp怎么使用呢
jsonp({Aparams}).then(jsonp({Bparams})).then({jsonp(Cparams)})即可
当第一个jsonp执行后返回一个promise对象,promise对象状态发生改变就会触发then并且可以拿到A的resolve传递出去的数据,再执行第二个jsonp返回一个promise对象,让promise对象状态发生变化时触发then可以拿到B的resolve传递出去的数据再执行第三个jsonp,依次类推,非常清晰。
当然业务上其实有reject的情况,这时会执行.catch( // 进行错误处理)
那么问题来了,什么是promise状态发生改变时
- pending(进行中);
- fulfilled(已成功);
- rejected(已失败)。
- 当执行resolve时,promise对象的状态会从pending 变为 fulfilled;
- 当执行reject时,promise对象的状态会从pending 变为 rejected;
当然ajax也可以结合promise封装,axios已经结合了promise可以直接使用
由于项目很多地方都需要滑动,所以我们对better-scroll进行封装
详见本站另一篇文章✌ 点击传送
非常好用的一个优化插件 官方文档✌ 点击传送
1.npm 安装
cnpm install vue-lazyload --save
2.main.js中use
import VueLazyLoad from 'vue-lazyload'
Vue.use(VueLazyLoad, {
// loading图片
loading: require('本地图片路径')
})
// 页面中使用 只需要用v-lazy指令替换src就可以了
// scr="imgUrl" => v-lazy="imgUrl"
更多属性请看官方文档,超超超好用
vuex帮助我们管理共享状态,多个没有什么关联性的组件想要共享状态可以通过vuex
详见另一篇文章 ✌ vuex的学习及使用
- ES5中生成实例对象的方法--构造函数
function Holly(x, y) {
this.x = x
this.y = y
}
Holly.protitype.connect = function() {
return (this.x + ',' + this.y )
}
var hollyTree = new Holly('www.hollytree', '.top')
- ES6 中引入class这个概念,针对上面改写
// 定义一个Holly的类
class Holly {
constructor(x, y) {
this.x = x
this.y = y
}
// 方法直接定义 不需要function关键字 也不需要逗号
connect() {
return (this.x + ',' + this.y )
}
}
var hollyTree = new Holly('www.hollytree', '.top')
Holly类里有一个cunstructor方法,这就是构造方法this指向实例。
也就是说ES5中的构造函数Holly对应ES6中Holly类的构造方法
- ES6的类可以看做构造函数的另一种写法,typeof 类 返回 ‘function’,数据类型为函数,类本身指向构造函数;
- 类所有的方法都定义在类的prototype(原型)上;
- 原型对象的constructor属性直接指向类本身与ES5一致
// song.js
// 定义一个Song类,类的构造函数接收一些参数并指向实例
export default class Song {
constructor({ id, mid, singer, name, album, duration, image, url }) {
this.id = id
this.mid = mid
this.singer = singer
this.name = name
this.album = album
this.duration = duration
this.image = image
this.url = url
}
// 类的方法 实例可以直接调用
getLyric() {
if (this.lyric) {
return Promise.resolve(this.lyric)
}
}
}
let songData = new Song({id: 22, mid:666, singer: 'holly'...})
console.log(songData) // {id: 22, mid: 666, singer: 'holly'...}
简单应用
<audio ref="audio" :src="currentSong.url" @canplay="ready" @error="error" @timeupdate="updateTime"> </audio>
- play()方法 开始播放
- canplay事件:当浏览器可以开始播放音频/视频时触发。
- paly事件: 当音乐开始播放时触发(播放暂停有时因为业务逻辑可能需要将canplay换成play事件,控制切换以及ready触发时保证已经play())
- error事件:当在音频/视频加载期间发生错误时触发。
- timeupdate事件:在音频/视频(audio/video)的播放位置发生改变时触发。
以下代码实现功能:
- 当歌曲发生改变的时候播放也就是调用play()
- 在播放器切换歌曲时可以控制,当前歌曲已经ready时才能切换到下一首
- 实时获取播放时间
data() {
return {
// 标识
songReady: false
}
},
methods: {
// 只有该歌曲已经ready时,赋值为true
ready() {
this.songReady = true
},
// 然后在切换的方法里 例如next() 加一个判断就可以了
next() {
if(!this.songReady) {
return
}
// 就不执行下面的了
...
// 最后在重置为false
this.songReady = false
},
// 当资源加载失败时不影响切换操作
error() {
this.songReady = true
}
},
watch: {
// 当前歌曲变化时并且已经ready 开始播放
currentSong() {
if(!this.songReady) {
return
}
this.$refs.audio.play()
this.songReady = true
}
}
混入 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。
详见另一篇文章✌ 点击传送 Mixins的使用
- vue中一般是v-model绑定input值然后监听,一旦发生改变就发送请求;
- 例如我想搜索周杰伦,输入周时请求一次,杰时请求一次,伦时请求一次;或者删除伦时请求一次....
- 频繁的发送请求,页面有可能造成卡顿,也增大了服务器的压力;
- 这个时候需要进行节流优化。
项目中用到了.stop .prevent
- .stop
阻止事件冒泡
- .prevent
取消浏览器默认行为(例如a标签的默认刷新页面)
- .capture
使用事件捕获模式
- .self
只作用于元素本身,类似于已阻止事件冒泡
- .once
只作用一次
修饰符可以串联 例如需要阻止冒泡并且只触发一次 .stop.once
npm run build
打包以后的文件如下:
包含static静态资源文件夹 与 html 文件
由于是单页应用程序,进入首页时会加载所有的静态文件。项目比较大时会白屏很久。
这时推荐路由懒加载的模式进行优化,这样打包后会分模块,进入不同路由后加载对应静态资源
详见: 路由懒加载✌
一个由微信团队开发开源的插件 使用方法 点击传送✌