1.网页临时获取一个网络资源,若通过同步方式获取,那么js 则需要等待资源完全从服务器端获取后才能继续执行。而采用异步,在下载资源期间,js 和UI 的执行都不会处于等待状态。
2. 阻塞与非阻塞IO
阻塞:必须等当前任务执行完,返回数据再执行下一个数据。
非阻塞IO: 内核把输入输出都当做文件来处理,应用程序若进行IO 调用,需先打开文件描述符,然后根据文件描述符取显示文件的数据读取。而非阻塞io完成整个过程则不带数据直接返回。若要获取数据,通过文件描述符再次读取。
非阻塞再次获取文件方式:轮询(重复调用判断操作 确认是否完成)
2.1 read 最原始,性能最低,通过重复检查IO 的状态来完成完整数据的读取,在完成任务前,cpu 一直耗用在等待上。
2.2 select 通过对文件描述符的状态进行判断。但其采用1024长度的数组来存储状态,最多只能同时检查1024个文件描述符。
2.3 根据 select改进,存储方式为链表避免数组长度的限制和不要的检查。
2.4 epoll 进入轮询如果没有检查到io 事件,将会进行休眠,直到事件发生将它唤醒。利用事件通知、执行回调的方式,而不是遍历查询。
轮询:满足非阻塞io 确报获取完整数据的需求,但对应用程序,仍只能算一种同步,因应用程序仍需等待io 完全返回,依旧花费很多时间来等待。等待期间,CPU 要么用于遍历文件描述符,要么用于休眠等待事件发生。
3.现实的异步io
多线程方式实现,通过让部分线程进行阻塞io 或非阻塞io 加轮询技术来完成数据获取,让一个线程进行计算。
常说 Node 是单线程是指 javascript 执行在单线程而已。
3.1 Node 实现异步IO : 事件循环(生产者消费者模型 从观察者那里取出事件并处理)观察者和请求对象(异步IO 网络请求)。
4. webpack 作用
一切皆模块
Webpack有一个不可不说的优点,它把所有的文件都都当做模块处理,JavaScript代码,CSS和fonts以及图片等等通过合适的loader都可以被处理。
webpack提供两个工具处理样式表,css-loader
和 style-loader
,二者处理的任务不同,css-loader
使你能够使用类似@import
和 url(...)
的方法实现 require()
的功能,style-loader
将所有的计算后的样式加入页面中,二者组合在一起使你能够把样式表嵌入webpack打包后的JS文件中。
5. 关于script src 的路径问题
使用相对于web工程的相对路径(在单页面html 中 使用 当前工程的相对路径)
-
<link type="text/css" rel="stylesheet" href="styles/main.css" />
-
<script type="text/javascript" src="scripts/dtree.js"></script>
5. vue 文件中的 ,style 的scope 属性6. .vue 中的<script></script> 中采用es6 语法
与es2015 差别:
var name="123";
var Person={ name: name} ====> 简写: var Person={ name}
var Person={
eat: function(){ 省略掉: :function =========》 eat(){ console.log('eat eat eat ') }
console.log('eat eat eat ')
}
}
.vue文件中的script 导出对象中有 data 方法 返回一个对象,在template 中直接使用属性即可e
export default {
}
6.各种命令
v-bind 绑定某种样式属性,多与class 结合使用。
单个样式 用三元表达式判断即可。多个样式写成JSON 格式。
<div v-bind:class="isStyle?'red':'blue'"></div>
<div :class="{'red':true,'blue':false}">123</div>
<div>
<ul>
<li v-for="item in stu" :class="{12:'red',25:'blue'}[item.age]">{{item.name}}</li>
</ul>
</div>
还可以根据数据内容来 决定当前使用什么样式。{}[] 样式对象后面跟随一个数组
<script>
export default {
data(){
return{
myapp:"这是我的第一个vue项目示例",
text: "zmmmmmmm",
isStyle: false,
html: `
<ul>
<li>haha</li>
</ul>
`,
stu: [{
name: 'zbc',
age: 12
},
{
name: 'zmm',
age: 25
}]
}
}
}
</script>
<style>
.red{
background-color: red;
width: 100px;
height:100px
}
.blue{
background-color: blue;
width: 100px;
height:100px
}
</style>
v-text :将文本赋予双标签元素,即innerText 属性。
v-html : 同理,即innerHtml
v-model 双向数据流
v-bind 单向,在标签中改变值,不影响其他地方。
v-for 放在循环结构中 v-for="stu in stus"
<input type="text" name="" v-model="text">
<span v-html="html"></span>
<input type="text" name="" v-bind:value="text">
<script>
export default {
data(){
return{
myapp:"这是我的第一个vue项目示例",
text: "zmmmmmmm",
isStyle: false,
html: `
<ul>
<li>haha</li>
</ul> `
}
}
methods:{
change(){
this.isStyle=!this.isStyle;
this.stu.push({name:'zm',age: 29}) ========》在script js 代码中,通过this.属性 赋值
}
}
}
</script>
绑定事件 v-on: (事件名)=“(表达式)/(方法名 有参数则加上传参,没参数则可以省略括号不写)”
<button v-on:click="isStyle=!isStyle">按钮</button>
<button @click="change">按钮2</button>
.在export default 中添加属性methods 中的方法。methods:{ }
v-for 用于循环遍历数组、对象。为了性能优化,一般会绑定index 属性,是为了在删除元素的时候能够删除js 中的数据,而不需重排。
<div>
<ul>
<li v-for="(item,index) in stu" v-bind="index">{{item.name}} index:{{index}}</li>
</ul>
</div>
遍历对象,value,key,index 按照顺序排列,其后与使用向对应。
<div>
<ul>
<li v-for="(value,key,index) in person" v-bind="index">value:{{value}} index:{{index}} key:{{key}}</li>
</ul>
</div>
7. 组件的使用
7.1 父子组件的使用
1.新建子组件.vue 文件,可在style 中定义 样式,在style 后面加上 “scoped” 则表示定义样式作用于子组件内,不带则表示作用于全局。
2. 在父组件.vue 文件中 js script 前引入 import header.vue from ‘./componets/header.vue’ 文件,并在export default {}里面 s声明 components 属性, 属性对象中{}key,value 引入 子组件,key 可省略不写。
components:{
headVue:headVue,===============》(‘组件名’:组件对象)
footVue
}
或者使用全局组件:
在main.js 中直接import ,其后声明 Vue.component('组件名',组件对象)
import headVue from './components/header.vue'
import footVue from './components/footer.vue'
Vue.component('headVue',headVue);
Vue.component('footVue',footVue);
7.2 父组件给子组件传值
7.2.1 在子组件的export default{} 中 声明父组件定义的属性props:['prop1','prop2'] 父组件中直接赋值给属性
1.赋值给常量
2.赋值给变量。 需要在父组件的export default{} 中的data 函数中添加属性变量值,并在标签中通过
v-bind 绑定。
<headVue textIn="hell"></headVue>
<footVue :textfoot="hello"></footVue>
App.vue
export default {
data(){
return{
myapp:"这是我的第一个vue项目示例",
text: "zmmmmmmm",
isStyle: false,
hello: 'kogou',
}
}
}
footer.vue
<script type="text/javascript">
export default{
props: ['textfoot']
}
</script>
7.3 子组件给父组件传值
通过新建一个vue 文件 导出作为通信连接的connect
import Vue from 'vue'
var connect=new Vue()
export default connect
实例 事件
this.$on('事件名',回调函数(参数)) ===》触发事件
this.$once('事件名',回调函数(参数)) ====>就触发一次
this.$off('事件名' ) ============》取消事件
this.$emit('事件名',数据)==========》发送数据
在父组件 js 中import connect from '../connect.js' ============》vuebus
methods 中引入方法,注册事件 connect.$on('phone',fn)
<template>
<div>
<footVue></footVue>
<button v-on:click="callPhone">等待消息</button>
</div>
</template>
<script>
import connect from './connector/connector.js';
export default {
data(){
return{
}
},
methods:{
callPhone(){
connect.$on('phone',function(message){
console.log(message)
})
}
}
}
在子组件 js 中import connect from '../connect.js'===========> vuebus
methods 中引入方法,触发事件 connect.$emit('phone',data)
<template>
<div>
<button v-on:click="emitM">sonmessage</button>
</div>
</template>
<script>
import connect from '../connector/connector.js';
export default{
data(){
return{
}
},
methods:{
emitM(){
connect.$emit('phone','i miss you')
}
}
}
</script>
<style scoped>
div{
height: 100px;width: 100px;
background-color: yellow;
}
</style>
7.4 过滤器的使用
7.4.1 定义局部过滤器 声明filters 属性,对应一个对象。这个对象即为过滤器函数,参数作为传递的内容,函数体类实现一系列数据变化,
<template>
<div>
<footVue></footVue>
<button v-on:click="callPhone">等待消息</button>
<input type="text" v-model="text">
显示:{{text | myfilter}}
</div>
</template>
export default {
filters: {
myfilter:function(value){
return value.split('').reverse().join('');
}
},
data(){
return{
text:'zkj'
}
},
7.4.2 定义全局过滤器
在main.js 中声明。
Vue.filter('myfilter',function(){
return '123';
)
注意:一般vue中定义函数 都有返回值。
7.5 获取原生元素(div 等)
在组件创建之后,初始化会生成 created()函数,此时还尚未构建DOM 树。
在mounted()函数阶段,DOM树已经构成,可获取到元素。
<div ref="divAttr"></div>
mounted(){
this.$refs.divAttr.innerHTML='123'; ===》插入文本
}
7.6 获取子组件元素
<footVue ref="foot"></footVue>
<div ref="divAttr"></div>
mounted(){
console.log(this.$refs.divAttr);============》div
console.log(this);=====================》App.vue 对象
console.log(this.$refs.foot); =============》foot.vue对象
this.$refs.divAttr.innerHTML='123';=======》 操作div 元素,插值
this.$refs.foot.$el.innerHTML='123ger'; ====》获取组件对象中的DOM 对象($el)
}
7.7 根据路由跳转
main.js
import Music from './music.vue'
var router=new Router({
route: {name: 'music',path: './music',component: Music}
})
或者:router.addRoutes([{path: '/home',redirect: '/home'}]) ===>或者 redirect: {name: 'home'}
new Vue({
el:'#app',
router: router, =============>注意:标签为router
render:(h)==>h(App)
})
在App.vue 中注册 引入 <router-view></router-view> 即路由跳转页面控制将在此显示。
方式一: 通过对象当中的name 属性 ,查找到要跳转的地址 <router-link :to="{name: 'music' }"></router-link>
方式二: 直接跳转到path 的目录位置,显示相应的页面 <router-link to="/path"></router-link>
可以在URL中传递参数 <router-link :to="{name: 'music' ,query:{id: 'index'} }"></router-link>
====> <a href="#/music?id=2></a>
routes:[ {name: 'music',path: './music/:id',component: Music} ]====> <a href="#/music/2></a>
<router-link :to="{name: 'music' ,param:{id: 'index'} }"></router-link>
vue-router 挂载两类属性。$route : 数据属性 $router: 功能属性
create(){ this.$route.query}========> id:2
获取路由参数: this.$route.query.id
在第一次访问页面时 create() 函数中可获取。
根据浏览器记录 向上一页跳转 this.$router.go(-1) 向下一页跳转 this.$router.go(1)
向指定地方跳转 this.$router.push({name: '...'}) 或者指着传地址 this.$router.push(‘/music’)
7.6 嵌套路由
在路由设置中,设置路径等。 父组件的router-view 中可以包含children 其子组件的router-view
main.js
let router=new VueRouter({
routes:[
{path:'/',redirect: '/type'},
{name:'inner',path:'/dance',query:{id: 0},component:innerVue},
{name:'detailM',path:'/detail',component:detailVue},
{name: 'type',path: '/type',component:entainmentVue,
children:[{name: 'music',path: 'music',component:musicVue},
{name: 'movie',path: 'movie',component:movieVue}]
}
]
})
entainment.vue
<template>
<div>
娱乐
<router-link :to="{name:'movie'}">电影</router-link>
<router-link :to="{name:'music'}">音乐</router-link>
<router-view></router-view>
</div>
</template>
App.vue
<template>
<div>
<headVue></headVue>
<router-view></router-view>
</div>
</template>
7.6 多视图
在一个router-view 中可能细分顶部、中部、底部等。可以name 属性来区分
在routes 属性里面 根据路径,添加多个components 一个name 对应一个componet, 若无name,可设置为default:
main.js
let router=new VueRouter({
routes:[
{path: '/',components:{music:musicVue,movie:movieVue} }
]
App.vue
<template>
<div>
<headVue></headVue>
<router-view name="movie"></router-view>
<router-view name="music"></router-view>
</div>
</template>