Vue 课程学习笔记
基础部分
方法创建在 method 的大括号里面
可以将 v-on:click 简写为 @click
new Vue() 的方法创建 vue 实例
两个标签,v-text 会对内容做转义,然后填充;v-html 不会对内容做转义,直接填充。 语法内部都是 js 表达式,可以直接做修改
计算属性
VUE 的属性计算方法特点:只有当这个方法所依赖的属性有了改动时才会重新计算,;否则就使用缓存数据。
VUE 的属性计算方法需要放到 computed 大括号下
计算属性有 get 和 set 方法 ,示例代码如下:
computed:{
fullName:{
get:function(){
return a + b;
},
set:function(value){
var arr = value.split(" ");
this.a = arr[0];
this.b = arr[1];
}
}
}
vue 属性括号总结
- data : 数据
- method :方法
- watch : 监听器
- coumputed : 计算方法
- template : 模版
标签的 class 可以与 布尔符、字符串、数组 等绑定
通过这种方式,可以实现页面样式的动态改变
v-if 和 v-else 的使用
{{msg}}
{{msg}}
通过 show 属性可以让这两个 div 其中一个显示。还可以在中间加 v-else-if 标签,用法参照 Js 的语法。
注意:v-if 和 v-else 两个必须紧贴着使用,不能被阻隔。
通过给相同的标签添加不同的 key 值,可以避免 vue 复用标签
占位符标签
template 标签可以作为占位符,但不会被渲染到页面上
改变数组中某一个元素,并动态更新到页面上的方法
- 方法一:直接重新赋值整个 list 数组
- 方法二:调用数组的变异方法,比如截取,转换等方式
- 方法三:调用 vue 的 set 方法;比如 vueName.$set(vueName.listName,index,value)
Vue 实例的生命周期钩子
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeDestroy
- destroyed
第四部分
如何使用 is 标签解决页面 bug ? 固定标签中使用模版标签时,可能会出现标签不符合 HTML 规范,这时候就可以使用 is 标签
可以通过 ref 获得子组件的引用,从而获取到子组件的内容
父子组件间传值
(父=》子)
- 父组件通过属性的方式向子组件传递数据;
- 子组件不能修改父组件传递过来的数据,但是可以自己申明另外的变量来存储数据,并修改自己的变量。
- 子组件的 data 一定是个函数,而不是实例
(子=》父) - 子组件通过事件触发的方式向父组件传递数据;
- 子组件通过 this.$emit('methodName') 的方式触发父组件的方法
组件中控制传参类型
组件传参可以通过以下方式进行规范,其中规定传参的数据类型的方式有三种,使用其中一种即可。
Vue.component('comName',{
props:{
content:Number , //方式一,规定为数字类型
//content:[String,Number] , //方式二,可以通过数组的方式限制为多个类型
//type:String , //方式三,通过 type 的方式规定传参类型
required:true, //是否必须传参
default:'default value', //设置组件初始化的默认值
validator:function(value){ //自定义组件传参校验器
return (value.length > 5)
}
},
template:'{{content}}'
})
非 props 属性的特点
- 非 props 特性会展示在子组件的最外层的标签的属性中
- 非 props 参数不能被子组件合法使用
给组件加 native 触发原生事件
4-5 非父子组件间传值(Bus/总线/发布订阅模式/观察者模式)
Vue.component.bus = new Vue()
Vue.component('comName',{
props{
content:String
},
data:function(){
return { selfContent:this.content} //因为子组件不能改变父组件参数,所以自己创建一个
},
template:'{{content}}',
method:{
handleClick:function(){
this.bus.$emit('change',this.selfContent)
}
},
mounted:function(){ //生命周期函数
var this_ = this
this.bus.$on('change',function(msg){
this_.selfContent = msg
})
}
})
4-6 在 Vue 中使用插槽(slot)
插槽的意义在于简化往子组间中间插入内容的方式。
通过给子组间的内部标签添加 slot 属性,可以在使用时做区分
添加了 slot 属性的叫做具名插槽,没有的叫做 无名插槽
-
插槽可以设置默认值
some value1111
some value2222
default value 内容
default value
4-7 Vue的作用域插槽
作用域插槽使用场景:列表项中的 dom 结构需要由外部自定义的时候
作用域插槽必须被 template 标签包裹
-
作用域插槽的 slot 属性必须放到 props 里面
{{props.item}}
4-8 动态组件与 v-once 指令
动态组件根据 is 属性 type 的变化,自动加载不同的组件
v-once 指令可以在元素初始化时将实例存储在内存中,可以有效提高静态内容的展示效率
some content
第五部分
5-1 Vue 中的 CSS 动画
通过在元素外面添加 transition 标签,可以添加过渡动画效果
/* 通过 v-if 或者 v-show 控制元素显示和隐藏,通过 transition 监听元素显示和隐藏的动作,然后自动添加动画 */
...
hello
5-2 在 Vue 中使用 Animate.css 库
在 animate.css 官网下载库文件,引入到代码中,就可以使用官网提供的一系列动画效果。
网址如下:Animate 官网
hello
5-3 在 Vue 中同时使用过渡和动画
animated 的默认动画执行时间是 1 秒,而我们自己定义的动画可能不是 1 秒,那么此时以哪个时长为准呢?用以下三种方式定义,任选其一即可。
...
hello
5-4 Vue 中的 Js 动画与 Velocity.js 的结合
Velocity.js 的作用跟 animated 类似,同样是加入动画效果。
网址如下 Velocity 官网
hello
...
/* Vue 实例中的 method*/
methods:{
handleBeforeEnter:function(el){
el.style.opacity = 0;
},
handleEnter:function(el,done){ //此处使用 Velocity
Velocity(
el,
{opacity:1},
{duration:1000,complete:done}
)
},
handleAfterEnter:function(el){
console.log("动画结束")
}
}
5-5 Vue 中多个元素或组件的过渡动画
在 transition 标签中加入多个元素时,可以通过设置 mode="out-in" 属性,可以设置移出和移入过渡效果(即动画的先后顺序)。
多个组件间的动画切换,主要通过 is 属性切换组件名,从而触发切换动画
5-6 Vue 的列表过渡动画
通过 transition-group 标签为列表项添加动画
5-7 Vue 中的动画封装
将整个 transition 写到 template 里面,通过调用组件的方式,直接附带动画效果
hello world
...
Vue.component('fade',{
props:['show'],
template:'
hello
',
methods:{
handleBeforeEnter:function(el){
el.style.color = 'red';
},
handleEnter:function(el,done){
setTimeout( =>{
el.style.color = 'green'
done() //要手动调用 done 函数
},2000)
},
handleAfterEnter:function(el){
console.log("动画结束")
}
}
})
5-8 总结
还有 动态过渡 效果 和 状态过渡 效果,后面可以根据官方文档做具体深入了解。
第六部分
6-1 配置项目
安装 node.js ,直接官网下载安装
码云创建 Travel 仓库
安装 git
-
生成电脑的公钥,教程地址
- 右键 git bash 打开命令窗口
- 输入命令 ssh-keygen -t rsa -C "[email protected]" ,三次回车,直接到相应目录下找到 id_rsa.pub ,打开复制到 git 相应地方
- 然后到项目文件夹中,打开 win 命令行, git clone [email protected]:jinPengStudio/Travel.git
- 若出现 permission denied ,则参考这个网址
安装 vue-cli 框架,执行命令 npm install --global vue-cli
-
切换到项目目录下,执行命令 vue init webpack projectName
- 编译方式 :runtime + Compiler(运行时或编译时); runtime-only(仅运行时)
- 是否安装 vue-router :是
- 是否 用 ESlint 检查 :是
- 是否 unit 单元测试:否
- 是否 E2E 测试:否
- 包管理方式使用 npm 还是 Yarn :npm
- 等待下载,Project initialization finished !
- cd Travel
- npm run dev (若出错,参考如下网址)
6-2 项目中的目录作用介绍
main.js 是整个项目的入口文件
6-3 单文件组件与 Vue 中的路由
路由:根据网址的不同,返回不同的内容给用户
6-4 多页应用 VS 单页应用
多页应用特点
- 每次跳转都要请求,所以首屏时间快
- 搜索引擎优化(SEO)效果好
- 如果网络慢,在页面跳转时会比较慢
单页应用
- 首次跳转请求所有数据,所以首屏时间慢
- 搜索引擎优化(SEO)效果差,搜索引擎不识别 js 中的内容
- 页面跳转不需要请求网络,页面跳转快
6-5 项目代码初始化
-
增加移动端特性,缩放无效,比例为 1
,minimum-scale=1.0 ,maximum-scale=1.0 ,user-scalable=no"
引入 reset.css ,保证各个浏览器效果一样
引入 border.css ,保证移动端边框效果适配
-
引入 fastclick 包,保证移动端点击事件没有延迟,解决移动端 300 毫秒的延时问题,使用如下代码导入:
//1. 命令行到项目目录下,执行 npm install fastclick --save //2. main.js 中导入 import fastClick from 'fastclick' //3. main.js 中声明 fastClick.attach(document.body)
7-1 首页制作
安装 stylus ,方便快捷的书写 css 样式
//1. 安装 stylus
npm install stylus --save
//2. 安装 stylus-loader
npm install stylus-loader --save
用 scoped 关键字让样式只对本页面有效
在 build -> webpack.base.conf.js -> resolve -> alias 下定义自定义路径,方便项目中的资源导入
// 修改前的导入方式
@import '../../../assets/styles/varibles.styl'
//修改后的导入方式
@import '~styles/varibles.styl'
注意: 修改玩 webpack 配置项之后,一定要重启才能生效
安装 swiper 实现轮播图效果
npm install [email protected] --save
git 操作实例
提交 swiper 功能代码,并合并到主分支上
git add *
git commit -m "swiper complete"
git push
git checkout master
git merge index-swiper
git push
查看页面元素对应的数据
安装 chrome 插件 vue.js devtools 用于查看页面元素对应的数据
安装 axios 网络请求框架
进行 ajax 网络数据请求,使用 axios 框架进行:
npm install axios --save
安装 better-scroll 插件,用于城市列表的滚动展示
npm install better-scroll --save
其他
对象也可以使用 v-for 循环
通过监听页面元素的值来控制页面的显示和隐藏
Vuex 实现数据操作
Vuex 的数据操作流程图,可去官网查看
安装 Vuex
npm install vuex --save
- 新建 store.js 声明文件,对 state、action、mutation 作声明,如下代码示例(city 就是数据名):
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
city: '测试'
},
actions: {
changeCityAction (context, city) {
context.commit('changeCityMutation', city)
}
},
mutations: {
changeCityMutation (state, city) {
state.city = city
}
}
})
- 在相应的数据调用处,直接使用 this.$store.state.city 来引用数据
- 如果要修改 state 中存储的数据,使用如下方法
this.store.commit('changeCityMutation', city) //此方法省略了 action 的步骤,直接调用 mutation 也可以
使用路由控制页面跳转(router)
this.$router.push('/')
Vuex 的一些高级用法
用 mapState 简化本地 state 数据的调用
另外,也有 mutation、getter 等用法,具体去官网
使用 iconfont 中的图标库
从购物车中将图标添加至我的项目,然后下载至本地
复制 iconfont.eot 、 iconfont.svg 、 iconfont.ttf 、 iconfont.woff 文件到资源目录下
方式一,替换 iconfont.css 第四行,即替换编码方式,适用于第二次使用 iconfont.css 文件时,比如 url('data:application/x-font-woff2;charset=utf-8;base64
方式二,直接将下载好的 iconfont.css 文件复制到资源目录下,但要修改图标所对应的目录,比如 url('./iconfont/iconfont.woff?t=1561968816383')
其他
用 exclude 标签排除不需要使用缓存的页面
解决浏览器不支持 promis 的协议出现的白屏情况,需要安装 babel-polyfill 插件
npm install babel-polyfill --save
打包整个 vue 项目
npm run build
将打包好的 dist 文件夹里面的东西,复制到服务器根目录下即可。
配置服务器地址表
修改 config -> index.js 文件
proxyTable: {
// 此处是将 '/static/mook' 目录替换成 '/api' 目录,使用代理的方式替换地址
// 到时候在测试服务器和正式服务器转换时,直接调整这里配置项就可以
// 记住修改完配置项,一定要重启后才能生效
'/api': {
target: 'http://localhost:8080',
pathRewrite: {
'^/api': '/static/mook'
}
}
}
通过 IP 访问项目
找到项目根目录下的 package.json 文件,修改 scripts 下的
// 添加 --host 0.0.0.0 这个代码 ,让本项目可以通过 IP 地址来访问
// "dev": "webpack-dev-server --host 0.0.0.0 --inline --progress --config build/webpack.dev.conf.js",
// 原本的代码如下:
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
配置服务器端运行项目的根目录
修改 config -> index.js 文件
assetsPublicPath: '/', //打包的项目将要在服务器端运行的目录路径
打包后生成的文件
.js.map 文件主要是用于调试,不用管
.js 文件主要有三种
- app.js :主要的页面代码,项目的业务逻辑代码
- manifest.js :项目的配置项
- vender.js :各个页面、组件公用的代码
配置异步加载
修改 router -> index.js 文件,将原来在 Home 页面加载所有页面数据的形式,修改为跳转到各个页面时,再各自加载的形式。
使用异步加载的项目至少需要在 MB 级别以上,不然的话,多次的网络请求反而降低了程序性能
// 异步加载测试部分
// 原来的代码,需要一个个导入组件
// routes: [
// {
// path: '/',
// name: 'Home',
// component: Home
// }, {
// path: '/city',
// name: 'City',
// component: City
// }, {
// path: '/detail/:id', // 动态路由
// name: 'Detail',
// component: Detail
// }
// ],
// 改后的代码,不需要在上面导入,直接在组件名称处导入
routes: [
{
path: '/',
name: 'Home',
component: () => import('@/pages/home/Home')
}, {
path: '/city',
name: 'City',
component: () => import('@/pages/city/City')
}, {
path: '/detail/:id', // 动态路由
name: 'Detail',
component: () => import('@/pages/detail/Detail')
}
]