root容器里面的代码被称为【vue模板】
Vue模板语法有两大类:插值语法、指令语法
插值语法一般动态指定标签体内容,解析标签体内容
指令语法一般动态指定标签属性值,解析标签
插值语法:
功能:用于解析标签体的内容
语法: {{xxx}}**,**xxx是js表达式,且可以直接读取到data中的所有属性
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> 初识vue</title>
<!--引入vue 引入之后,全局就多了一个vue这个构造函数-->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>插值语法</h1>
<h3>你好,{{name}} </h3>
<hr/>
</div>
<script type="text/javascript">
//阻止vue在启动时生成生产提示
Vue.config.productionTip=false
new Vue({
el:'#root',
data:{
name:'jack'
}
})
</script>
</body>
</html>
假如我们使用下图的方式获取data中url的内容,控制台会有一个报错
点我去一个好地方
new Vue({
el:'#root',
data:{
name:'jack',
url:'http://www.baidu.com'
}
报错信息:插值语法去动态指定标签里面的属性值的方式已经被移除了,我们可以使用v-bind或 :id=“val”,也就是指令语法
指令语法:
功能:用于解析标签(包括:标签属性、标签体内容、绑定事件…)
举例:
v-bind:href=“xxx” 可简写成 :href=“xxx”
xxx同样要写js表达式,且可以直接读取到data中的所有属性
备注:Vue中有很多的指令,且形式都是:v-???
<div id="root">
<h1>插值语法</h1>
<h3>你好,{{name}} </h3>
<hr/>
<h1>指令语法</h1>
<!-- 带有v-的都是指令语法 bind是绑定的意思 -->
<!-- 在这个地方把url的结构绑定给href url为js表达式 -->
<!-- v-bind可以动态的给属性绑定值 -->
<!-- <a v-bind:href="url">点我去一个好地方</a> -->
<!-- 其中v-bind都可以省略写成 : -->
<a :href="url">点我去一个好地方</a>
</div>
<script type="text/javascript">
//阻止vue在启动时生成生产提示
Vue.config.productionTip=false
new Vue({
el:'#root',
data:{
name:'jack',
url:'http://www.baidu.com'
}
})
</script>
原因:下面的url被当做url表达式来执行了
<a v-bind:href="url">
Vue中有两种数据绑定方式:
1.单向绑定(v-bind):数据只能从data流向页面
2.双向绑定(v-model):数据能从data和页面互相流向
备注:
1.双向绑定一般都应用在表单类元素上(如:input、select等)
2.v-model:value 可以简写为v-model,因为v-model默认手机的就是value值
我们之前在指令语法中见到了
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> 初识vue</title>
<!--引入vue 引入之后,全局就多了一个vue这个构造函数-->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
单行数据绑定: <input type="text" :value="name">
</div>
<script type="text/javascript">
//阻止vue在启动时生成生产提示
Vue.config.productionTip=false
new Vue({
el:'#root',
data:{
name:'尚硅谷123'
}
})
</script>
</body>
</htm
展示单向数据绑定
当我们在Vue中修改name的值的时候,页面的值也会随着修改,如下图
但是我们在文本框中修改内容的时候,Vue中的name值不会改变
原因: 单向绑定的关系
<div id="root">
单行数据绑定: <input type="text" :value="name">
<br>
双向数据绑定: <input type="text" v-model:value="name">
</div>
结果如下图
当我们修改Vue中name时,我们发现两个文本框都会改变
当我们修改双向绑定文本框的时候,我们发现Vue的name值也会改变 (单向文本框也会改变的原因是因为Vue的name值改变了)
产生了一个类似下图的连锁反应
以后会在学组件的时候使用到el与data
<script type="text/javascript">
//阻止vue在启动时生成生产提示
Vue.config.productionTip=false
const v= new Vue({
el:'#root', //el第一种写法
data:{
name:'张靖奇'
}
})
</script>
<script type="text/javascript">
//阻止vue在启动时生成生产提示
Vue.config.productionTip=false
const v= new Vue({
data:{
name:'张靖奇'
}
})
v.$mount('#root') //el第二种写法 mount是挂载的意思
</script>
在Vue实例中有几个很特别的属性,带着$符,这些都是给我们用的
不带$符的都不是给程序员用的(Vue底层自己在用)
我们使用$mount替换el
为什么说这种方式更灵活呢?
比如下段代码我们设置了一个定时器,在1秒之后才将Vue实例和root容器关联
为什么是mount?
我们要把我们的模板root交给Vue实例进行解析,解析完之后将内容放到(挂载到)页面上指定位置展示
<script type="text/javascript">
//阻止vue在启动时生成生产提示
Vue.config.productionTip=false
const v= new Vue({
el:'#root',
//data的第一种写法,对象式
data:{
name:'张靖奇'
}
})
</script>
函数式 (推荐)
函数式必须要返回一个对象,对象中的数据就是我们所需要的
<script type="text/javascript">
//阻止vue在启动时生成生产提示
Vue.config.productionTip=false
const v= new Vue({
el:'#root',
//data的第二种写法,函数式
data:function(){
return{
name:'张靖奇'
}
}
})
</script>
而且我们的data函数是Vue帮我们调用的,我们可以验证一下
下图中的this是Vue实例对象 (前提是把下图中的data写成普通函数,如果写成箭头函数便不可以,因为箭头函数中没有this,就会往外找,找到全局的window)
由Vue管理的函数一定不要写成箭头函数,一旦写了箭头函数,this就不再是Vue实例了
data:function(){
console.log('@@@',this)
return{
name:'尚硅谷'
}
}
我们一般都下面这样写,比较方便
data(){
return{
}
}
数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)
给一个对象添加或定义属性使用
比如下面有一个person对象,然后我们想增加一个“age”属性,怎么办?
let person = {
name: '张三',
sex: '男',
}
如下所示:
<script type="text/javascript">
let number = 18
let person = {
name: '张三',
sex: '男',
}
//参数一:给哪个对象添加参数
//参数二:添加的参数叫什么名
//参数三:配置项,可以写很多的配置
bject.defineProperty(person, 'age', {
value: 18,//这样就代表着age属性的值是18
// 但是我们这样添加的元素无法进行枚举或者遍历
// 为了我们新添加的age元素可以添加遍历,我们还需要一个配置
enumerable: true,
//除此之外,我们新添加的age属性在页面上无法修改,为了在页面上也可以修改,我们需要再进行配置
// writable:true
configurable: true, //控制属性可以被删除
})
</script>
假如我想把自定义的变量number赋值给person的新属性age怎么做?
<script type="text/javascript">
let number =18
let person ={
name:'张三',
sex:'男',
}
Object.defineProperty(person,'age',{
enumerable:true,
// writable:true,
configurable:true ,
//当有人读取person的age属性时,get函数或者说getter就会被调用,且返回值就是age的值
get:function(){
console.log('有人读取了age属性')
return number
},
// 当有人修改person的age属性时,set函数或者说setter就会被调用,且会受到具体的值
set(value){
console.log('有人修改了age属性时,且值是',value)
number=value
}
})
</script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> 初识vue</title>
<!--引入vue 引入之后,全局就多了一个vue这个构造函数-->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
</div>
<script type="text/javascript">
let obj= { x:100 }
let obj2={ y:200 }
Object.defineProperty(obj2,'x',{
//当有人想获取obj2中的x属性时,我们把obj的x属性给他
get(){
return obj.x
},
// setter被调用时说明有人想修改obj2的x
// 当有人想修改obj2中x属性时,我们把obj中的x属性值给改掉就可以了
set(value){
obj.x=value
}
})
</script>
</body>
</html>
效果如下图所示
通过vm对象来代理data对象中属性的操作(读或写)
更加方便的操作data中的数据。
我们在data中定义的数据,在Vue实例中是"_data"的形式存在,即vm._data=data
通过Object.defineProperty()把data对象中所有属性添加到vm上
为每个添加到vm上的属性都指定一个getter和setter
在getter/setter内部去操作(读或写)data中对应的属性
数据代理图示
下图中右下角黄色和紫色的先就代表着数据代理
假设我们没有数据代理,我们在使用插值语句的时候使用了**_data.xxxx**这样就增加了代码量,也非常的不方便,故我们使用了上面的数据代理
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> 初识vue</title>
<!--引入vue 引入之后,全局就多了一个vue这个构造函数-->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h1> {{_data.name}}</h1>
<h1> {{_data.address}}</h1>
</div>
<script type="text/javascript">
//阻止vue在启动时生成生产提示
Vue.config.productionTip=false
new Vue({
el:'#root',
data:{
name:'尚硅谷',
address:'洪福科技园'
}
})
</script>
</body>
</html>