节点
- document
- element
- attribute
- text
MVVM
-
modeL:模型,数据对象(data)
-
view:视图,模板页面
-
viewModel:视图模型(vue的实例)
指令
----绑定数据
双括号{{}}
<p>{{msg}}</p>
----双向绑定
<input type="text" v-model="username">
<p>Hello {{username}}</p>
----不解析html
v-text
<p v-text='msg'></p>
----解析html
v-html
<p v-html='msg'></p>
----强制绑定
v-bind 或【:】
<img v-bind:src='imgUrl'></img>
<img :src='imgUrl'></img>
----v-on:事件类型
@事件类型 :绑定事件监听
<button v-on:click='test'>test-clic</button>
<button @click='test2(msg)'></button>
vue实例内相关属性
【el】 绑定容器元素
【data】 数据绑定
【method】 方法
【computed】计算属性
【watch】监视
【生命周期函数】
生命周期
生命周期函数一般执行1次。
-
beforeCreate() 创建前
-
created () 创建后
-
beforeMount() 挂载前
-
mounted() 挂载后
-
beforeUpdate() 更新前,执行0-n次
-
**updated() ** 更新前,执行0-n次
-
beforeDestroy() 销毁前
-
destroyed() 销毁后
常用
- mounted() 发送ajax请求,启动定时器等异步任务
- beforeDestroy() 收尾工作,如:清除定时器
自定义指令
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>class与style绑定</title>
</head>
<body>
<div id="demo">
<p v-upper-text="msg1"></p>
<p v-lower-text="msg1"></p>
</div>
<div id="demo1">
<p v-upper-text="msg2"></p>
<p v-lower-text="msg2"></p>
</div>
<script src="./vue.js"></script>
<script>
// 定义全局指令
Vue.directive("upper-text",function(el,binding){
console.log(el,binding);
el.textContent = binding.value.toUpperCase();
})
const vm = new Vue({
el:"#demo",
data:{
msg1:"NBA I Love This Game!"
},
methods:{
},
computed:{// 计算属性
},
watch:{ // 监视
},
directives: { // 注册局部指令 在当前vm管理范围有效
'lower-text'(el,binding){
console.log(el,binding);
el.textContent = binding.value.toLowerCase();
}
},
})
const vm2 = new Vue({
el:"#demo1",
data:{
msg2:"Just Do It!"
},
})
</script>
</body>
</html>
插件
- 定义插件
/**
* vue定义插件 .js文件
*/
(function(){
// 向外暴露插件对象
const MyPlugin = {}
MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或 property
Vue.myGlobalMethod = function () {
console.log("vue函数对象的方法myGlobalMethod()")
}
// 2. 添加全局资源
Vue.directive('my-directive', function(el,binding){
el.textContent = binding.value.toUpperCase();
})
// 4. 添加实例方法
Vue.prototype.$myMethod = function (methodOptions) {
console.log('vue实例对象的方法$myMethod()')
}
}
// 向外暴露
window.MyPlugin = MyPlugin;
})()
- 使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>class与style绑定</title>
</head>
<body>
<div id="demo">
<p v-my-directive="msg"></p>
</div>
<script src="../vue.js"></script>
<script src="./vue-myPlugin.js"></script> <!-- 引入插件 -->
<script>
//声明使用插件
Vue.use(MyPlugin) // 内部会执行MyPlugin.install(Vue)
// 使用插件
Vue.myGlobalMethod()
const vm = new Vue({
el:"#demo",
data:{
msg:"I Liek You ~ "
},
})
// 使用插件方法
vm.$myMethod()
</script>
</body>
</html>
vue------------------------------------
组件标签
- 可以使用-加小写形式
如标签:<UsersMain/> 可写成 <users-main/>
浏览器缓存
- 获取数据:window.localStorage.setItem(“key”)
- 获取数据:window.localStorage.getItem(“key”)
组件通信:
绑定属性
- 传递属性 :xxx = “xxx”
- 子组件props接收属性 可声明接收类型(Number、Function等)
- 调用属性
绑定事件
-
给子标签绑定事件函数 @xxx = “xxx”
-
子组件触发事件
this.$emit(函数,数据);
ref
-
ref=“xxx” 给子组件取名
-
父组件绑定事件函数
mounted(){//执行异步代码 //给<TodoHeader/>绑定addTodo事件监听 //this.$on('addTodo',this.addTodo)//直接用this的话是给当前组件(App)绑定的监听,不对 this.$refs.xxx.$on('addTodo', this.addTodo) // 通过refs获取需绑定的组件 },
-
子组件触发事件
消息订阅与发布
好处:两个组件通信,无位置限制(父子、子孙等),不用一层层传递。
安装pubsub:npm install --save pubsub-js
引入:import PubSub from ‘pubsub-js’
-
订阅消息:subscribe
-
发布消息:publish
订阅消息
类似绑定事件监听,调用事件处理
PubSub.subscribe('消息名',回调函数(msg,data));
发布消息
类似提示触发事件
PubSub.publis('消息名',传递的数据)
Slot
slot=插槽
把标签传递过去,属性也会一起传递
// 子组件:定义插槽
<slot name="checkA11"></slot>
// 父组件:传递标签 通过属性slot="xxx"绑定标签到子组件那个插槽中 如:
<input type="checkbox" v-model="isAllCheck" slot="checkAll"/>
vue项目两个ajax库
vue-resource
vue插件,vue1.x广泛使用
安装:npm install vue-resource --save
使用
import VueResource from 'vue-resource'
// 声明使用插件
Vue.use(VueResource) // 内部会给vm对象和组件对象添加一个属性: $http
// 发ajax请求获取数据
const url = 'https://api.github.com/search/repositories?q=vu&sort=stars'
this.$http.get(url).then(
response => {
// 成功了
const result = response.data;
// 得到最受欢迎的repo
const mostRepo = result.items[0];
this.repoUrl = mostRepo.html_url;
this.repoName = mostRepo.name;
},
error => {
alert('请求失败');
}
)
axios
通用请求库 推荐 vue2.x广泛使用
安装: npm install axios --save
使用:
// 引入
import axios from 'axios'
// 使用axios发送ajax请求
const url = 'https://api.github.com/search/repositories?q=vu&sort=stars'
axios.get(url).then(
response => {
// 成功了
}
).catch(
error => {
alert('请求失败');
}
)
ui组件库
Mint Ul:
- 主页: http://mint-ui.github.io/#!/zh-cn
- 说明:饿了么开源的基于vue 的移动端uI组件库
安装:npm install --save mint-ui
修改 babel 配置:
"plugins": [
"transform-runtime",
[
"component",
[
{
"libraryName": "mint-ui",
"style": true
}
]
]
]
使用
// 注册成标签(全局注册)
import {Button} from 'mint-ui'
Vue.component(Button.name, Button) // Button.name 即标签使用默认原标签名称
// 使用
<template>
<mt-button @click="handleClick" type="primary" style="width: 100%">Test</mt-button>
</template>
<script>
import {Toast} from 'mint-ui'
export default {
methods: {
handleClick () {
Toast('点击了测试');
}
}
}
</script>
Elment
主页: http://element-cn.eleme.io/#/zh-CN
说明:饿了么开源的基于vue的PC端u组件库
安装:npm install element-ui --save
使用
// main.js引入
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
// .vue里使用
<el-button type="primary">主要按钮</el-button>
路由
安装: npm install vue-router --save
- 编写路由模块
/*
路由器模块 ./src/router/index.js
*/
import Vue from 'vue'
import VueRouter from 'vue-router'
import About from '../views/About.vue'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
export default new VueRouter({
// n个路由
routes: [
{
path: '/about',
component: About
},
{
path: '/home',
component: Home
},
{
path: '/',
redirect: '/about'
}
]
})
- 引入路由
// ./src/main.js
import router from './router' // 路由器
new Vue({ // 配置对象的属性名都是一些确定的名称,不能随便修改
router:router
})
- 使用
// .vue
<!--生成路由链接-->
<router-link to="/about" class="list-group-item">About</router-link>
<router-link to="/home" class="list-group-item">Home</router-link>
<!--显示当前组件-->
<router-view></router-view>
跳转:
// 字符串
this.$router.push('/home/first')
// 对象
this.$router.push({ path: '/home/first' })
// 命名的路由
this.$router.push({ name: 'home', params: { userId: wise }})
嵌套路由
// 配置路由文件 ./src/router/index.js
routes:[
path: '/home',
component: home,
children: [
{
// path: '/home/news' 或者简化写法
path: 'news',
component: News
},
{
path: 'message',
component: Message
},
{
path: ''
redirect: '/home/news' // 默认使用
}
]
]
// .vue 使用
<router-link to="/home/news">News</router-link>
<router-link to="/home/message">Message</router-link>
<router-view></route-view>
缓存路由组件
<keep-alive>
<router-view></router-view>
</keep-alive>
路由传参
路径携带
- 配置路由
path: 'mdetail/:id', // :xx来占位
component: MessageDetail
- 路由路径传递参数
<router-link :to="`/home/message/mdetail/${m.id}`">{{m.title}}</router-link>
- 路由组件读取参数
// $route 代表当前路由
this.$route.params.id
属性携带数据
<router-view :msg="msg"></router-view>
- 路由组件接收
props: {
msg: String
}
编程式路由
路由使用栈来管理。
使用:$router.xxx(’’);
- push() 点击路由链接(可回退当前路由)
- replace() 新路由替换当前路由(不可返回当前路由界面)
- back() 返回上一记录的路由
- go() 前进上一记录的 路由 go(-1) =返回上一记录的路由
js
Object
Object.defineProperty(obj,‘属性名’,{…}); 定义属性
{…}内相关:
- configurable:是否可以重新定义
- enumerable:是否可以枚举
- value:初始值
- writable:是否可以修改属性值
- get:回调函数,根据其它相关的属性动态计算得到当前属性值
- set:回调函数,监视当前属性值的变化,更新其它相关的属性值
Object.keys(obj); 获取对象所有属性。
obj.hasOwnProperty(‘属性’); 判断对象自身是否有该属性。
DocumentFragment
文档碎片,高效批量更新多个节点
Document:对应显示的页面,包含n个element 一旦更新document内部某个元素,界面更新
DocumentFragment:内存中保存n个element容器对象(不与界面关联),更新fragment中某个element,界面
使用:
// html
<ul id="fragment_test">
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ul>
// js使用documentFragment
const ul = document.getElementById('fragment_test')// 获取ul元素
// 1创建 fragment
const fragment = document.createDocumentFragment()
// 2取出xx节点中所有子节点保存到fragment
let child;
while(child = ul.firstchi1d){ // 一个节点只能有一个父亲
fragment.appendchild(child); // 1-从ul移除,2-添加为fragment子节点
}
// 3更新fragment中子节点
//Array.prototype.slice.call(xx) 将伪数组xx调用数组中slice方法。
Array.prototype.slice.call(fragment.childNodes).forEach(node => {
if(node.nodeType === 1){ // 元素节点
node.textContent = "xiaoai";
}
})
// 4将fragment插入xx节点
ul.appendChild(fragment);
补充1
-
slice() 方法可从已有的数组中返回选定的元素。
-
slice()方法可提取字符串的某个部分,并以新的字符串返回被提取的部分。
slice() 方法不会改变原始数组。
补充2
node.nodeType
存在 12 种不同的节点类型,其中可能会有不同节点类型的子节点:
节点类型 | 描述 | 子节点 | |
---|---|---|---|
1 | Element | 代表元素 | Element, Text, Comment, ProcessingInstruction, CDATASection, EntityReference |
2 | Attr | 代表属性 | Text, EntityReference |
3 | Text | 代表元素或属性中的文本内容。 | None |
4 | CDATASection | 代表文档中的 CDATA 部分(不会由解析器解析的文本)。 | None |
5 | EntityReference | 代表实体引用。 | Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference |
6 | Entity | 代表实体。 | Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference |
7 | ProcessingInstruction | 代表处理指令。 | None |
8 | Comment | 代表注释。 | None |
9 | Document | 代表整个文档(DOM 树的根节点)。 | Element, ProcessingInstruction, Comment, DocumentType |
10 | DocumentType | 向为文档定义的实体提供接口 | None |
11 | DocumentFragment | 代表轻量级的 Document 对象,能够容纳文档的某个部分 | Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference |
12 | Notation | 代表 DTD 中声明的符号。 | None |
对于每种节点类型,nodeName 和 nodeValue 属性的返回值:
节点类型 | nodeName 返回 | nodeValue 返回 | |
---|---|---|---|
1 | Element | 元素名 | null |
2 | Attr | 属性名称 | 属性值 |
3 | Text | #text | 节点的内容 |
4 | CDATASection | #cdata-section | 节点的内容 |
5 | EntityReference | 实体引用名称 | null |
6 | Entity | 实体名称 | null |
7 | ProcessingInstruction | target | 节点的内容 |
8 | Comment | #comment | 注释文本 |
9 | Document | #document | null |
10 | DocumentType | 文档类型名称 | null |
11 | DocumentFragment | #document 片段 | null |
12 | Notation | 符号名称 | null |
NodeTypes - Named Constants
NodeType | Named Constant |
---|---|
1 | ELEMENT_NODE |
2 | ATTRIBUTE_NODE |
3 | TEXT_NODE |
4 | CDATA_SECTION_NODE |
5 | ENTITY_REFERENCE_NODE |
6 | ENTITY_NODE |
7 | PROCESSING_INSTRUCTION_NODE |
8 | COMMENT_NODE |
9 | DOCUMENT_NODE |
10 | DOCUMENT_TYPE_NODE |
11 | DOCUMENT_FRAGMENT_NODE |
12 | NOTATION_NODE |