1、模板语法
一般用{{ }}两个括号中间填入自己设定的值,里面不能用不确定的值(比如if),但是可以用三目运算符,如果需要插入网站的话需要加一个属性,比如<p v-html="xxxx"><p>
1.1 模板引用
关键字:ref
通过在属性中加入 ref="" 就可以通过dom方式获取(this.$refs."属性名称"),具体代码如下所示
<template>
<h1>------------------------------------------------------------------------------</h1>
<p ref="test">{{ message }}</p>
<button @click="UpdateDom"></button>
<h1>------------------------------------------------------------------------------</h1>
</template>
<script>
export default
{
data()
{
return{
message:"嘿嘿嘿"
}
},
methods:{
UpdateDom(){
this.$refs.test.innerHTML="哈哈哈";
}
}
}
</script>
2、绑定
2.1 属性绑定
属性绑定一般常用的命令是v-bind
绑定单个命令时可以省略掉v-bind,比如
<div v-bind:id="dynamicID" >测试</div>
<div :id="dynamicID" >测试</div>
但是在绑定一个对象中具有多个元素时,应该使用
<template>
<div v-bind="objets"></div>
</template>
<script>
export default
{
data()
{
return{
objets:{
dynamicID:"22",
dynamicClass:"muchen",
}
}
}
}
</script>
有时对于按钮,如果想让它点击功能不可用,也可以通过属性绑定的方式去修改它的‘disabled’属性
完整代码如下:
<template>
<div v-bind:id="dynamicID" :class="dynamicClass" :title="dynamicTitle">测试</div>
<button :disabled="iduse">button</button>
<div v-bind="objets"></div>
</template>
<script>
export default
{
data()
{
return{
dynamicID:"22",
dynamicClass:"muchen",
dynamicTitle:null,
iduse:false,
//绑定多个值
objets:{
dynamicID:"22",
dynamicClass:"muchen",
}
}
}
}
</script>
2.2 Class绑定
使用v-bind进行绑定,vue使得class内可以内嵌对象以及数组
例如:
<template>
<h1>------------------------------------------------------------------------------</h1>
<p :class="{'Active':isActive}">Class测试1</p>
<p :class="[ArrActive,Arrisbig]">Class测试2</p>
<p :class="[isActive?'Active isBig':'']">Class测试3</p>
<h1>------------------------------------------------------------------------------</h1>
</template>
<script>
export default
{
data()
{
return{
isActive:false,
isBig:true,
ArrActive:"Active",
Arrisbig:"isBig",
}
}
}
</script>
<style>
h1{
color:brown;
}
.Active{
color: blue;
}
.isBig{
font-size: 50px;
}
</style>
通过{}可以添加属性名,设定’isActive‘是否为true来决定这个class是否显示,也可以通过return{}下直接通过键值对绑定属性,这样在:class后面可以直接引用这个key值
2.3 Style绑定
使用v-bind进行绑定,正常来说都使用Class来设定样式
<template>
<h1>------------------------------------------------------------------------------</h1>
<p :style="{color:colorr,fontSize:sizr}">style测试1</p>
<h1>------------------------------------------------------------------------------</h1>
</template>
<script>
export default
{
data()
{
return{
colorr:"red",
sizr:"50px",
}
}
}
2.4 表单输入绑定
关键词 v-model
修饰符: 修改之前是在事件后更新数据,加上.lazy 在change后更新数据(比如input是边写边更新,修改之后是输入完一起更新)
<template>
<h1>------------------------------------------------------------------------------</h1>
<input type="text" v-model="message">
<p>{{ message }}</p>
<h1>------------------------------------------------------------------------------</h1>
</template>
<script>
export default
{
data()
{
return{
message:""
}
},
}
}
</script>
3.渲染
3.1条件渲染
v-if v-else v-show
<template>
<h3>条件渲染</h3>
<p v-if="test1">test1能被看见</p>
<p v-else>test1不能被看见</p>
<p v-show="test2">v-show的可视化</p>
</template>
<script>
export default{
data(){
return{
test1:true,
test2:true,
}
}
}
</script>
v-if v-else 属于在第一次编译如果遇到false则不会渲染,属于需要就渲染不需要就销毁
v-show是首次一定会渲染,后面不会销毁指挥修改可视化的属性
3.2 列表渲染
v-for
常用写法:
<div v-for="num in objets" :key="num">{{num}}</div>
<p v-for="(value,key,index) in tests" :key="key">{{ value }}-{{ key }}-{{ index }}</p>
<template>
<h1>测试</h1>
<div v-for="num in objets" :key="num">
<p >{{ num.id }}</p>
<p>{{ num.title }}</p>
</div>
<p v-for="(value,key,index) in tests" :key="key">{{ value }}-{{ key }}-{{ index }}</p>
</template>
<script>
export default{
data(){
return{
maths:["1","2","3"],
objets:[
{
"id":11,
"title":"muchen"
},
{
"id":22,
"title":"aboo",
}
],
tests:{
id:2,
titile:"test"
}}
}
}
</script>
注意:不要用index来作为v-for的Key值,因为序号总是容易变化,应该用数据的唯一索引,例如数据库的ID,它总是不变的
4.事件处理
4.1添加事件
v-on:
@ (更方便)
<button v-on:click="addAction">测试按钮</button>
<button @click="addAction">测试按钮</button>
上面两行代码效果一样,完整代码如下:
<template>
<button v-on:click="addAction">测试按钮</button>
<p>{{ count }}</p>
</template>
<script>
export default
{
data()
{
return{
count:0
}
},
methods:{
addAction()
{
this.count++;
}
}
}
</script>
4.2 事件传参
如果html中,例如@click="addAction()没有传参,则可以在方法定义中addAction(e){},获取到事件e的相关参数,但如果需要传参,则需要改为addAction(‘XXX‘,$event),在方法定义中相对改为addAction(xxx,e){}
4.3 事件修饰符
5.数组变化侦测
Vue 能够侦听响应式数组的变更方法,并在它们被调用时触发相关的更新。这些变更方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
个人理解:原来的内存地址直接修改数组(可以直接更改html上面的UI),而不是创建一个新的数组对UI无影响。
原文链接:数组变化侦测
6.侦听器:
关键词:watch
与data methods computed 同等级,接收data内改变的数值
<template>
<h1>------------------------------------------------------------------------------</h1>
<button @click="UpdateData"></button>
<p>{{ message }}</p>
<h1>------------------------------------------------------------------------------</h1>
</template>
<script>
export default
{
data()
{
return{
message:"old_Message"
}
},
methods:{
UpdateData(){
this.message="new_messqge";
}
},
watch:{
message(newValue,oldValue){
console.log(newValue,oldValue);
}
}
}
</script>
7.多个组件交互
7.1 组件之间传递数据(父传子)
关键字:props
可以传递任何类型的数据
首先需要明确概念,被注入的组件是父组件,注入的组件是子组件,注入成功之后
在父组件中:可以通过引用子组件的方式"<Child :titile="">"来声明后面需要传递给子组件的对象,在声明时既可以通过v-bind:的方式来绑定data来达到动态的目的,也可以直接通过"test=“xxxx”的方式来只绑定一个字符串。
在子组件中:需要增加
export default {
props:["xxx"]
}
其中xxx为在父组件中生命的属性,此种方式引用之后即可以在子组件中使用传过来的数据 。
完整代码如下:
父组件:
<template>
<div>
<h1>------------------------------------------------------------------------------</h1>
<p ref="test">{{ message }}</p>
<Child :title="message" pro1="这个是传递的字符串"></Child>
<h1>------------------------------------------------------------------------------</h1>
</div>
</template>
<script>
import Child from "./Child.vue"
export default
{
data()
{
return{
message:"嘿嘿嘿"
}
},
components:{
Child
}
}
</script>
子组件:
<template>
<div>
<h1>子进程</h1>
<p>{{title}}</p>
<p>{{pro1}}</p>
</div>
</template>
<script>
export default {
props:["title","pro1"]
}
</script>
子组件也可以通过props将数据传回给父组件,只需要传递函数,父组件定义有参数方法,传递给子组件进行传参调用,此时父组件就会接收到来自子组件的方法调用,效果等同于事件
7.2 组件传递的数据校验
如果不校验的话就是此种方式编写props:
props:["title","pro1"]
设置为校验的话就是:
props:{
test:{
type:Number,
require:true, //设置是否为必须项
},
title:{
type:String,
default:"没传过来", //设置如果没传过来的默认值
},
arr: {
type:Array,
default(){ //如果是数组或者对象的默认值需要用方法返回
return []
}
}
}
注意:props是只读的,不能进行传入数据的修改
7.3 组件事件(子传父)
关键字:this.$emit
通过组件事件,可以从子组件中将数据传递给父组件
子组件:
<template>
<div>
<h1>子进程</h1>
<button @click="SendFather">向父组件发送信息</button>
</div>
</template>
<script>
export default {
data(){
return{
message:"子组件传递的信息",
}
},
methods:{
SendFather(){
this.$emit("ResData",this.message);
//第一个参数是寻路,会找到父组件中子组件标签中定义的同名属性 ,第二个参数是传递的数值
}
},
}
</script>
父组件:
<template>
<div>
<h1>------------------------------------------------------------------------------</h1>
<p ref="test">{{ message }}</p>
<Child @ResData="receiveDate"></Child>
//在父组件中的子组件标签中通过@来让子组件传入的信息找到地址,然后=方法名称,进行事件调用
<h1>------------------------------------------------------------------------------</h1>
</div>
</template>
<script>
import Child from "./Child.vue"
export default
{
methods:{
receiveDate(data){
this.message = data;
}
},
data()
{
return{
message:"嘿嘿嘿",
test:22
}
},
components:{
Child
}
}
</script>
7.4 插槽
7.4.1 初始化
相比于prop emit是在父子组件之中传递数据,插槽slot是将父组件的模板内容传递给子组件
具体步骤:
1.导入子组件
2.在子组件的标签中编写模板内容
3.在子组件中插入<slot></slot>标签
父组件:
<template>
<div>
<h1>------------------------------------------------------------------------------</h1>
<Child>
<h1>插槽示例</h1>
<p>{{message}}</p>
</Child>
<h1>------------------------------------------------------------------------------</h1>
</div>
</template>
子组件:
<template>
<div>
<h1>现在下面显示子组件</h1>
<slot></slot>
</div>
</template>
<script>
默认内容,在子组件 <slot>我是默认内容</slot>中添加内容就可以作为默认内容,如果父组件没有给子组件传值的话就可以使用默认内容显示.
7.4.2 具名插槽
在父组件声明插槽内容的时候可以通过
<template v-slot:name1>
或者
<template #name2>
的方式来给插槽内容命名,方便在子组件中引用不同的插槽内容,这样在子组件中只需使用
<slot name="name1"></slot>
即可显示对应的插槽内容。
7.4.3 插槽回传数据,同时显示
子组件:
<template>
<div>
<h1>现在下面显示子组件</h1>
<slot name="name1" :msg="message">我是默认内容</slot>
<p>--------------------------------------------</p>
<slot name="name2"></slot>
</div>
</template>
<script>
export default {
data(){
return{
message:"hahahah",
}
}
}
</script>
父组件:
<template>
<div>
<h1>------------------------------------------------------------------------------</h1>
<Child>
<template v-slot:name1="slotprops">
<h1>插槽示例1-{{slotprops.msg}}</h1>
</template>
<template #name2>
<h1>插槽示例2</h1>
</template>
</Child>
<h1>------------------------------------------------------------------------------</h1>
</div>
</template>
8.组件生命周期
生命周期函数:
创建期:beforeCreate created
挂载期:beforeMount mounted
更新期:beforeUpdate updated
销毁期:beforeUnmount unmounted
9.动态组件
template>
<div>
<!--<MapVue></MapVue>-->
<component :is="component"></component> //将原有各种组件的标签改为component标签
<button @click="changeTab" >测试按钮</button>
</div>
</template>
<script >
import HelloWorld from './components/HelloWorld.vue';
import IfDemo from "@/components/If-demo.vue";
//import MapVue from './components/MapStudy.vue'
export default {
data(){
return{
component:"HelloWorld",
}
},
components:{
HelloWorld,
IfDemo
},
methods:{
changeTab(){
this.component = this.component == "HelloWorld"?"IfDemo":"HelloWorld";
}
}
}
</script>
<keep-alive>标签可以强制组件存活
10.注入依赖
当跟组件向多级后的子组件传递数据时,往往需要跨越很多个组件,这时可以使用注入依赖功能
在根组件中声明
provide{
参数:"xxxx"
}
provide(){
return{
参数:this.xxx //此种方法是为了传递data下的数据
}
}
在需要被注入的组件中调用:
<p>{{参数}}</p>
inject:["参数"]
11.路由
11.1 路由基础配置
路由安装:
npm install --save vue-router
注意:有时候可能因为node_cache的权限没有配置好而导致无法安装
简单一点的解决方法就是将文件的权限全部打开。
新建一个router的文件夹,并新建index.js
import {createRouter,createWebHashHistory} from "vue-router"
import home from "../views/home"
const routes = [
{
path:'/',
name:'home',
component:home
},
{
path:'/about',
name:'about',
component:()=>import('../views/about.vue') //这样做为了异步加载,不需要初始化全部引用
},
]
const router = createRouter({
history:createWebHashHistory(),
routes
})
export default router;
然后需要在main.js文件中引入ruter
import { createApp } from 'vue'
import App from './App.vue'
import router from "./router/index"
const app = createApp(App)
app.use(router)
app.mount('#app')
最后在App.vue中将router显示出来
<router-link to="/">首页</router-link>| //链接样式
<router-link to="/about">关于</router-link>
<router-view></router-view> //主要显示的界面
11.2 路由传递参数
在最初创建项目的时候,如果勾选创建路由,则可以省掉11.1的步骤,
当需要路由跳转携带参数key时,可以在创建路由时将path属性后面新增 /:
{
path:'/about/intro/:name',
name:'intro',
component:()=>import('../views/intro.vue')
}
在App.vue显示界面新增
<template>
<div>
<router-link to="/">首页</router-link>|
<router-link to="/about">关于</router-link>
<ul>
//通过在link后面新增/xxx可以定义自己的参数
<li><router-link to="/about/intro/详情A">详情A</router-link></li>
<li><router-link to="/about/intro/详情B">详情B</router-link></li>
<li><router-link to="/about/intro/详情C">详情C</router-link></li>
</ul>
<router-view></router-view>
</div>
</template>
然后在路由到的vue界面通过
<p>{{ $route.params.name }}</p>
可以获得传入的参数并显示
11.3 嵌套路由配置
如果需要点击一个路由跳转界面,新界面中嵌套其他路由,就需要配置嵌套路由(注意嵌套内的path不需要加/)
const routes = [
{
path:'/',
name:'home',
component:home,
redirect:"/A", //添加重定向是为了每次自动打开路径A
children:[
{
path:'A', //注意嵌套内的path不需要加/
component:()=>import('../views/HomeViews/homeA.vue'),
},
{
path:'B',
component:()=>import('../views/HomeViews/HomeB.vue'),
}
]
},
{
path:'/about',
name:'about',
component:()=>import('../views/about.vue')
},
{
path:'/about/intro/:name',
name:'intro',
component:()=>import('../views/intro.vue')
}
]
添加完成后需要在被嵌套的vue中增加<router-view></router-view>来进行显示,达到嵌套的效果,如
<template>
<div>
<h1>Home页面</h1>
<router-link to="/A">内容A</router-link>|
<router-link to="/B">内容B</router-link>
<router-view></router-view>
</div>
</template>