上代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 导入vue的脚本文件,不是固定的 -->
<script src="unpkg.com_vue@3.3.4_dist_vue.global.js"></script>
</head>
<body>
<!-- 声明要被vue控制的DOM区域 -->
<div id="app">
{{message}} //第一种渲染方式{{}}:模板语法,两个花括号,可以将data中的数据直接做渲染.模板中只能有变量或者表达式,不能有语句.
<!-- 变量可以随意使用JS的方法 -->
{{message.split(" ").reverse().join('')}}
<p>姓名:{{user.username+'是我'}}</p>
<p>性别:{{user.gender}}</p>
<p>{{desc}}</p>//默认将标签看成字符串
<br>//渲染到标签里的地址
<p v-html="desc">{{desc}}</p>//v-html为指令,后面加上对应的值,作用为将指定的变量以HTML的形式渲染出来
<br>//渲染到属性里的地址 :/ v-bind: 不这样设置标签属性会默认把后面的变量当成字符串常量,加上冒号属性就会将""中的内容作为变量去读<br>
<a :href="link">百度</a>
<input type="text" :placeholder="inputValue">
<img :src="imgSrc" :style="{width:w}" alt="">
</div>
<div id="app0">
<!-- 数据发生变化,页面会自动渲染刷新 -->
<h3>count的值为: {{count}}</h3>
<!-- 事件绑定指令 -->
<button v-on:click="addCount">+1</button>
<button @click="count+=1">+1</button>
<!-- 貌似之前on开头的都可以用@表示 -->
<!-- 条件渲染指令:根据条件控制元素是否可以显示,比如豆瓣电影"新"标签是动态显示的-->
<button @click="flag=!flag">Reverse Flag!</button>
<!-- v-if:如果属性值为true,则渲染该标签 -->
<p v-if="flag">请求成功 --- 被 v-if 控制</p>
<p v-else>还没有成功捏</p>
<!-- 注意v-else必须紧跟v-if之后! 可以加表达式比如 v-if="type==='A"实现真正的if判断语句-->
<p v-show="flag">请求成功 --- 被 v-show 控制</p>
<!-- 二者不同的地方在于,如果flag=false那么v-if所在的标签根本不会被创建,检查html源码的时候完全消失 -->
<!-- 而v-show的标签会被创建,只不过通过增加CSS方式增加style="display:none;" -->
如果该标签会经常切换显示/不显示,则建议使用v-show,只是增删属性效果,性能更高!不过v-if还有v-else!
</div>
<div id="app1">
<!-- 列表渲染指令:后端返回多少数据,前端就渲染多少标签 -->
<ul>
<!-- 实际上写的只有一个li标签,但是能渲染很多 -->
<li v-for="(user,i) in userList" :key="user.name">索引:{{i}},姓名:{{user.name}}</li>
<!-- 也可以没有索引"user in userList"这样 -->
</ul>
<!-- v-for中的key,标记每一个li,给每一个使用v-for的li标签加上索引,否则组件化开发会报错 -->
<input type="text" v-model="name">
<!-- v-model双向绑定name的值,而且不用加 :以读取变量。如果页面发生变化则前端数据也会发生变化,数据变化则页面也会发生变化 -->
<!-- 如果使用 :value="name",则为单向绑定,页面变化时原数据无法改变 -->
<!-- 结合input,可以得出结论:用户输入的内容会自动影响name的属性值,会自动存储在前端data-return的name变量中了 -->
<button @click="addNewUser">添加</button>
<ul>
<li v-for="(user,index) in userList" :key="user.id"><input type="checkbox">姓名:{{user.name}}</li>
<!-- 原来key并不是区分不同的v-for,而是区分v-for之下的li标签。vue对于li标签的状态是有惰性的 -->
<!-- 如果不设置li标签的key,在第一个li复选框被勾选上时,如果在其之上产生了新的标签,vue的状态惰性会将勾选状态继续保持 -->
<!-- 如果加key,那么每一份状态就有了指定的标签归宿,解除了vue对于li标签状态的惰性 -->
<!-- 但是index也是会被动态继承的,最好要使用从数据库查询过来的主键,本次使用的是user.id -->
</ul>
</div>
<!-- 创建vue实例对象 -->
<script>
Vue.createApp({
data:function() {
return {
//{}中为对象
user:{
username:'zhangsan',
gender:'M',
},
desc:'<a href="http://www.baidu.com">百度</a>',
message:'Hello vue!',
link:"http://www.baidu.com",
//文本框的占位符内容
inputValue:'请输入内容',
imgSrc:'./images/demo.png',
w:'500px',
}
}
}).mount('#app')
Vue.createApp({
data:function(){ //数据
return{
count:0,
flag:false,
}
},
methods:{ //自定义方法
addCount(){
this.count+=1
},
}
}).mount('#app0')
Vue.createApp({
data:function(){ //数据:后面都是后端传过来的数据,即实现前后端的联调
return{
//用户列表
userList:[
{id:1,name:'zhangsan'},
{id:2,name:'lisi'},
],
num:Math.random(),//生成1以内的随机数
//输入的用户名
name:'',
//下一个用户可用的id值
nextId:3,
}
},
methods:{ //自定义方法,给数组的起始位置添加元素unshift
addNewUser(){
this.userList.unshift({id:this.nextId,name:this.name})
//这个name大有文章,它是在输入框input中的v-model属性值。也就是说,它是一种更好的同步动态的value值,也就是输入框中的值
//每次添加user时如果不将this.name置空,那么添加完之后name不变,输入框中仍旧显示上一个添加的姓名,不会刷新,不方便每次从头开始写
this.name=''
this.nextId++
},
}
}).mount('#app1')
</script>
</body>
</html>
其实抽象来看就是三个部分:首先在<head>模块中导入vue的脚本文件,然后声明data(Model)和 id属性(View),然后通过Vue.createApp(data).mount(id)让二者连接,形成页面。
各模块分析
<!-- 声明要被vue控制的DOM区域 -->
<div id="app">
{{message}} //第一种渲染方式{{}}:模板语法,两个花括号,可以将data中的数据直接做渲染.模板中只能有变量或者表达式,不能有语句.
<!-- 变量可以随意使用JS的方法 -->
{{message.split(" ").reverse().join('')}}
<p>姓名:{{user.username+'是我'}}</p>
<p>性别:{{user.gender}}</p>
<p>{{desc}}</p>//默认将标签看成字符串
<br>//渲染到标签里的地址
<p v-html="desc">{{desc}}</p>//v-html为指令,后面加上对应的值,作用为将指定的变量以HTML的形式渲染出来
<br>//渲染到属性里的地址 :/ v-bind: 不这样设置标签属性会默认把后面的变量当成字符串常量,加上冒号属性就会将""中的内容作为变量去读<br>
<a :href="link">百度</a>
<input type="text" :placeholder="inputValue">
<img :src="imgSrc" :style="{width:w}" alt="">
</div>
<scirpt>
Vue.createApp({
data:function() {
return {
//{}中为对象
user:{
username:'zhangsan',
gender:'M',
},
desc:'<a href="http://www.baidu.com">百度</a>',
message:'Hello vue!',
link:"http://www.baidu.com",
//文本框的占位符内容
inputValue:'请输入内容',
imgSrc:'./images/demo.png',
w:'500px',
}
}
}).mount('#app')
</script>
第一种渲染方式:{{ }}模板语法,两个花括号,可以将data中的数据直接做渲染。模板中只能有变量或者表达式,不能有语句。
<div id="app0">
<!-- 数据发生变化,页面会自动渲染刷新 -->
<h3>count的值为: {{count}}</h3>
<!-- 事件绑定指令 -->
<button v-on:click="addCount">+1</button>
<button @click="count+=1">+1</button>
<!-- 貌似之前on开头的都可以用@表示 -->
<!-- 条件渲染指令:根据条件控制元素是否可以显示,比如豆瓣电影"新"标签是动态显示的-->
<button @click="flag=!flag">Reverse Flag!</button>
<!-- v-if:如果属性值为true,则渲染该标签 -->
<p v-if="flag">请求成功 --- 被 v-if 控制</p>
<p v-else>还没有成功捏</p>
<!-- 注意v-else必须紧跟v-if之后! 可以加表达式比如 v-if="type==='A"实现真正的if判断语句-->
<p v-show="flag">请求成功 --- 被 v-show 控制</p>
<!-- 二者不同的地方在于,如果flag=false那么v-if所在的标签根本不会被创建,检查html源码的时候完全消失 -->
<!-- 而v-show的标签会被创建,只不过通过增加CSS方式增加style="display:none;" -->
如果该标签会经常切换显示/不显示,则建议使用v-show,只是增删属性效果,性能更高!不过v-if还有v-else!
</div>
Vue.createApp({
data:function(){ //数据
return{
count:0,
flag:false,
}
},
methods:{ //自定义方法
addCount(){
this.count+=1
},
}
}).mount('#app0')
重点在于:v-if v-else,这是切换时常用的标签属性。
<div id="app1">
<!-- 列表渲染指令:后端返回多少数据,前端就渲染多少标签 -->
<ul>
<!-- 实际上写的只有一个li标签,但是能渲染很多 -->
<li v-for="(user,i) in userList" :key="user.name">索引:{{i}},姓名:{{user.name}}</li>
<!-- 也可以没有索引"user in userList"这样 -->
</ul>
<!-- v-for中的key,标记每一个li,给每一个使用v-for的li标签加上索引,否则组件化开发会报错 -->
<input type="text" v-model="name">
<!-- v-model双向绑定name的值,而且不用加 :以读取变量。如果页面发生变化则前端数据也会发生变化,数据变化则页面也会发生变化 -->
<!-- 如果使用 :value="name",则为单向绑定,页面变化时原数据无法改变 -->
<!-- 结合input,可以得出结论:用户输入的内容会自动影响name的属性值,会自动存储在前端data-return的name变量中了 -->
<button @click="addNewUser">添加</button>
<ul>
<li v-for="(user,index) in userList" :key="user.id"><input type="checkbox">姓名:{{user.name}}</li>
<!-- 原来key并不是区分不同的v-for,而是区分v-for之下的li标签。vue对于li标签的状态是有惰性的 -->
<!-- 如果不设置li标签的key,在第一个li复选框被勾选上时,如果在其之上产生了新的标签,vue的状态惰性会将勾选状态继续保持 -->
<!-- 如果加key,那么每一份状态就有了指定的标签归宿,解除了vue对于li标签状态的惰性 -->
<!-- 但是index也是会被动态继承的,最好要使用从数据库查询过来的主键,本次使用的是user.id -->
</ul>
</div>
Vue.createApp({
data:function(){ //数据:后面都是后端传过来的数据,即实现前后端的联调
return{
//用户列表
userList:[
{id:1,name:'zhangsan'},
{id:2,name:'lisi'},
],
num:Math.random(),//生成1以内的随机数
//输入的用户名
name:'',
//下一个用户可用的id值
nextId:3,
}
},
methods:{ //自定义方法,给数组的起始位置添加元素unshift
addNewUser(){
this.userList.unshift({id:this.nextId,name:this.name})
//这个name大有文章,它是在输入框input中的v-model属性值。也就是说,它是一种更好的同步动态的value值,也就是输入框中的值
//每次添加user时如果不将this.name置空,那么添加完之后name不变,输入框中仍旧显示上一个添加的姓名,不会刷新,不方便每次从头开始写
this.name=''
this.nextId++
},
}
}).mount('#app1')
重点是addNewUser方法的思想,每次提交后,姓名都清空,便于后续重新输入。