Vue2.x的基本使用
基本使用
- 引入 (可下载Vue.js 也可在线引用)
- 创建Vue实例
<div id="app">
<!-- 插值表达式:1.添加数据 2.进行计算 3.字符串拼接 -->
{{msg}}
</div>
<script>
var app = new Vue({
el:"#app" //所挂载的元素,只能是双标签元素
data:{ //存放数据,模型数据
msg:"Hello Vue"
}
})
</script>
模板语法(指令)
1.v-cloak:解决插值表达式页面闪动问题
原理:先display:none;隐藏元素 创建Vue实例后替换元素
1.<style>
[v-clock]{
display: none;
}
</style>
2.<div id="app">
<div v-cloak>{{ meg }}</div>
</div>
3.<script>
var app = new Vue({
el:"#app",
data:{
meg:"hello Vue"
}
})
</script>
-
数据绑定 v-test :文本填充
v-html:文本填充,解析HTML标签
<div id="app"> <div v-text="msg"></div> <div v-html="div"></div> </div>
-
双向数据绑定 v-model,一般用在input标签
<div id="app">
<input v-model="msg" type="text" >
<div v-text="msg"></div>
</div>
- 事件绑定 v-on:事件名=“处理事件的方法名” 简写为 @事件名 = “方法名”
<div id="app">
<button @click="add" @keyup.enter = "add">+</button>
<!-- 按键修饰符 :事件keyup -->
<!-- 特殊: 回车 v-on:keyup.enter
删除: keyup.delete
-->
<div v-text="num"></div>
<button @click.stop="sub(2)">-</button>
<!-- 事件修饰符 -->
<!-- @事件.stop:阻止事件冒泡-->
<!-- @事件.prevent:阻止默认事件-->
</div>
<script>
var app = new Vue({
el:"#app",
data:{
msg:"hello Vue",
num:0
},
methods: {
add:function(){
this.num++ //this 就是app对象
},
sub:function(data){ //传参
this.num=this.num-data
}
},
})
</script>
- 条件渲染
v-if v-else-if v-else 原理:dom树渲染
v-show 原理是 display :none;
<div id="app">
<h2 v-if="score>=90">优秀</h2>
<h2 v-else-if="score>=60 && score<90"> 良好</h2>
<h2 v-else>不及格</h2>
<h1 v-show="score == 70">ok</h1>
</div>
<script>
var app = new Vue({
el:"#app",
data:{
score:70
}
})
</script>
- 动态属性处理 v-bind
<!-- 样式 -->
<style>
.one{
width: 160px;
height: 120px;
border: green 2px solid;
}
.bg{
background-color: hotpink;
width: 160px;
height: 120px;
}
</style>
<!-- 标签-->
<div id="app">
<img v-bind:src="src" alt="cat" title="猫">
<!-- 样式绑定 v-bind 简写 : -->
<img :src="src" :class="{one:flag}">
<!-- 多样式 -->
<div :class="{one:flag,bg:flag}"></div>
<!-- 表达式方式 三元运算符 -->
<div :class="flag ? 'one':'bg'"></div>
</div>
<!--Vue -->
<script>
var app = new Vue({
el:"#app",
data:{
src:"./cat.jpg",
flag:true
}
})
</script>
- 循环 v-for = (item,index) in list :key=“index”
key:区分不同元素,提高性能
<div id="app">
<div class="main" >
<div v-for="(item, index) in list" :key="index">
<!-- 属性取值 -->
<img class="box" :src="item.src" alt="">
<p>{{ index }}</p>
<!-- index 数组索引值 -->
</div>
</div>
</div>
<script>
var app = new Vue({
el:"#app",
data:{
src:"./3.jpg",
list:[{src:"./3.jpg"},
{src:"./2.jpg"},
{src:"./1.jpg"}]
},
})
</script>
methids异步调用解决方法
- 在外面 var that = this
- 箭头函数
var app = new Vue({
el:"#app",
data:{
msg:"I LOVE YOU BABY~~~"
},
methods: {
start:function(){
setInterval(()=>{
var left = this.msg.substring()
},1000)
}
},
})
VUE特性
计算属性
-
computed
🔑 获取的后台数据,我们还要进行处理;缓存机制:只能基于data的数据。
<script>
var app = new Vue({
el:"#app",
data:{
goods:[
{id:1,price:1900,name:"手机"},
{id:2,price:1200,name:"手表"},
{id:3,price:4100,name:"电脑"},
]
},
computed:{
// 创建计算属性
smg:function(){
var sum = 0
for(let item of this.goods){
sum = sum + item.price
}
return sum
}
}
})
</script>
理解:setter 和 getter
<body>
<div id="app">
{{ smg }}
{{ getSmg() }}
</div>
</body>
<script>
var app = new Vue({
el:"#app",
data:{
stname:"H",
edname:"J"
},
computed:{
// 创建计算属性
smg:{
set:function(data){//设置
console.log("111"+data)
this.edname = data
},
get:function(){ //获取
return this.stname+this.edname
}
}
},
//VUE内部处理后简写为
// computed:{
// smg:function(){
// return this.stname+this.edname
// }
// },
methods: {
getmsg:function(){
return this.stname+this.edname
}
},
})
</script>
computed 和methods的区别:computed vue内部做了缓存,如果值没有改变,就不会重新计算,直接展示缓存中的数据,而methods没有缓存机制
-
侦听器(watch)
🔑 数据一旦改变就通知侦听器中绑定的方法 ;数据变化时,执行异步操作,或者对开销较大的操作
<body>
<div id="app">
<input type="text" v-model="stname">
<input type="text" v-model="edname">
<h2>{{ fullname }}</h2>
</div>
</body>
<script>
var app = new Vue({
el:"#app",
data:{
stname:"He",
edname:"Jiang",
fullname:""
},
// 监听那个data,就用哪个data做watch属性,val:就是新改变的值
watch:{
stname:function(val){
this.fullname = val+" "+this.edname
},
edname:function(val){
this.fullname = this.stname +" " +val
}
}
})
</script>
过滤器
filters:对呈现前的数据进行一系列处理
<div id="app">
<!-- 首字母大写 -->
<input type="text" v-model="msg">
<!-- 2. 使用过滤器 -->
<h2>{{ msg | up }}</h2>
</div>
<script>
//1.全局创建 一个参数时,参数val就是使用过滤器的数据 msg
//多个参数时 第二个起都为过滤器参数
Vue.filter('up',function(val){
return val.charAt(0).toUpperCase() + val.slice(1)
})
var app = new Vue({
el:"#app",
data:{
msg:""
}
})
</script>
带参数过滤器
<div id="app">
<!-- 格式化日期:2021-3-2 -->
<h2>{{ date.time | formate("yyyy-MM-dd") }}</h2>
</div>
<script>
//全局创建 参数val就是使用过滤器的数据 msg
Vue.filter('formate',function(val,arg){
if(arg=="yyyy-MM-dd"){
return `${val.getFullYear()}-${val.getMonth()+1}-${val.getDate()}`
}
})
var app = new Vue({
el:"#app",
data:{
date:{
time:new Date()
}
},
filters:{
}
})
</script>
局部过滤器
var app = new Vue({
el:"#app",
data:{
date:{
time:new Date()
}
},
filters:{
formate2:function(val,arg){
if(arg=="yyyy-MM-dd"){
return `${val.getFullYear()}-${val.getMonth()+1}-${val.getDate()}`
}
}
}
})
组件化
🔑组件化思想:组件数
基本实例
<div id="app">
<!-- 3.使用 -->
</div>
<script>
// 1.全局注册
Vue.component("lun-bo",{
data:function(){
return {
msg:"轮播"
}
},
// 2.模板
template:`<h2>{{msg}}</h2>`
})
var app = new Vue({
el:"#app",
data:{
},
})
</script>
基本使用注意事项:
Vue.compnent('组件名'),data:存放组件数据,template:模板 (推荐用es6模板字符串)
- 模板必须挂载在某个Vue实例范围
- 组件中的data是一个函数
- template模板必须是父子结构
- 组件命名方式 :compnent-name 或者 compnentName(CLI中没问题)
局部组件
<div id="app">
<my-son></my-son>
</div>
<script>
var mySon = {
data:function(){
return{
}
},
template:`<div>my son</div>`
}
var app = new Vue({
el:"#app",
data:{
},
// 1.局部创建
components:{
'my-son':mySon
}
})
</script>
组件通讯
- 父组件向子组件传递数据
<!-- 父组件模板 -->
<div id="app">
<!-- 3.发送父组件信息 -->
<son :getmsg="msg" :getmsg2='msg2'></son>
</div>
<!-- 子组件模板 -->
<template id="son">
<div>
<h2>son1</h2>
<!--5. 显示在子组件中 -->
<h2>{{ getmsg+getmsg2 }}</h2>
</div>
</template>
<script>
// 父组件向子组件传值 props:[] []里面的字符串是个变量
// 子组件中
var son = {
data() {
return {
}
},
template:`#son`,
// props:['getmsg','getmsg2'] 4.接收父组件数据,
//开发中 多使用对象 1.加限制 2.加默认值
props:{
getmsg:String,
getmsg2:{
type:Number,//限定传值的类型
default(){ //父组件没有传递数据时的默认值
return 'no data'
},
required: true , //此时必须绑定属性
}
}
}
// 1.父组件就是根组件
var app = new Vue({
el:"#app",
data:{
msg:"you are my son",
msg2:2
},
components:{
son //2.创建子组件
}
})
</script>
- 子组件向父组件传值
使用$emit自定义方法
<body>
<!-- 父组件模板 -->
<div id="app">
<!-- 3. 父组件监听自定义事件 V-on -->
<son @getson='getData'></son>
{{msg}}
</div>
<!-- 子组件模板 -->
<template id="son">
<div>
<button v-for="(item, index) in classgoods" :key="index" @click='getitem(item)'>
{{item.name}}
</button>
</div>
</template>
</body>
<script>
var son = {
data() {
return {
classgoods:[
{id:1,name:"TV"},
{id:2,name:"TV2"},
{id:3,name:"TV3"},
{id:4,name:"TV4"},
]
}
},
template:`#son` ,
methods: {
//1.获取子组件数据
getitem(item){
var datas = item
//2.创建自定义事件,this.$emit("事件名",事件传的数据)
this.$emit('getson',datas)
}
},
}
//父组件
var app = new Vue({
el:"#app",
data:{
msg:"you are my son",
},
//创建局部子组件
components:{
son
},
// 4.接收自定义事件并处理
methods: {
getData(item){
this.msg = 'ok'
console.log(item);
}
},
})
</script>
- 非父子组件传值
<body>
<div id="app">
<copone></copone>
<coptwo></coptwo>
</div>
<template id="copone">
<div>
<h2>one:{{ value }}</h2>
<button @click = 'add'>点击</button>
</div>
</template>
<template id="coptwo">
<div>
<h2>two:{{ value }}</h2>
</div>
</template>
<script>
// 1.创建事件中心
var event = new Vue()
// 组件一
var copone ={
data() {
return {
value:1
}
},
methods: {
// 2.在事件中心创建自定义事件
add(){
event.$emit('gettwo',this.value)
}
},
template:`#copone`,
}
// 组件二
var coptwo ={
data() {
return {
value:2
}
},
template:`#coptwo`,
// 3.接收组件一传递的数据,通过 event.$on('共用事件名',callback)
mounted() {
event.$on('gettwo',(val)=>{
this.value = val+this.value
})
},
}
var app = new Vue({
el:"#app",
data:{
},
components:{
copone,
coptwo
}
})
</script>
组件插槽
- 基本使用
<slot></slot>
<div id="app">
<!-- 双标签内地内容直接填充到组件slot标签位置 -->
<copone>6666</copone>
</div>
<template id="copone">
<div>
<!-- 如果组件中没写666,将显示slot标签里的默认值555,写了就显示666 -->
<h2>one:{{ value }}<slot>555</slot></h2>
</div>
</template>
- 具名插槽
<div id="app">
<copone>
<p>内容</p>
<p>内容</p>
<p slot="header">头部</p>
<p slot="footer">底部</p>
</copone>
</div>
<template id="copone">
<div>
<!-- 根据名称匹配内容 -->
<header>
<slot name="header"></slot>
</header>
<!-- 没有名字就匹配没有名的内容 -->
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
- 作用域插槽
🔑父组件通过插槽替换子组件的标签,但是内容是子组件的
<body>
<!-- 父组件 -->
<div id="app">
<one></one>
<one>
<template slot-scope="data">
<span>{{data.data.join('-')}}</span>
</template>
</one>
</div>
<!-- 子组件 -->
<template id="one">
<div>
<slot :data='language'>
<ul>
<li v-for="(item, index) in language" :key="index">{{ item }}</li>
</ul>
</slot>
</div>
</template>
<script>
var one ={
data() {
return {
language:['js','c++','java','Go']
}
},
template:`#one`,
}
var app = new Vue({
el:"#app",
data:{
},
components:{
one
}
})
</script>
Vue-Router
🔑 本质就是对应关系
后端路由(早起开发):根据用户的不同url请求,服务器返回不同的内容,本质:url请求地址与服务器资源之间的对应关系
前端路由:根据不同的用户事件,显示不同页面内容,本质:用户事件与事件处理函数之间的对应关系
SPA:单页面应用程序:基于前端路由,内容变化通过ajax局部更新
基本使用
- 引入
- 添加路由链接
<router-link to="/zhuye">主页</router-link>
- 添加路由填位
<router-view> </router-view>
- 路由定义
- 创建路由实例对象匹配路由规则
- 挂载路由实例
<body>
<div id="app">
<!--2.添加路由链接,其中router-link 相当a标签的hash地址 to属性是对应的地址 -->
<router-link to="/zhuye">主页</router-link>
<router-link to="/yule">娱乐</router-link>
<!-- 3.创建占位符 router-view-->
<router-view> </router-view>
</div>
</body>
<!-- 1.引入 -->
<script src="./vue.js"></script>
<script src="./router.js"></script>
<script>
// 4.定义组件
var zhuye={template:`<h2>主页</h2>`}
var yule={template:`<h2>娱乐</h2>`}
// 5. 创建路由实例对象和匹配路由规则
const router = new VueRouter({
// routes是路由规则是一对象数组,其中path是路由地址,component是展示的组件
routes: [
{path:'/zhuye',component:zhuye},
{path:'/yule',component:yule},
]
})
var app = new Vue({
el:"#app",
data:{},
// 挂载路由实例
router
})
</script>
路由重定向
作用:用户访问a地址时,强制让用户访问b地址
{path:'/',redirect:"/zhuye"},
路由嵌套
<body>
<div id="app">
<!--2.添加路由链接,其中router-link 相当a标签的hash地址 -->
<router-link to="/zhuye">主页</router-link>
<router-link to="/yule">娱乐</router-link>
<!-- 3.创建占位符 router-view-->
<router-view> </router-view>
</div>
<template id="yule">
<div>
<h2>娱乐</h2>
<h4>
<!-- b2.添加路由链接 -->
<router-link to="/p1">p1</router-link>
<router-link to="/p2">p2</router-link>
<!-- b3.创建占位符 -->
<router-view></router-view>
</h4>
</div>
</template>
</body>
<!-- 1.引入 -->
<script src="./vue.js"></script>
<script src="./router.js"></script>
<script>
// 4.定义组件
var zhuye={template:`<h2>主页</h2>`}
var yule={template:`#yule`}
// b4.定义组件
var p1={template:`<h2>p1</h2>`}
var p2={template:`<h2>p2</h2>`}
// 5. 创建路由实例对象和匹配路由规则
const router = new VueRouter({
// routes是路由规则 其中path是路由地址,component是展示的组件
routes: [
{path:'/',redirect:"/zhuye"},
{path:'/zhuye',component:zhuye},
{path:'/yule',component:yule,
// b5.在对应的父组件中添加children属性
children:[
{path:'/p1',component:p1},
{path:'/p2',component:p2}
]
},
]
})
var app = new Vue({
el:"#app",
data:{},
// 挂载路由实例
router
})
</script>
编程式导航
router-link
是声明式导航,而编程式导航放在js中的常用this.$router.push('地址')
,另外this.$router.go(1或者-1)
表示前进和后退 ,后退很常用(-1)