Vue

Vue简介

Vue 核心

初识 Vue

  1. 想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象;
new Vue({
el:'#demo',
data:{ //data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
name:'atguigu',
address:'北京'
}
})

参数说明:

  • el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。也可以是以原生JS的方法获得的DOM元素。比如:el:document.getElementById("root")
  • data中用于存储数据,数据供el所指定的容器去使用,值可以是对象或函数的形式,常用函数的形式
  1. root容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法;
  2. root容器里的代码被称为【Vue模板】;
  3. Vue实例和容器是一一对应的(不是一对多或多对一的关系);
  4. 真实开发中只有一个Vue实例,并且会配合着组件一起使用;
  5. {{xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性;
    注意区分:js表达式 和 js代码(语句)
    1. 表达式:一个表达式会产生一个值(包括undefined),可以放在任何一个需要值的地方:
      (1). a
      (2). a+b
      (3). demo(1)
      (4). x === y ? 'a' : 'b'
    2. js代码(语句)
      (1). if(){}
      (2). for(){}
  6. 一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新;
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>初识Vue</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="demo">
<h1>Hello,{{name.toUpperCase()}},{{address}}</h1>
</div>
<script type="text/javascript" >
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
//创建Vue实例
new Vue({
el:'#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
data:{ //data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
name:'atguigu',
address:'北京'
}
})
</script>
</body>
</html>

image

Vue.config 是一个对象,包含 Vue 的全局配置。可以在启动应用之前修改下列 property
productionTip

  • 类型:boolean
  • 默认值:true
  • 用法:设置为 false 以阻止 vue 在启动时生成生产提示。
    image

模板语法

html 中包含了一些 JS 语法代码,语法分为两种,分别为:

  1. 插值语法(双大括号表达式)
  2. 指令(以 v-开头)

Vue模板语法有2大类:

  1. 插值语法:
    功能:用于解析标签体内容。
    写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。
  2. 指令语法:
    功能:用于解析标签(包括:标签属性、标签体内容、绑定事件.....)。
    举例:v-bind:href="xxx" 或 简写为 :href="xxx",xxx同样要写js表达式,且可以直接读取到data中的所有属性。
    备注:Vue中有很多的指令,且形式都是:v-????,只是v-bind:href="xxx"可以简写为:href="xxx"
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<!-- 插值语法只能解析标签体内容,不能解析标签属性内容,所以href的值就为"{{url}}" -->
<a href="{{url}}">点我去{{name}}学习1</a>
<!-- 要想解析标签属性内容可以用v-bind,这里是简写形式 -->
<a :href="url">点我去{{name}}学习2</a>
</div>
<script type="text/javascript" >
new Vue({
el:'#root',
data:{
name:'jack',
// 同名属性写在同一级的话后面的属性会覆盖前面的,将同名属性写在不同层级不会互相影响
name:'尚硅谷',
url:'http://www.atguigu.com',
}
})
</script>
</body>
</html>

image
image

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>模板语法</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<h1>插值语法</h1>
<h3>你好,{{name}}</h3>
<hr/>
<h1>指令语法</h1>
<a v-bind:href="school.url.toUpperCase()" x="hello">点我去{{school.name}}学习1</a>
<a :href="school.url" x="hello">点我去{{school.name}}学习2</a>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el:'#root',
data:{
name:'jack',
school:{
// 同名属性写在同一级的话后面的属性会覆盖前面的,将同名属性写在不同层级不会互相影响
name:'尚硅谷',
url:'http://www.atguigu.com',
}
}
})
</script>
</html>

image

数据绑定

Vue中有2种数据绑定的方式:

  1. 单向数据绑定
  • 语法:v-bind:href ="xxx" 或简写为 :href
  • 特点:数据只能从 data 流向页面
  1. 双向数据绑定
  • 语法:v-mode:value="xxx" 或简写为 v-model="xxx"
  • 特点:数据不仅能从 data 流向页面,还能从页面流向 data
    备注:
  1. 双向绑定一般都应用在表单类元素上(如:input、select等),就是有value属性的元素,即可以输入值的元素(包括单选按钮,复选框等)
  2. v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。
<body>
<!--
Vue中有2种数据绑定的方式:
1.单向绑定(v-bind):数据只能从data流向页面。
2.双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。
备注:
1.双向绑定一般都应用在表单类元素上(如:input、select等)
2.v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。
-->
<!-- 准备好一个容器-->
<div id="root">
<!-- 普通写法 -->
<!-- 单向数据绑定:<input type="text" v-bind:value="name"><br/>
双向数据绑定:<input type="text" v-model:value="name"><br/> -->
<!-- 简写 -->
单向数据绑定:<input type="text" :value="name"><br/>
双向数据绑定:<input type="text" v-model="name"><br/>
<!-- 如下代码是错误的,因为v-model只能应用在表单类元素(输入类元素)上 -->
<!-- <h2 v-model:x="name">你好啊</h2> -->
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el:'#root',
data:{
name:'尚硅谷'
}
})
</script>

单向数据绑定
image

image

el和data的2种写法

  1. el有2种写法
    (1).new Vue时候配置el属性。
const v = new Vue({
el:'#root', //第一种写法, 在创建Vue实例对象时就指定el
data:{
name:'尚硅谷'
}
})

(2).先创建Vue实例,随后再通过vm.$mount('#root')指定el的值。mount此处意为挂载

// 创建Vue实例时先不指定el
const v = new Vue({
data:{
name:'尚硅谷'
}
})
...
v.$mount('#root') //第二种写法, 在适当的时候再挂载el
  1. data有2种写法
    (1).对象式
new Vue({
el:'#root',
//data的第一种写法:对象式
data:{
name:'尚硅谷'
}

(2).函数式:data属性值是一个函数(不要是箭头函数,以免造成this的混乱),函数的返回值是与对象式中的data等效的对象, 例如
data:function(){ ... return {...} }
可简写成
data(){ ... return {...} }
函数中的this是Vue实例对象

如何选择:目前哪种写法都可以,以后学习到组件时,data必须使用函数式,否则会报错。

  1. 一个重要的原则:
    由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了。

MVVM 模型

  1. M:模型(Model) :对应 data 中的数据
  2. V:视图(View) :模板html
  3. VM:视图模型(ViewModel) : Vue 实例对象

特点
image

  1. data中所有的属性,最后都出现在了vm身上。
  2. vm身上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。
<body>
<!-- 准备好一个容器-->
<div id="root">
<h1>学校名称:{{name}}</h1>
<h1>学校地址:{{address}}</h1>
<h1>测试一下1:{{1+1}}</h1>
<!-- Vue模板(就是与Vue实例绑定的DOM)可以直接读取Vue实例及其原型链上的属性 -->
<h1>测试一下2:{{$options}}</h1>
<h1>测试一下3:{{$emit}}</h1>
<h1>测试一下4:{{_c}}</h1>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
const vm = new Vue({
el:'#root',
data:{
// data中的属性添加到了Vue实例中
name:'尚硅谷',
address:'北京',
}
})
console.log(vm)
</script>

image

数据代理

Object.defineProperty()

详见MDN
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象
该方法允许精确地添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,在枚举对象属性时会被枚举到(for...in 或 Object.keys方法),可以改变这些属性的值,也可以删除这些属性。这个方法允许修改默认的额外选项(或配置)。默认情况下,使用 Object.defineProperty() 添加的属性值是不可修改(immutable)、不可删除且不可枚举的。
备注:应当直接在 Object 构造器对象上调用此方法,而不是在任意一个 Object 类型的实例上调用
语法
Object.defineProperty(obj, prop, descriptor)
参数
obj: 要定义属性的对象。
prop:要定义或修改的属性的名称或 Symbol
descriptor:要定义或修改的属性描述符(就是一个配置对象)。对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符是由 getter 函数和 setter 函数所描述的属性。一个描述符只能是这两者其中之一;不能同时是两者
返回值:被传递给函数的对象

descriptor中的配置项

  • value, 即要配置的obj对象中prop的属性值
  • writable,控制属性是否可以被修改,默认值是false即不能被重新赋值
var o = {}; // 创建一个新对象
Object.defineProperty(o, 'a', {
value: 37,
writable: false
});
console.log(o.a); // logs 37
o.a = 25; // No error thrown
// (it would throw in strict mode,
// even if the value had been the same)
console.log(o.a); // logs 37. The assignment didn't work.
  • enumerable 默认是false,定义了该属性是否可以在 for...in 循环和 Object.keys() 中被枚举
var o = {};
Object.defineProperty(o, "a", { value : 1, enumerable: true });
Object.defineProperty(o, "b", { value : 2, enumerable: false });
Object.defineProperty(o, "c", { value : 3 }); // enumerable 默认为 false
o.d = 4; // 如果使用直接赋值的方式创建对象的属性,则 enumerable 为 true
for (var i in o) {
console.log(i);
}
// logs 'a' and 'd' (in undefined order)
Object.keys(o); // ['a', 'd']
  • configurable 默认值为false,表示对象的属性是否可以被删除,以及除 value 和 writable 外的其他配置项是否可以被修改
var o = {};
Object.defineProperty(o, 'a', {
get() { return 1; },
configurable: false
});
Object.defineProperty(o, 'a', {
configurable: true
}); // throws a TypeError
Object.defineProperty(o, 'a', {
enumerable: true
}); // throws a TypeError
Object.defineProperty(o, 'a', {
set() {}
}); // throws a TypeError (set was undefined previously)
Object.defineProperty(o, 'a', {
get() { return 1; }
}); // throws a TypeError
// (even though the new get does exactly the same thing)
Object.defineProperty(o, 'a', {
value: 12
}); // throws a TypeError // ('value' can be changed when 'configurable' is false but not in this case due to 'get' accessor)
console.log(o.a); // logs 1
delete o.a; // Nothing happens
console.log(o.a); // logs 1

如果 o.a 的 configurable 属性为 true,则不会抛出任何错误,并且,最后,该属性会被删除

  • get() :每次读取prop属性时,get函数(getter)就会被调用,且返回值就是prop属性的值
  • set() :每次修改person的age属性时,set函数(setter)就会被调用,该方法接受一个参数(也就是被赋予的新值)
<body>
<script type="text/javascript" >
let number = 18
let person = {
name:'张三',
sex:'男',
}
Object.defineProperty(person,'age',{
// value:18,
// enumerable:true, //控制属性是否可以枚举,默认值是false
// writable:true, //控制属性是否可以被修改,默认值是false
// configurable:true //控制属性是否可以被删除,默认值是false
//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
get(){
console.log('有人读取age属性了')
return number
},
//当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
set(value){
console.log('有人修改了age属性,且值是',value)
number = value
}
})
// console.log(Object.keys(person))
console.log(person)
</script>
</body>

image

数据代理

通过Object.defineProperty()让obj中的x属性映射到obj2中(双向映射的关系),同时修改obj2中的x属性也会修改obj中的x属性, 这类现象叫做“数据代理”

let obj = {x:100}
let obj2 = {y:200}
Object.defineProperty(obj2,'x',{
get(){
return obj.x
},
set(value){
obj.x = value
}
})

image

Vue中的数据代理

  1. Vue中的数据代理:
    通过vm对象来代理data对象中属性的操作(读/写)
  2. Vue中数据代理的好处:
    更加方便的操作data中的数据, 即可以直接用data对象中的属性名,而
    不用通过_data.属性名来操作属性
  3. 基本原理:
    通过Object.defineProperty()把data对象中所有属性添加到vm上。
    为每一个添加到vm上的属性,都指定一个getter和setter。
    在getter和setter内部去操作(读/写)data中对应的属性。
    image

image

image


本文作者:Code6E

本文链接:https://www.cnblogs.com/road2code/p/17149163.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Code6E  阅读(16)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.