1.vue特点
- 采用组件模式
- 申明式编码【使用 v-for 等指令,避免了对DOM的直接操作】
- 使用虚拟 DOM + 优秀的 Diff 算法,尽量复用DOM节点【Diff比较算法】
2.MVVM模型
【所以经常将vue返回值命名为vm】
3.数据代理
Object.defineProperty()
4.使用
vue 容器和 dom 对象只能是一对一接管
4.1 vue语法
- el 对象接管和 data 的两种写法
【注】":function可以不写"
4.2 内置指令
- 插值语法: {{}}
内部写的是 js 表达式,常用于标签体的内容
- 指令语法: v-xxx
字符串就会被默认为 js 表达式执行【即:到相应的vue实例中去寻找】
- "v-bind:" 能给标签里的任何一个属性动态绑定值 能简写为 “:”,常用于标签的属性值。【单向数据绑定】
<div id="root">
<h1>{{name}}</h1>
<a v-bind:href="url">点击跳转百度</a>
<input :value="name.toUpperCase()"/>
</div>
<script type="text/javascript">
new Vue({
el:"#root", //绑定对象
data:{//属性
name:"tomcat",
url:"http://www.baidu.com"
},
methods:{
//方法
},
conputed:{
//计算属性
},
watch:{
//监视
},
filters:{
//过滤器
},
directives:{
//自定义指令
},
//生命周期函数
})
</script>
- "v-model:" 只能运用于表单类元素(输入类元素 即:有 value 值)上面【双向数据绑定,默认收集的就是 value 值,对于单选和复选框 通过指定 value 值】
-
v-on:事件名
-
v-on:click点击的时候【简写为 @click】
-
v-show=“true/false”【底层使用了display属性,适用于变化频率快,节点值还有用】
-
v-if=“true/false”【删除很彻底,F12直接没有DOM元素,适用于变化频率低】
template只能配合v-if使用【template标签只是包裹作用,在浏览器中编译为HTML时会自动去掉】
- v-for="person in persons"
配合key一起使用【:key=“person.id”】
可以遍历数组,字符串,对象,数字等
<div id="root">
<h1 v-for="person in persons" :key="person.id">
{{person.name}}-{{person.age}}
</h1>
<!-- 第二种写法 -->
<h1 v-for="(person, index) in persons" :key="index">
{{person.name}}-{{person.age}}-{{index}}
</h1>
</div>
key是虚拟DOM中的唯一标识
使用 index 作为 key,如果打乱了原有 list 的顺序,会导致位置错乱【虚拟DOM的对比算法问题】
如果不写 key,在 v-for 时 vue 会自动使用 index 作为 key
- v-text【等同于插值语法{{}} 一般使用插值语法】
- v-html【相比于v-text能解析标签,但是纯在安全问题,可能导致xss攻击】
- v-cloak【处理js延迟/阻塞问题,vue还没接管时存在,接管后就删除该指令,可以在style里进行属性设置为none】
- v-once【初次动态渲染后就视为静态内容,即:不会再因为其改变而从新执行get方法】
- v-pre 【Vue不去解析,提高效率,用于没有插值语法和指令语法的标签】
4.3 自定义指令【directives】
v-big指令
-
函数式【只用到了 bind 和 update 两个方法】
-
完整类型
【自定义指令注意事项】
1. 多个单词命名时使用"-"隔开 因为不区分大小写,还需要用传统的''(单引号将方法名包裹起来) |
2. 指令函数中的 this 都是 window |
---|
3. 内部指令【全局指令可以参考全局过滤器】 |
---|
4.2 列表渲染
4.2.1 数组过滤
计算属性用到的任何属性发生变化,计算属性都会重新计算
4.3 nextTick钩子【对更新后的 dom 元素进行操作】
5.数据监视
- Vue 响应式监测添加属性通过 vue.set()方法 或者 vm.$set()方法【vm为vue的实例对象,这两个方法不能给 vm 和 vm 的根数据对象上】
- Vue 检测数组时只对数组操作的7中基本方法是响应式的,因为vue对其方法进行了封装
【注】修改不奏效时记得去查看是不是没有为其服务的 get 和 set
总结
6.过滤器
过滤器可以串联【一般定义全局过滤器,过滤器时产生新的 item 进行展示,没有改变原来的】
- filters 内部过滤器【和 methods 写法相同】
- Vue.filter 全局过滤器 在Vue实例化之前创建【即:new 之前】
7.Vue 生命周期
【注意】
mounted:页面一加载完毕就干嘛…
beforeDestroy:关闭定时器等…【避免"他杀"导致其不知道,计数器等继续计数等浪费资源】
8.组件编程
Vue.extend
- 非单文件组件
一个文件中包含有 n 个组件
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<hello></hello> <hr> <school></school> <hr> <student></student></div>
</body>
<script type="text/javascript">
//创建学校组件【组件包含html、css、js】
const school = Vue.extend({
template:`
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
</div> `,
//组件不能绑定所以不能使用el
//组件的data不需使用函数式返回【避免引用导致值不一致】
data(){
return {
schoolName:"黄埔军校",
address:"上海"
}
}
})
//创建学生组件
const student = Vue.extend({
template:`
<div>
<h2>学生姓名:{{studentName}}</h2>
<h2>学生年龄:{{age}}</h2>
</div> `,
//组件不能绑定所以不能使用el
//组件的data不需使用函数式返回【避免引用导致值不一致】
data(){
return {
studentName:"pawn",
age:22
}
}
})
//创建hello组件
const hello = Vue.extend({
template:`
<div>
<h2>hello:{{name}}</h2>
</div> `,
//组件不能绑定所以不能使用el
//组件的data必须使用函数式返回【避免引用导致值不一致】
data(){
return {
name:"tom"
}
}
})
//全局注册hello组件 参数分析(组件名称(即以后使用hello组件是所用的标签名),组件位置)
Vue.component("hello",hello)
//注册组件
const vm = new Vue({
el:"#root",
components:{
//完整写法
school:school,
//名字一样的简化写法
student
}
})
</script>
</html>
写组件标签时才会执行 new VueComponent
VC 和 VM 不同【el data写法 函数式】
- 单文件组件
一个文件中只包含 1 个组件
-
完整版本
-
开发常用版本
1. ref属性
2. props属性
不允许修改,如果想修改可以在data中同步但是不能同名——>props属性比data属性先被vue解析
3. mixins属性
【注】 data数据和methods优先级都是vc中的大于mixin中的,即:mixin中的会被覆盖。但是挂载属性是不会被覆盖的 即:如果都有挂载属性 则会都被执行一次
4. 插件
插件可以给Vue进行增强,insatll第一个参数是Vue 后面可以自己添加参数
- 写插件
- main 中引入插件
- main 中 use 插件
- 其他的地方可以使用了
plugins.js
5. scoped属性
9.流程分析
- 抽取组件【组件划分】
兄弟组件之间传送消息
方法一【通过父组件进行传递 props属性】
子组件想给父组件传数据只用父组件给子组件传一个方法即可【子组件将数据放入方法中】
父子间的通信方式
方式一【父组件直接把方法传给子组件 props属性】
方式二【自定义组件事件】
app
方式二更加灵活,能自定 timer
Student
10.全局事件总线【任意组件间的通信】
-
原理写法
-
标准写法
【注】
- 在想要回调(即:收数据)的 vc 的 mounted 函数中给 bus 绑定事件,并对数据进行处理
- 记得在 beforeDestroy 函数中进行解绑
11.消息订阅与发布【vue一般不用】
Vue全局总线是在 main.js 中安装全局总线
消息订阅事在订阅者和发布者 vc 中 import pubsub-js
【注】也需要取消订阅
12.动画|过度
transition 标签
-
第一种
-
第二种
插件 Animate.css
13.Vue 脚手架中的 ajax 请求
13.1 Vue 脚手架开启代理服务器
vue.config.js
【注】两种请求地址的差异,加上前缀,必走远端服务器
14.插槽【给组件的内容体中放置内容】
14.1 默认插槽
Categoty.vue
app.vue
14.2 具名插槽【具有名字的插槽】
Categoty.vue
app.vue
【注】上面两种插槽数据都在父组件
14.3 作用域插槽【组件使用者在复用组件时决定其展示的样式,且父组件可以不需要知道子组件的数据】
Categoty.vue
app.vue
15.vuex【多组件依赖同一状态】
15.1 vuex 的普通写法
存放多组件共享的数据(便于他们修改,查看)
原理图
环境配置
//该文件用于创建Vuex中最核心的store
//引入Vue
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//使用Store
Vue.use(Vuex)
//用于响应组件中的动作
const actions = {}
//用于操作数据
const mutations = {}
//用于存储数据
const state = {}
//创建并暴露Vuex的Store对象
export default new Vuex.Store({
actions,
mutations,
state
})
【注】必须在这里引入 Vuex 并使用,因为使用了之后才能对 Vuex 的 Store 进行实例化
为了简化代码【 $store.state.key 和 this.$store.dispatch等】
具体写法
- mapState
mapGetters mapActions mapMutations 也同理
【注意】:他们的不同点
- 位置: mapState mapGetters 写在计算属性中,mapActions mapMutations 写在 methods 中
- 是否需要传参 方法一般需要参数 在哪里传参
非简化写法
简化写法
15.2 vuex 的模块化
16.路由
address => 组件 路由组件不需要使用组件标签 直接由 router 渲到页面
16.1 一级路由
- 引入路由
main.js
router/index.js
//引入Vue
import Vue from 'vue'
//该文件用于创建整个应用的 vueRouter
import VueRouter from 'vue-router'
//使用VueRouter
Vue.use(VueRouter)
//引入需要路由展示的组件
import About from '../components/About'
import Home from '../components/Home'
//创建并暴露一个路由器
export default new VueRouter({
routes:[
{
path:"/about",
component:About
},
{
path:"/home",
component:Home
}
]
})
App.vue
【注意】:没有被渲染的路由组件是被销毁了
16.2 嵌套路由【多级路由】
router/index.js
16.3 query 传参
不用修改路由设置
**【注意】:path 和 name 的区别,还有这里必须是单引号 **
16.4 pamars 传参
1. 在路由配置中需要声明接受 即:占位
2. 对象写法 必须使用name 不能使用path 因为pamars的path="address/key1/value1/key2/value2"
16.5 路由中的 props 接收参数
16.6 使用其他标签[比如按钮]进行路由
拿到路由器对象
- this.$router.push
- this.$router.replace
## 16.7 路由缓存
即:切走组件不进行销毁 keep-alive
多个组件需要缓存时 使用数组【注意使用 “:”】
16.8 activated deactivated 生命周期钩子
搭配缓存使用,既保证组件在不出现时被缓存,又保证其在后台时不运行
16.9 路由守卫
16.9.1 全局前置路由守卫【类似于过滤器】
- 给需要权限监测的路由地址配置 meta 信息
meta 中可以以键值对的形式任意配置
16.9.2 全局后置路由守卫
16.9.3 独享路由守卫【只有前置 没有后置】
16.9.4 组件内路由守卫
不是在路由器中配置 而是在组件内配置