vue介绍
-
什么是vue
- vue是一个前端开发框架,用于降低UI复杂度
-
vue的特点
- 渐进性
- 响应性
- 组件化
环境配置
-
node.js
官网 https://nodejs.org/zh-cn/ 检查是否安装成功 node --version
-
配置淘宝镜像
npm包的服务器在国外,下载速度会很慢,配置淘宝镜像(国内)
终端中输入 npm config set registry https://registry.npm.taobao.org 检查是否配置成功 npm config get registry
-
vue cli (vue脚手架构建vue项目)
终端中输入 npm install -g @vue/cli 检查是否安装成功 vue --version
vue脚手架(vue cli)构建vue项目
-
命令行方式
vue create myapp
-
图形化界面
vue ui
下载与卸载依赖
-
下载
npm init npm i 包名 例如 npm i element-ui npm i axios
-
卸载
npm uninstall 包名
插值表达式
-
{{表达式}}
-
变量{{msg}}
-
字符串{{‘测试’}}
-
三元表达式{{true ? ‘测试1’ : ‘测试2’}}
<template> <div> <h2>{{msg}}</h2> <h2>{{'测试'}}</h2> <h2>{{true ? '测试1' : '测试2'}}</h2> </div> </template> <script> export default { data () { return { msg: '测试' } } } </script> <style scoped lang='less'> </style>
-
常用的指令
-
v-text
-
v-html
<template> <div> <h2 v-text="msg1"></h2> <div v-html="msg2"></div> </div> </template> <script> export default { data () { return { msg1: 'v-text相当于innerText', msg2: '<h2>v-html相当于innerHTML</h2>' } } } </script> <style scoped lang='less'> </style>
-
v-if、v-else-if、v-else
<template> <div> <h2 v-if="item===1">测试1</h2> <h2 v-else-if="item===2">测试2</h2> <h2 v-else>测试</h2> <hr /> <div class="box" v-if="isShow" style="background:red;"></div> <div class="box" v-else style="background:green;"></div> <button @click="isShow=!isShow">切换</button> </div> </template> <script> export default { data () { return { item: 1, isShow: true } } } </script> <style scoped lang='less'> .box { width: 200px; height: 200px; } </style>
-
v-show
<template> <div> <div class="box" v-show="isShow"></div> <button @click="isShow=!isShow">{{isShow ? '隐藏' : '显示'}}</button> </div> </template> <script> export default { data () { return { isShow: true } } } </script> <style scoped lang='less'> .box { width: 200px; height: 200px; background: pink; } </style>
-
v-bind:class 简写 :class 动态绑定属性
<template> <div> <!-- 动态绑定class--对象形式 --> <div :class="classObj"></div> <button @click="handle()">切换</button> <!-- 动态绑定class--数组形式 --> <div :class="classArr"></div> <hr /> <!-- 动态绑定style--对象形式 --> <div :style="styleObj"></div> <!-- 动态绑定style--数组形式 --> <div :style="[styleArr1,styleArr2]"></div> </div> </template> <script> export default { data () { return { classObj: { red: true, green: false }, classArr: ['demo1', 'demo2'], styleObj: { width: '200px', height: '200px', background: 'pink' }, styleArr1: { width: '200px', height: '200px' }, styleArr2: { background: 'deeppink' } } }, methods: { handle () { for (let item in this.classObj) { this.classObj[item] = !this.classObj[item] } } } } </script> <style scoped lang='less'> .red { width: 200px; height: 200px; background-color: red; } .green { width: 200px; height: 200px; background-color: green; } .demo1 { width: 200px; height: 200px; border: 1px solid red; } .demo2 { background-color: orange; } .demo2:hover { transform: scale(1.5); } </style>
-
v-on:click 简写 @click 事件处理
<template> <div> <div class="box" v-show="isShow"></div> <button @click="handle()">{{isShow ? '隐藏' : '显示'}}</button> </div> </template> <script> export default { data () { return { isShow: true } }, methods: { handle () { this.isShow = !this.isShow } } } </script> <style scoped lang='less'> .box { width: 300px; height: 300px; background-color: pink; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; } </style>
-
v-model
双向数据绑定,相当于绑定了input的value值,注册了input事件 <input type="text" v-model="msg"> <input type="text" :value="msg" @input="msg=$event.target.value" />
-
v-for
<template> <div> <ul> <li v-for="item in arr" :key="item.id"> <h3>{{item.title}}</h3> </li> </ul> </div> </template> <script> export default { data () { return { arr: [ { id: 0, title: 'SACASCASCASCASCSASA' }, { id: 1, title: 'SACASCASCASCASCSASA' }, { id: 2, title: 'SACASCASCASCASCSASA' }, { id: 3, title: 'SACASCASCASCASCSASA' }, { id: 4, title: 'SACASCASCASCASCSASA' } ] } } } </script> <style scoped lang='less'> ul { list-style: none; li { width: 300px; border: 1px solid #ccc; } } </style>
事件修饰符
-
.stop
<!-- 阻止事件冒泡或捕获 --> <a @click.stop="handle()"></a> 相当于event.stopPropagation()
-
.prevent
<!-- 阻止默认事件的执行,如a标签的默认跳转事件 --> <a @click.prevent="handle()"></a> 相当于event.preventDefault()
-
事件修饰符可以串联也可以只有修饰符
<!-- 修饰符可以串联 --> <a @click.stop.prevent="handle"></a> <!-- 只有修饰符 --> <form v-on:submit.prevent></form>
-
.self
<!-- 只当在 event.target 是当前元素自身时触发处理函数 --> <div @click.self="handle"></div>
-
.once
<!-- 点击事件将只会触发一次 --> <a @click.once="handle"></a>
按键修饰符
-
.enter
回车键触发submit <input @keyup.enter="submit">
侦听器watch
<template>
<div>
<!-- 浅度监听 -->
<div>
<h2>{{msg}}</h2>
<input type="text" v-model="msg" />
</div>
<hr />
<!-- 深度监听 -->
<div>
<input type="text" v-model="msg1" />
<button @click="confirm()">修改name</button>
<ul>
<li v-for="item in obj" :key="item">{{item}}</li>
</ul>
</div>
</div>
</template>
<script>
export default {
data () {
return {
msg: 'safafasas',
msg1: '',
obj: {
name: 'sadassda'
}
}
},
methods: {
confirm () {
this.obj.name = this.msg1
}
},
watch: {
// 浅度监听
msg (newV, oldV) {
console.log(newV, oldV)
},
// 深度监听
obj: {
deep: true,
handler (newV, oldV) {
console.log(newV, oldV)
}
}
}
}
</script>
<style scoped lang='less'>
</style>
计算属性computed
<template>
<div>
firstName:
<input type="text" v-model="firstName" />
<br />
laseName:
<input type="text" v-model="lastName" />
<br />
fullName:
<input disabled type="text" v-model="fullName" />
</div>
</template>
<script>
export default {
data () {
return {
firstName: 'MEI',
lastName: 'BO'
}
},
computed: {
fullName () {
return this.firstName + '--' + this.lastName
}
}
}
</script>
<style scoped lang='less'>
</style>
组件
组件通信
-
父传子
父组件 Home.vue <template> <div> <h2>父组件</h2> <Main :Msg="msg"></Main> </div> </template> <script> import Main from '../components/Main' export default { data () { return { msg: '我是父组件传来的信息' } }, components: { Main } } </script> <style scoped lang='less'> </style>
子组件 Main.vue <template> <div> <h4>子组件</h4> <p>{{Msg}}</p> </div> </template> <script> export default { data () { return {} }, props: { Msg: String } } </script> <style scoped lang='less'> </style>
-
子传父
父组件 Home.vue <template> <div> <h2>父组件</h2> <p>{{msg}}</p> <Main @myevent="handle"></Main> </div> </template> <script> import Main from '../components/Main' export default { data () { return { msg: '' } }, methods: { handle (val) { this.msg = val } }, components: { Main } } </script> <style scoped lang='less'> </style>
子组件 Main.vue <template> <div> <button @click="handle">子传父</button> </div> </template> <script> export default { data () { return {} }, methods: { handle () { this.$emit('myevent', '我是子组件传来的信息') // 触发事件 } } } </script> <style scoped lang='less'> </style>
-
组件refs
-
ref放在标签上,拿到的是原生节点
<template> <div> <input type="text" v-model="msg" ref="msgRef" @blur="handle" /> </div> </template> <script> export default { data () { return { msg: '测试' } }, methods: { handle () { console.log(this.$refs.msgRef) // 原生节点input console.log(this.$refs.msgRef.value) // input的value值 } } } </script> <style scoped lang='less'> </style>
-
生命周期
-
什么是生命周期
每个 Vue 实例在被创建时都要经过一系列的初始化过程。例如:从开始创建、初始化数据、编译模板、挂载Dom、数据变化时更新DOM、卸载等一系列过程。我们称这一系列的过程就是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会,利用各个钩子来完成我们的业务代码。
-
生命周期图示
-
生命周期钩子函数
经常使用的是created(完成创建后执行的钩子函数)和mounted(编译好的html挂载到页面后执行的钩子函数),在这里请求后台接口数据
推荐一个开源API:https://api.apiopen.top/api.html
例:
<template>
<div>
<!-- 名言 -->
<div>
<h1>随机一句名言</h1>
<div class="wrap">
<h2>{{info.from}}</h2>
<p>{{info.name}}</p>
</div>
</div>
<hr />
<!-- 网易新闻 -->
<div>
<h1>网易新闻</h1>
<ul>
<li v-for="item in newsData" :key="item.title">
<h2>
<a target="_black" :href="item.path">{{item.title}}</a>
</h2>
<p>{{item.passtime}}</p>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
data () {
return {
info: {},
newsData: []
}
},
created () {
this.getInfo()
this.getNewsData()
},
methods: {
// 获取随机一句名言
async getInfo () {
const res = await this.$http.get('http://poetry.apiopen.top/sentences')
if (res.status === 200) {
this.info = res.data.result
}
},
// 获取网易新闻
async getNewsData () {
const res = await this.$http.post('https://api.apiopen.top/getWangYiNews')
if (res.status === 200) {
this.newsData = res.data.result
}
}
}
}
</script>
<style scoped lang='less'>
* {
margin: 0;
padding: 0;
}
.wrap {
padding: 10px;
}
hr {
margin: 20px 0 20px 0;
}
ul {
list-style: none;
li {
padding: 10px;
a {
color: black;
text-decoration: none;
}
}
}
</style>
MVVM
-
Model view viewModel(模型 视图 视图模型)数据驱动视图改变
-
数据劫持
-
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过object.defineProperty()来劫持各个属性的setter ,getter,在数据变动时发布消息给订阅者,触发相应的监听回调
-
实现mvvm的双向数据绑定
-
实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
-
实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
-
实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
-