Vue框架-基础知识(二)
一、基础知识
以v-开头的为Vue的指令,使用v-bind来绑定属性
1、绑定属性 v-bind:
<template>
<div class="msg">
<p>
<!--插值表达式-->
{{message}}{{name}}
</p>
<span v-bind:title="dream">学好vue不是梦</span>
</div>
</template>
<script>
export default {
name: "Greeting",
data(){
return {
message:'Hello Python测开大佬们',
name: '不语',
dream: '小目标'
}
}
}
</script>
鼠标移至span标签内容上,显示“小目标”。data中的dream作为span的title属性内容,如图:

v:bind 缩写成 :
2、v-if和v-show
v-if:
<template> <div class="msg"> <p v-if="isNotKeyou">不会开车的老师不是好老师</p> </div> </template> <script> export default { name: "Greeting", data(){ return { isNotKeyou: false
} } } </script> <style scoped> .msg p{ color: red; } </style>
p标签中的变量isNotKeyou在data()中设置为false,页面中P标签对应的内容不显示,当设置isNotKeyou为true时,p标签内容才显示:
v-if每次都会重新删除或创建控制区域的html页面元素。

v-show
设置v-show的isNotKeyou属性值为false,对应控制区域的p标签内容不显示,但是p标签页面元素存在。
<template> <div class="msg"> <p v-show="isNotKeyou">不会开车的老师不是好老师</p> </div> </template> <script> export default { name: "Greeting", data(){ return { isNotKeyou: false } } } </script> <style scoped> .msg p{ color: red; } </style>

设置isNotKeyou为true,p标签的内容显示

v-show 每次不会重新进行DOM的删除和创建操作,只是切换元素的display属性。
3、条件渲染
<template> <div class="msg"> <p>有一天,{{username}}想去网吧上网</p> <p v-if="age >= 70">爷爷,你还是回去锻炼身体!</p> <p v-else-if="age >= 18">欢迎光临,请愉快的上网吧</p> <p v-else>{{username}}小朋友,作业写完了吗</p> </div> </template> <script> export default { name: "Greeting", data(){ return { username: '马仔', age: 16 } } } </script> <style scoped> .msg p{ color: red; } </style>
通过修改age的值,满足不同的条件,从而显示不同的标签内容。
age设置16,显示如图

age=19,显示如下:
age=70,显示如下:

4、表格
增加子组件ProjectList.vue设置表格和样式:
<template>
<div>
<table>
<tr>
<th>项目名称</th>
<th>项目负责人</th>
<th>应用名称</th>
</tr>
<tr>
<td>前程贷项目</td>
<td>奔奔</td>
<td>p2p</td>
</tr>
<tr>
<td>探索火星项目</td>
<td>悠悠</td>
<td>吊炸天应用</td>
</tr>
<tr>
<td>无比牛逼的项目</td>
<td>芳芳</td>
<td>神秘应用</td>
</tr>
</table>
</div>
</template>
<script>
export default {
name: "ProjectList"
}
</script>
<style scoped>
table{
margin: 50px auto;
border-collapse: collapse;
width: 40%;
}
td, th{
border: 1px solid #dddddd;
padding: 8px;
}
</style>
在父组件中引用和声明,页面效果如图:

缺点:表格中的数据直接写死。
假如数据是在数据库中,那怎么渲染到前端呢?是否可以将数据放在data中,通过插值表达式的方式读取呢?数据多的话不可取,这种情况下需要用到for循环。
5、v-for
<template>
<div>
<!-- <table>-->
<!-- <tr>-->
<!-- <th>项目名称</th>-->
<!-- <th>项目负责人</th>-->
<!-- <th>应用名称</th>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td>前程贷项目</td>-->
<!-- <td>奔奔</td>-->
<!-- <td>p2p</td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td>探索火星项目</td>-->
<!-- <td>悠悠</td>-->
<!-- <td>吊炸天应用</td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td>无比牛逼的项目</td>-->
<!-- <td>芳芳</td>-->
<!-- <td>神秘应用</td>-->
<!-- </tr>-->
<!-- </table>-->
<table>
<tr>
<th v-for="(project,key) in project_headers" v-bind:key="key">{{project}}</th>
</tr>
<tr v-for="(item, key) in projects" v-bind:key="key">
<td>{{item.name}}</td>
<td>{{item.leader}}</td>
<td>{{item.app_name}}</td>
</tr>
</table>
</div>
</template>
<script>
export default {
name: "ProjectList",
data(){
return{
project_headers:['项目名称','项目负责人','应用名称'],
projects:[
{name:'前程贷项目', leader:'奔奔', app_name:'p2p平台应用'},
{name:'探索火星项目', leader:'悠悠', app_name:'吊炸天应用'},
{name:'无比牛逼的项目', leader:'芳芳', app_name:'神秘应用'},
]
}
}
}
</script>
<style scoped>
table{
margin: 50px auto;
border-collapse: collapse;
width: 40%;
}
td, th{
border: 1px solid #dddddd;
padding: 8px;
}
</style>
将数据已数组方式存储在data中,v-for对数据进行遍历
v-bind:key对数据进行双向绑定,页面运行效果:

6、使用UI框架来实现
ElementUI参考文档地址:https://element.eleme.cn/#/en-US/component/installation
- 安装命令:npm i element-ui -S
- 在 main.js 中写入以下内容:
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
- ElementUI加入Vue实例中
Vue.use(ElementUI);
//导入vue.js import Vue from 'vue' //导入根组件 import App from './App.vue' //导入element-ui import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; //在创建Vue实例之前,要将element-ui插入到Vue中 Vue.use(ElementUI); Vue.config.productionTip = false //创建实例 new Vue({ render: h => h(App),//render:渲染App根组件 }).$mount('#app')//app:index.html中的div且id=app的容器
新建子组件ElementProject.vue,从ElementUI中选择对应的组件,复制源码进行修改:
<template>
<el-table
ref="multipleTable"
:data="tableData"
style="width: 100%"
@selection-change="handleSelectionChange"
class="ElementProject">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
label="项目名称"
prop="name"
width="120">
</el-table-column>
<el-table-column
label="项目负责人"
prop="leader"
width="120">
</el-table-column>
<el-table-column
label="应用名称"
prop="app_name"
width="120">
</el-table-column>
</el-table>
</template>
<script>
export default {
name: "ElementProject",
data(){
return{
project_headers:['项目名称','项目负责人','应用名称'],
tableData:[
{name:'前程贷项目', leader:'奔奔', app_name:'p2p平台应用'},
{name:'探索火星项目', leader:'悠悠', app_name:'吊炸天应用'},
{name:'无比牛逼的项目', leader:'芳芳', app_name:'神秘应用'},
]
}
}
}
</script>
<style scoped>
.ElementProject{
margin: 50px 500px;
}
</style>
上述代码中,需要指定数据源tableData,每列的数据指定对应的key值。
效果图:

7、v-on
v-on为Vue中的指令,用于绑定事件(各种事件),事件触发之后可以执行js操作,v-on:缩写成@
<template>
<div class="msg">
<span v-on:click="username='路人'">有一天,{{username}}想去网吧上网</span>
<p v-if="age >= 70">爷爷,你还是回去锻炼身体!</p>
<p v-else-if="age >= 18">欢迎光临,请愉快的上网吧</p>
<p v-else>{{username}}小朋友,作业写完了吗</p>
</div>
</template>
<script>
export default {
name: "Greeting",
data(){
return {
username: '马仔',
age: 16
}
}
}
</script>
<style scoped>
.msg p{
color: red;
}
</style>
鼠标点击span标签内容后,页面发生变化:
点击前 : 点击后:

事件除了可以直接指定属性之外,也可以调用函数来改变属性:
<template>
<div class="msg">
<!-- <span @click="username='路人'">有一天,{{username}}想去网吧上网</span>-->
<span @click="changeUsername">有一天,{{username}}想去网吧上网</span>
<p v-if="age >= 70">爷爷,你还是回去锻炼身体!</p>
<p v-else-if="age >= 18">欢迎光临,请愉快的上网吧</p>
<p v-else>{{username}}小朋友,作业写完了吗</p>
</div>
</template>
<script>
export default {
name: "Greeting",
data(){
return {
username: '马仔',
age: 16
}
},
methods:{
changeUsername:function () {
//this就相当于python中的self
this.username='一个没有整容需求的人'
}
}
}
</script>
<style scoped>
.msg p{
color: red;
}
</style>
vue中函数是在scpript的methods中定义,事件绑定函数时,直接写入函数名。点击事件发生时,条用函数,点击后效果如图:

methods中方法定义的第二种方法:
<template>
<div>
<el-table
ref="multipleTable"
:data="tableData"
style="width: 100%"
@selection-change="handleSelectionChange"
class="ElementProject">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
label="项目名称"
prop="name"
width="120">
</el-table-column>
<el-table-column
label="项目负责人"
prop="leader"
width="120">
</el-table-column>
<el-table-column
label="应用名称"
prop="app_name"
width="120">
</el-table-column>
</el-table>
<el-button @click="toggleSelection()">Clear selection</el-button>
</div>
</template>
<script>
export default {
name: "ElementProject",
data(){
return{
project_headers:['项目名称','项目负责人','应用名称'],
tableData:[
{name:'前程贷项目', leader:'奔奔', app_name:'p2p平台应用'},
{name:'探索火星项目', leader:'悠悠', app_name:'吊炸天应用'},
{name:'无比牛逼的项目', leader:'芳芳', app_name:'神秘应用'},
]
}
},
methods:{
toggleSelection() {
this.$refs.multipleTable.clearSelection();
},
handleSelectionChange(val) {
this.multipleSelection = val;
}
}
}
</script>
<style scoped>
.ElementProject{
margin: 50px 500px;
}
</style>
ref:为一个元素或子组件的应用
组件中定义的所有ref都会放在当前组件的$ref属性中
8、v-model
增加子组件Login.vue,使用单向绑定方式(设置model数据默认值或者修改model数据值)并在父组件中引入和使用:
<template>
<div class="login">
<form method="post" action="">
<label for="username">用户名:</label>
<input type="text" id="username"
placeholder="请输入用户名"
:username="username">
<br>
<label for="password">密 码:</label>
<input type="password"
id="password"
placeholder="请输入密码"
:password="password">
</form>
</div>
</template>
<script>
export default {
name: "Login",
data(){
return{
username:'snow',
password:'123456'
}
}
}
</script>
<style scoped>
input{
margin:10px auto;
font-size: medium;
}
label{
margin-right: 10px;
}
</style>
页面渲染结果:

从页面渲染结果来看,model的数据并没有显示在页面上。
输入框输入值,发现model中的数据也没有进行更新:

发现单向绑定不能满足要求,只能将model中的数据只能传给绑定的属性
使用v-model方式绑定
<template>
<div class="login">
<form method="post" action="">
<label for="username">用户名:</label>
<input type="text" id="username"
placeholder="请输入用户名"
v-model= username>
<br>
<label for="password">密 码:</label>
<input type="password"
id="password"
placeholder="请输入密码"
v-model=password>
</form>
</div>
</template>
<script>
export default {
name: "Login",
data(){
return{
username:'snow',
password:'123456'
}
}
}
</script>
<style scoped>
input{
margin:10px auto;
font-size: medium;
}
label{
margin-right: 10px;
}
</style>
页面渲染结果达到预期:

v-model为双向绑定,既可以将Model中的数据传给绑定的属性,也可以 将用户输入的内容传给Model来处理
注意:v-model只能在input,textarea,selcet上使用
自己写的ui不是很美观,在element ui中有对应的form,可以选择合适的进行使用
9、vue生命周期
参考文档:https://www.jianshu.com/p/672e967e201c
Vue实例有一个完整的生命周期,也就是说从开始创建、初始化数据、编译模板、挂在DOM、渲染-更新-渲染、卸载等一系列过程,我们成为Vue 实例的生命周期,钩子就是在某个阶段给你一个做某些处理的机会。


beforeCreate( 创建前 )
在实例初始化之后,数据观测和事件配置之前被调用,此时组件的选项对象还未创建,el 和 data 并未初始化,因此无法访问methods, data, computed等上的方法和数据。
created ( 创建后 )
实例已经创建完成之后被调用,在这一步,实例已完成以下配置:数据观测、属性和方法的运算,watch/event事件回调,完成了data 数据的初始化,el没有。 然而,挂在阶段还没有开始, $el属性目前不可见,这是一个常用的生命周期,因为你可以调用methods中的方法,改变data中的数据,并且修改可以通过vue的响应式绑定体现在页面上,,获取computed中的计算属性等等,通常我们可以在这里对实例进行预处理,也有一些童鞋喜欢在这里发ajax请求,值得注意的是,这个周期中是没有什么方法来对实例化过程进行拦截的,因此假如有某些数据必须获取才允许进入页面的话,并不适合在这个方法发请求,建议在组件路由钩子beforeRouteEnter中完成
beforeMount
挂在开始之前被调用,相关的render函数首次被调用(虚拟DOM),实例已完成以下的配置: 编译模板,把data里面的数据和模板生成html,完成了el和data 初始化,注意此时还没有挂在html到页面上。
mounted
挂在完成,也就是模板中的HTML渲染到HTML页面中,此时一般可以做一些ajax操作,mounted只会执行一次。
beforeUpdata (更新前)
在数据更新之前被调用,发生在虚拟DOM重新渲染和打补丁之前,可以在该钩子中进一步地更改状态,不会触发附加地重渲染过程
updated (更新后)
在由于数据更改导致地虚拟DOM重新渲染和打补丁只会调用,调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作,然后在大多是情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环,该钩子在服务器端渲染期间不被调用
beforeDestrioy (销毁前)
在实例销毁之前调用,实例仍然完全可用,
- 这一步还可以用this来获取实例,
- 一般在这一步做一些重置的操作,比如清除掉组件中的定时器 和 监听的dom事件
destroyed(销毁后)
在实例销毁之后调用,调用后,所以的事件监听器会被移出,所有的子实例也会被销毁,该钩子在服务器端渲染期间不被调用

浙公网安备 33010602011771号