Vue简介

el和data的两种写法

        const v = new Vue({
el: '#root',
data: {
name: '123'
}
})

动态指定el容器

        console.log(v)
setTimeout(()=>{
v.$mount('#root')
},1000)

函数式返回data

            data: function() {
return {
name: '123'
}
}

而不能写成箭头函数,因为箭头函数没有this,下面输出为window而不是vue

            data:()=> {
console.log(this)
return {
name: '123'
}
}

在对象中写明方法也可以简写为

            data() {
console.log(this)
return {
name: '123'
}
}

MVVM模型

M:模型(Model):Data中的数据

V:视图(View):模板代码

VM:视图模型(ViewModel):Vue实例

数据代理

Object.defineProperty方法(对象,新增属性,value)

let number = 18
let person = {
name: 'hikaru',
sex: 'w',
// age: 30
} Object.defineProperty(person, "age", {
value: number,
enumerable: true, //设置新增属性可以枚举,默认为false
writable: true, //设置新增属性可以被修改,默认为false
configurable: true //设置新增属性可以被删除,默认为false
})
// 两种遍历方法
for (let key in person) {
console.log(person[key])
}
console.log(Object.keys(person))
console.log(person)

get和set方法

        Object.defineProperty(person, "age", {
// value: number,
enumerable: true, //设置新增属性可以枚举,默认为false
// writable: true, //设置新增属性可以被修改,默认为false
// configurable: true, //设置新增属性可以被删除,默认为false
get() {
return number
},
set(value) {
console.log(value)
} })

get在当age被读取时,get函数(getter)就会被调用,且返回值就是age的值

set在当age被修改时,set函数(setter)就会被调用,且参数就是被修改的age值

get set方法与writable、configurable属性重复不能一起写

数据代理实现

通过一个对象实现对另一个对象的读写操作

Vue.config.productionTip = false
let obj1 = {x:100}
let obj2 = {y:200} Object.defineProperty(obj2, 'x', {
get() {
return obj1.x
},
set(value) {
obj1.x = value
}
})

Vue中的数据代理:通过vm对象来代理data中的数据

vm(vue实体)将model中的data赋值给vm中的_data

数据代理: 将_data中所有的属性通过Object.defineProperty添加到vm中。

vm的data调用getter、setter方法时就会获取修改model中的data。

事件处理 v-on:xxx / @xxx

    <div id="root">
<button v-on:click="getInfo1">Info1</button><br/>
<button @click="getInfo2($event, 66)">Info2</button><br/>
<a href="https://www.baidu.com" @click="changeTarget">baidu</a><br/>
</div>
    <script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el: "#root",
methods: {
getInfo1() {
alert('info1')
},
getInfo2(event, number) {
console.log(number)
},
changeTarget(event) {
alert(event.target.href)
event.target.href += '/s?wd=vue'
}
},
})
</script>

只有data中的数据会被数据劫持代理,如果把method加入data也会被数据代理

Vue常用事件修饰符

1 prevent 阻止默认事件

js写法

        new Vue({
el: "#root",
methods: {
getInfo1() {
alert('info1')
},
getInfo2(event, number) {
console.log(number)
},
changeTarget(e) {
alert(e.target.href)
e.preventDefault(); }
},
})

Vue写法:@click.prevent

<a href="https://www.baidu.com" @click.prevent="changeTarget">baidu</a><br/>
2 stop 阻止事件向上级冒泡
3 once 事件只触发一次
4 capture 使用事件的捕获模式
5 self 只有event.target是当前操作的元素时才触发事件
    <div id="root" @click.prevent.self="getInfo">
<button @click.prevent="getInfo">getInfo</button>
</div>

冒泡到root的div时target仍是按钮

<button>getInfo</button>
6 passive 事件的默认行为立即执行,无需等待事件回调执行完毕

键盘事件

@keyup 在按键抬起的时候触发事件

@keydown 在按键按下的时候触发事件

常用按键别名

回车 Enter

删除 Delete

退出 Esc

空格 Spacce

换行 tab 需要配合keydown使用

上 up

下 down

左 left

右 right

    <div id="root">
<input type="text" placeholder="输入字符回车后提示" @keyup.enter="getInfo">
</div>
    <script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el: "#root",
methods: {
getInfo(e) {
console.log(e.key + ', ' + e.keyCode)
}
}
})
</script>

e.key + ', ' + e.keyCode 获取键盘输入字符和字符编码

如回车 Enter 13

计算属性

1 使用插值语法实现

<div id="root">
姓:<input type="text" v-model="firstName" ><br/>
名:<input type="text" v-model="lastName"><br/>
姓名:{{firstName + lastName}}
</div>
</body> <script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el: "#root",
data: {
firstName: '张',
lastName: '三'
}
})
</script>

2 使用methods实现

<div id="root">
姓:<input type="text" v-model="firstName" ><br/>
名:<input type="text" v-model="lastName"><br/>
姓名:{{getFullName()}}
</div>
</body> <script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el: "#root",
data: {
firstName: '张',
lastName: '三'
},
methods: {
getFullName() {
return this.firstName.slice(0,3) + '-' + this.lastName;
}
}
})
</script>

使用有返回值的方法时必须加括号

3 计算属性 利用已经有的属性计算生成新属性

            computed: {
fullName: {
get() {
return this.firstName.slice(0,3) + '-' + this.lastName;
},
set() { }
}
}

底层使用的是Object.defineProperty,方法get在被计算的属性被修改、计算的属性读取时被调用

只有get方法的计算属性的简写形式
            computed: {
fullName: function(){
return this.firstName.slice(0,3) + '-' + this.lastName;
}
}

监视属性

两种监视方法

①通过Vue实例化时的watch属性

            watch: {
firstName: {
immediate: true,
handler(newValue, oldValue) {
console.log(newValue + '=>' + oldValue)
}
}
}

immediate表示在被监视属性初始化时就调用handler

handler方法在被监视属性被修改时就会被调用

②通过vm

vm.$watch('lastName', {
immediate: true,
handler(newValue, oldValue) {
console.log(newValue + oldValue)
}
})

''为正常写法,不加引号是简写

在只有handler时的简写形式

            watch: {
firstName(newValue, oldValue) {
console.log(newValue + oldValue)
}
}
})
vm.$watch('lastName', function(newValue, oldValue){
console.log(newValue + oldValue)
})

深度监视

            watch: {
firstName: {
immediate: true,
deep: true,
handler(newValue, oldValue) {
console.log(newValue + '=>' + oldValue)
}
}
}

深度监视在数据有多层结构时会监视所有的层结构数据,默认为false

与计算属性的比较 需求:延迟显示

                watch: {
firstName(val) {
setTimeout(()=>{
this.fullName = val + this.lastName
},1000
)
},
lastName(val) {
setTimeout(()=>{
this.fullName = this.firstName + val
},1000
)
}

computer可以完成的功能,watch都能完成,反之则不然,如监视属性方便进行异步,而计算属性只能瞬时return

这里使用了箭头函数,但是函数中的this仍为vm,这是因为箭头函数没有自己的this,需要递归向上寻找this,而lastName为普通函数且其this为vm,故箭头函数中的this为vm

箭头函数与普通函数的使用原则

被Vue管理的函数使用普通函数,这样this指向的是vm实例 或者 组件对象

所有不被Vue管理的函数,使用箭头函数,这样this指向的是vm实例 或者 组件对象

如:定时器的回调函数、ajax的回调函数、Promise的回调函数等

class与stye的绑定 :class

    <body>
<div id="root">
<div class="basic" :class="classes" @click="changeMood"> </div>
</div>
</body> <script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el: '#root',
data: {
classes: 'normal'
},
methods: {
changeMood() {
let choose = Math.floor(Math.random(2) * 3)
let moods = ['normal', 'happy', 'sad']
this.classes = moods[choose]
}
}
})
</script>

①字符串写法

②数组写法

        new Vue({
el: '#root',
data: {
classArr: 'normal'
},
methods: {
changeMood() {
let choose = Math.floor(Math.random(2) * 3)
let moods = ['normal', 'happy', 'sad']
this.classArr = moods[choose]
}
}
})

③对象写法

            data: {
classArr: 'normal',
classObj: {
happy: false,
sad: true
}
},

条件渲染 v-if v-show

v-show=""中的表达式为真时,会为元素添加 style="display: none"

v-if 会直接让元素消失

列表渲染 v-for

遍历数组

        <div id="root">
<h2>人员列表</h2>
<ul v-for="(emp, index) in employeeList" :key="index">
<li>{{emp.name}}-{{emp.age}}</li>
</ul>
</div>
        new Vue({
el: '#root',
data: {
employeeList:[
{id: '001', name: '张三', age: 18},
{id: '002', name: '李四', age: 28},
{id: '003', name: '王五', age: 19}
]
},
methods: { }
})

遍历对象

        <div id="root">
<h2>人员列表</h2>
<ul v-for="(val, key) in employeeList[0]">
<li>{{val}} - {{key}}</li>
</ul>
</div>

接收对象的两个值先是value然后再是key

key的工作原理 虚拟DOM对比算法

key设置的属性为遍历对象的唯一标识

代码:

    <body>
<div id="root">
<h2>人员列表</h2>
<ul v-for="(emp, index) in employeeList" :key="index">
<li>{{index}} : {{emp.name}}-{{emp.age}} <input type="text"></li>
</ul>
<button @click="add">add</button>
</div>
</body> <script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el: '#root',
data: {
employeeList:[
{id: '001', name: '张三', age: 18},
{id: '002', name: '李四', age: 28},
{id: '003', name: '王五', age: 19}
]
},
methods: {
add() {
const e = {id: '004', name: '老六', age: 30}
this.employeeList.unshift(e)
}
}
})
</script>

出现的问题:

原因:

虚拟DOM对比算法,即是在数据发生变化的时候,生成的虚拟DOM会和原来的虚拟DOM依据key值进行比较,如果相同则直接复用原来的DOM结构,否则会生成新的DOM结构

如上图中,key为0的两个DOM比较,发现文本不同但是输入框相同(虚拟DOM不会考虑文本框内的内容),因此会生成新文本“老刘-30”,然后复用原来的输入框。

解决方法

①使用数据中的id作为key值

            <ul v-for="(emp, index) in employeeList" :key="emp.id">
<li>{{index}} : {{emp.name}}-{{emp.age}} <input type="text"></li>
</ul>

②或者使用不改变原有index顺序的插入方法

            methods: {
add() {
const e = {id: '004', name: '老六', age: 30}
this.employeeList.push(e)
}
}

列表过滤

用watch实现

<body>
<div id="root">
<h2>人员列表</h2>
<input v-model="keyWord" placeholder="请输入信息"/>
<ul v-for="(person, index) in filPersons" :key="index">
<li>{{person.name}}-{{person.age}}</li>
</ul>
</div>
</body> <script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el: '#root',
data: {
persons:[
{id: '001', name: '马冬梅', age: 18},
{id: '002', name: '周冬雨', age: 28},
{id: '003', name: '周杰伦', age: 19},
{id: '004', name: '温兆伦', age: 17}
],
filPersons: [],
keyWord: ''
},
methods: { },
watch: {
keyWord: {
immediate: true,
handler(val) {
this.filPersons = this.persons.filter((p)=>{
return p.name.indexOf(val) !== -1;
})
}
}
}
})
</script>

使用计算属性

    <body>
<div id="root">
<h2>人员列表</h2>
<input v-model="keyWord" placeholder="请输入信息"/>
<ul v-for="(person, index) in filPersons" :key="index">
<li>{{person.name}}-{{person.age}}</li>
</ul>
</div>
</body> <script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el: '#root',
data: {
persons:[
{id: '001', name: '马冬梅', age: 18},
{id: '002', name: '周冬雨', age: 28},
{id: '003', name: '周杰伦', age: 19},
{id: '004', name: '温兆伦', age: 17}
],
keyWord: ''
},
methods: { },
computed: {
filPersons() {
return this.persons.filter((p)=>{
return p.name.indexOf(this.keyWord) !== -1;
})
}
}
})
</script>

列表排序

            computed: {
filPersons() {
const arr = this.persons.filter((p)=>{
return p.name.indexOf(this.keyWord) !== -1;
})
if(this.sortType) {
arr.sort((p1, p2) => {
return this.sortType === 1 ? p1.age-p2.age : p2.age-p1.age
})
}
return arr
}
}

收集表单数据为JSON数据: JSON.stringify

<!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>Document</title>
<script type="text/javascript" src="./js/vue.js"> </script>
<style>
button {
margin-left: 2%;
}
</style>
</head>
<body>
<div id="root">
<form @submit.prevent="submit()">
<label for="userName">账号:</label>
<input type="text" id="userName" v-model="userInfo.userName"/><br/><br/> <label for="password">密码:</label>
<input type="password" id="password" v-model="userInfo.password"/><br/><br/> <label for="age">年龄:</label>
<input type="number" id="age" v-model.number="userInfo.age"/><br/><br/> 性别:
男<input type="radio" name="sex" value="male" v-model="userInfo.sex"/>
女<input type="radio" name="sex" value="female" v-model="userInfo.sex"/><br/><br/> 爱好:
学习<input type="checkbox" value="learning" v-model="userInfo.hobby">
打游戏<input type="checkbox" value="game" v-model="userInfo.hobby">
吃饭<input type="checkbox" value="eating" v-model="userInfo.hobby">
<br/><br/> 所属校区
<select v-model="userInfo.school">
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="广州">广州</option>
<option value="深圳">深圳</option>
</select>
<br/><br/> 其他信息
<textarea v-model="userInfo.otherText"> </textarea><br/><br/> <input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="#">《用户协议》</a>
<br/><br/>
<button type="submit">提交</button>
</form> </div>
</body> <script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el: '#root',
data: {
userInfo: {
userName: '',
passWord: '',
age: '',
sex: 'male',
hobby: [],
school: '',
otherText: '',
agree: true
}
},
methods: {
submit() {
console.log(JSON.stringify(this.userInfo))
}
},
computed: { }
})
</script>
</html>

【Vue】一的更多相关文章

  1. Vue.js 和 MVVM 小细节

    MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自 ...

  2. wepack+sass+vue 入门教程(三)

    十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...

  3. wepack+sass+vue 入门教程(二)

    六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...

  4. wepack+sass+vue 入门教程(一)

    一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...

  5. Vue + Webpack + Vue-loader 系列教程(2)相关配置篇

    原文地址:https://lvyongbo.gitbooks.io/vue-loader/content/ 使用预处理器 在 Webpack 中,所有的预处理器需要和一个相应的加载器一同使用.vue- ...

  6. Vue + Webpack + Vue-loader 系列教程(1)功能介绍篇

    原文地址:https://lvyongbo.gitbooks.io/vue-loader/content/ Vue-loader 是什么? vue-loader 是一个加载器,能把如下格式的 Vue ...

  7. 关于Vue.js 2.0 的 Vuex 2.0,你需要更新的知识库

    应用结构 实际上,Vuex 在怎么组织你的代码结构上面没有任何限制,相反,它强制规定了一系列高级的原则: 应用级的状态集中放在 store 中. 改变状态的唯一方式是提交mutations,这是个同步 ...

  8. Vue.js 2.0 和 React、Augular等其他框架的全方位对比

    引言 这个页面无疑是最难编写的,但也是非常重要的.或许你遇到了一些问题并且先前用其他的框架解决了.来这里的目的是看看Vue是否有更好的解决方案.那么你就来对了. 客观来说,作为核心团队成员,显然我们会 ...

  9. 窥探Vue.js 2.0 - Virtual DOM到底是个什么鬼?

    引言 你可能听说在Vue.js 2.0已经发布,并且在其中新添加如了一些新功能.其中一个功能就是"Virtual DOM". Virtual DOM是什么 在之前,React和Em ...

  10. 初探Vue

    Vue.js(读音/vju:/,类似于view),是近来比较火的前端框架,但一直没有怎么具体了解.实现过,就知道个啥的MVVM啦,数据驱动啦,等这些关于Vue的虚概念. 由于最近,小生在公司中,负责开 ...

随机推荐

  1. airtest的手势滑动方法封装

    ​ 这个网上应该很多类似的方法封装,各种实现方式也很多,但是感觉最简单实用的还是swipe了:代码很简单,直接上方法了. 很多方法都不会告诉你会导入什么包,其实很多小白入门可能就是这么简单的一步就被卡 ...

  2. python发布定时任务(schedule模块)

    最近公司开始让在自己开发的软件上写日志,有几次下班了都忘了写,好几次都是给领导发邮件,说明一下自己没有写日志这件事,很麻烦.但是我一想我每天都要写,岂不是很麻烦,想想自己之前有爬虫经验,为什么自己不写 ...

  3. CF1272 B DIV3 ---代码对比

    这次DIV3有点可惜啊,题解是我的与学长的代码对比 学长的原博客https://www.cnblogs.com/xyq0220/p/12036109.html B.Snow Walking Robot ...

  4. hello cnb

    Huawei executive Meng Wanzhou freed by Canada arrives home in China 目录 关于git merge冲突时候的想法 Git修改commi ...

  5. HCK 、PCLK、FCLK的区别

    HCLK is used for AHB bus, which is used by the ARM920T, the memory controller, the interrupt control ...

  6. 《Unix/Linux系统编程》第十周学习笔记

    <Unix/Linux系统编程>第十周学习笔记 块设备I/O和缓冲区管理 解释块设备I/O的原理和I/O缓冲的优点 I/O缓冲区:内核中的一系列NBUF缓冲区用作缓冲区缓存.每个缓冲区用一 ...

  7. NXOpen遍历工作部件表达式

    //用户代码#include <uf_defs.h>#include <NXOpen/NXException.hxx>#include <NXOpen/Session.h ...

  8. LeetCode86 分隔链表

    idea: 烦死了,这个题一直因为创立的指针为空,或者接入结点方法不对,结果将两个小链表搞混乱了,不过具体思路ok.将小值结点成一组,大值结点成一组,最后在首尾相连,实现起来也比较简单 /**  *  ...

  9. 实验二:Open vSwitch虚拟交换机实践

    基础要求提交 a) /home/用户名/学号/lab2/目录下执行ovs-vsctl show命令.以及p0和p1连通性测试的执行结果截图: b) /home/用户名/学号/lab2/目录下开启Min ...

  10. webpack之loader与plugin

    loader与plugin的区别 loader的作用是将代码进行转换,比如less转成css,一个loader就是一个函数,接收的参数是上一个loader的返回值,loader进行一系列处理后 返回新 ...