Vue实现
MVVM
-
MVVM,一种软件架构模式,决定了写代码的思想和层次
- M: model数据模型 (data里定义)
- V: view视图 (html页面)
- VM: ViewModel视图模型 (vue.js源码)
-
MVVM通过数据双向绑定让数据自动地双向同步 不再需要操作DOM
- V(修改视图) -> M(数据自动同步)
- M(修改数据) -> V(视图自动同步)
-
在vue中,不推荐直接手动操作DOM!!!
-
在vue中,通过数据驱动视图,不要在想着怎么操作DOM,而是想着如何操作数据!!(思想转变)
下面实现双向绑定
vue实现双向绑定,只使用
v-model
指令就可以完成。
- 数据变化 -> 视图自动同步
- 视图变化 -> 数据自动同步
1. 基本使用
<template>
<div>
<div>
<span>用户名:</span>
<!-- 1. v-model
双向数据绑定
value属性 - vue变量
-->
<input type="text" v-model="username">
</div>
<div>
<span>密码: </span>
<input type="password" v-model="pass">
</div>
</div>
</template>
<script>
export default {
data(){
return {
username: "",
pass: ""
}
}
}
</script>
<style>
</style>
2. 更多用法
<template>
<div>
<div>
<span>来自于: </span>
<!-- 下拉菜单要绑定在select上 -->
<select v-model="from">
<option value="北京市">北京</option>
<option value="南京市">南京</option>
<option value="天津市">天津</option>
</select>
</div>
<div>
<!-- (重要)
遇到复选框, v-model的变量值
非数组 - 关联的是复选框的checked属性
数组 - 关联的是复选框的value属性
-->
<span>爱好: </span>
<input type="checkbox" v-model="hobby" value="抽烟">抽烟
<input type="checkbox" v-model="hobby" value="喝酒">喝酒
<input type="checkbox" v-model="hobby" value="写代码">写代码
</div>
<div>
<span>性别: </span>
<input type="radio" value="男" name="sex" v-model="gender">男
<input type="radio" value="女" name="sex" v-model="gender">女
</div>
<div>
<span>自我介绍</span>
<textarea v-model="intro"></textarea>
</div>
</div>
</template>
<script>
export default {
data(){
return {
from: "",
hobby: [],
gender: "男",
intro: ""
}
}
}
</script>
<style>
</style>
3. v-model的修饰符
<template>
<div>
<div>
<span>年龄</span>
<!-- .number修饰符-把值parseFloat转数值再赋予给v-model对应的变量 -->
<input type="text" v-model.number="age">
</div>
<div>
<!-- .trim修饰 - 去除首尾两边空格 -->
<span>人生格言</span>
<input type="text" v-model.trim="motto">
</div>
<div>
<!-- .lazy修饰符 - 失去焦点内容改变时(onchange事件), 把内容同步给v-model的变量 -->
<span>个人简介</span>
<textarea v-model.lazy="intro"></textarea>
</div>
</div>
</template>
<script>
export default {
data(){
return {
age: 0,
motto: "",
intro: ""
}
}
}
</script>
<style>
</style>
原生实现
原理就是利用了
Object.defineProperty()
,这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的。
<div id="app">
<input type="text">
</div>
<!--
双向绑定的原生实现
1. 数据 -> 视图
数据一旦发生变化 视图会使用最新的数据进行更新
2. 视图 -> 数据
视图一旦发生变化 会把视图当前用户输入的最新的值 反向影响到数据
-->
<!--
数据 -> 视图
本质: 如何知道数据变化了
-->
<!--
视图 -> 数据
本质: 如何可以拿到当前视图最新的值 监听事件通过事件回调拿到最新的输入值
-->
<script>
// let info = {
// name:'cp'
// }
let info = {}
let _name = ''
Object.defineProperty(info, 'name', {
// 获取info.name属性会执行
// return 值就是你获取到的值
get() {
return _name
},
// 修改info.name属性时候会执行
set(value) {
// 使用最新的数据 value 去更新视图的逻辑呢?
// 什么是视图更新? dom操作
// 使用value 让input元素的value跟着变化
_name = value
document.querySelector('#app input').value = value
}
})
document.querySelector('#app input').addEventListener('input', (e) => {
// 反向赋值
info.name = e.target.value
})
/*
1.数据响应式 object.defineProperty()
2.数据驱动视图 数据变化 视图会使用最新的数据进行更新
3.如何让视图更新 视图更新离不开dom操作
4.视图发生变化 指的是用户因为输入 input 对视图的显示进行了修改
5.视图变化如何拿到当前视图最新的输入内容 基于事件监听 通过回调函数中的事件对象e拿到
*/
</script>