02、Vue基础详解

环境准备

1、安装node.js,为了使用npm

2、装完后,cmd进入控制台,查看node版本号node -v,查看npm版本号npm -v

3、查看path环境变量,cmd进入控制台,输入path查看是否有node字样,没问题进入下一步。

 

4、安装git,为了快捷地开发

5、装完之后,在需要开发的文件夹里面右击,选择Git Bash Here

 

6、由于npm源在国外速度慢,可以选择换源,或者使用淘宝镜像工具

7、安装淘宝npm镜像,可以使用cnpm,代替npm

npm install -g cnpm --registry=https://registry.npm.taobao.org

 

8、安装vue(其中的npm命令可以适当换成cnpm)

//全局安装vue-cli
npm install --global vue-cli

//创建一个基于webpack模板的新项目
vue init webpack my-project
//其他选项都可以直接回车或输入N回车,在vue-router的时候,输入Y回车
//当看见All packages installed,就完成了
//安装依赖包 cd my-project npm install npm run dev

 9、项目进行中时不要关闭git,若关闭了重新打开:cd my-project  ,npm run dev 即可

 

项目的创建

 1、在src目录下面创建自己的项目文件夹,如bb

 2、在该项目下面创建视图文件,xxx.vue

<template>
  <p>Hello World</p>
</template>

 3、设置路由,src目录下的router下的index.js,如:

import HelloWorld from '@/components/HelloWorld' /*当前@表示src目录*/
import xiangmu from '@/xiangmu/index.vue' /*第二种引入方式*/

export default new Router({
  routes: [{
      path: '/', //当地址栏输入/的时候,找到下面component的地址
      name: 'HelloWorld', //按照需求给这个路由命名
      component: HelloWorld //地址栏
    }, //记得两个路由之间要加上逗号
    {
      path: '/xiangmu',
      name: 'xiangmu',
      // component: require('@/xiangmu/index.vue') //第一种引入方式,这种方式有些版本不支持
      component: xiangmu //第二种方式,全通用
    }
  ]
})

 

 4、去掉默认大logo,src目录下App.vue,删除开头的的<img src="./assets/logo.png">标签,完成

 5、浏览器访问  http://localhost:8080/#/  到达首页

  

生命周期

生命周期图片:https://cn.vuejs.org/images/lifecycle.png

组件生成的时候就会自动调用生命周期函数,具体生命周期的实现如:

<script>
    export default{
        data(){   //每个组件都会有data这个函数
            return{}
        },  //两函数之间要用逗号隔开

        beforeCreate(){
            console.log('beforeCreate 创建之前');
        },
        created(){
            console.log('created 已经创建');
        },
        beforeMount(){
            console.log('beforeMount 挂载之前');
        },
        mounted(){
            console.log('mounted 已经挂载');
        },
                
        //生命周期函数监听到才触发

        beforeUpdate(){
            console.log('beforeUpdate 更新之前');
        },
        updated(){
            console.log('updated 已经更新');
        },
        beforeDestroy(){
            console.log('beforeDestroy 销毁之前');
        },
        destroyed(){
            console.log('destroyed 已经销毁');
        }
    }
</script>

 

选项数据

data

  export default {
    data() {
      return {
        bb: 'hello', //两个变量之间用逗号分隔
        cc: 'how are you' //这里定义的是全局变量,视图模板可以用,后续函数也可以用
      }
    },
  //code... }

模板调用

<template>
  <div>  <!-- 如需调用不多个选项数据,那必须在该div里面 -->
    <div>{{bb}}</div> <!--模板调用只需要 {{变量名}} 即可-->
  <!-- code... -->
</div> </template>

 

computed

//接着上面的export default 里面定义
computed: {
//computed是一个对象,里面可以定义各种函数   hi() {     return this.bb + this.cc; //调用data里面的变量 = this.变量名   } },

模板调用

//接着在模板{{bb}}后面写
<div>{{hi}}</div>

 

methods

methods:{  //methods对象,里面定义各种行为性的函数
  hello(){
    alert("hello");
  }
}

模板调用

//接着在模板{{hi}}后面写
<div @click="hello()">打招呼</div>  //用@click给该div绑定点击事件
//函数不需要传参时,后面()可写可不写

 

模板语法 

data语法

//在模板输出data属性(选项数据说过)

//data定义
data() {
    return {
        bb: 'Hello!'
    }
}    
//模板输出
<div>{{bb}}</div>

 

嵌入js语法

//在模板上面嵌入js

//data定义
data() {
    return {
        bb: 'Hello!  ', //两个变量之间用逗号分隔
        cc: 'How are you?' //这里定义的是全局变量,视图模板可以用,后续函数也可以用
    }
}  
//模板输出
<div>{{bb + cc +bb}}</div>  //js的字符串拼接 

 

v-html

//动态地嵌入html标签

//data定义
data() {
    return {
        dt:"<p>html是动态的,更改data里面属性值,html就会变化</p>"
    }
}
//模板输出
<div v-html="dt"></div>    //将dt里面的html嵌入到这个div里面

 

v-bind

//动态的属性名

//data定义
data() {
    return {
        lei:"nihao"
    }
}
//模板输出
<div v-bind:class="lei"></div>    
//class = data里面lei的value 。
//更改lei的value,该div的class就会发生改变

 

v-on

//绑定事件函数

//methods定义
methods:{
    say(h){
        alert(h);
    }
}
//模板输出
<div v-on:click="say(hi)">点击触发函数</div>    
//缩写形式:@click="say(hi)"

 

过滤器

//对模板中的变量进行过滤,通过过滤器,改变原来的输出

//data定义
data() {
    return {
        bb:"你好!"
    }
},
//filters定义,filters里面定义各种过滤器函数
methods:{
    say(h){
        alert(h+h);
    }
}

//模板输出
<div> {{bb | say(bb)}} </div>    //输出结果:你好!你好!
//没有过滤器的时候直接输出bb变量,通过say(bb)过滤器,输出了两个bb变量

 

计算属性(computed)

//模板与js分离(过多的嵌套js会导致模板页面维护成本变高)

//js分离:模板文件容易维护

//data定义
data() {
    return {
        bb:"Hello!"
    }
},
//computed定义
computed: {
    fanzhuan(){
        return this.bb.split('').reverse().join('');
    }
}
//模板输出
<div> {{bb}} </div>

 

class动态绑定

第一种方式

//模板输出
<div v-bind:class="{'inner':isinner,'active':isactive}">第一种</div> 
<!-- 用了引号的是class名,没用引号的是变量 -->

//data定义
data(){
  return{ isinner:
true, //true表示该属性生效 isactive:false //false表示该属性不生效
  }
}

 

第二种方式(个人推荐)

//模板输出
<div :class="classObject">第二种</div>
<!-- :class 是 v-bind:class 的缩写 -->

//data定义
data(){
    return{
        isinner:false,    //false表示该属性不生效
        isactive:true  //true表示该属性生效
        //这里可以添加适当多的class
    }
}

 

第三种

//模板输出
<div :class="[aclass,bclass]">第三种</div>
<!-- 这里aclass和bclass指的是data的变量 -->

//data定义
data(){
    return{
        aclass:'abc',
        bclass:'def'
    }
}

 

 

style动态绑定

//不推荐style嵌套在html中

第一种

//模板输出
<div v-bind:style="{'color':color1,'background-color':color2}">style第一种</div>
<!-- 这里color1 和 color2指的是data的变量 -->

//data定义
data(){
    return{
        color1:'red',    //这里所有不加引号的都表示变量
        color2:'orange'  //加了引号的才表示字符串
    }
}

 

第二种

//模板输出
<div v-bind:style="styleObject">style第二种</div>
<!-- 所有样式都可以存储在styleObject里面 -->

//data定义
data(){
    return{
        styleObject:{
            'color':'yellow',
            'background-color':'green'
            /*这里可以添加各种样式*/
       }
    }
}

 

第三种

//模板输出
<div v-bind:style="[ziti,beijing]">style第三种</div>
<!-- 数组里面的ziti和beijing都是对象,每个对象都可以有多种样式 -->

//data定义
data(){
    return{
       ziti:{ //这里可以添加多种样式
         'color':'cyan'
       },
       beijing:{ //这里可以添加多种样式
         'background-color':'blue'
       }
    }
}

 

条件渲染

v-if

//当v-if的属性值为真就执行

//模板输出
<div v-if="bb">当bb为真,打印出if语句</div>

//data定义
data(){
    return{
        bb:true
    }
}

 

v-if  v-else

//若v-if条件为假,则执行v-else的内容

//模板输出
<div v-if="bb === 'A'">选项A</div><!-- 判断bb变量的值是否===A,是就执行 -->
<div v-else>其他选项</div>
<!-- 注意v-else后面不需要属性值 -->

//data定义
data(){
    return{
        bb:'A'    //这里控制if和else哪个输出
    }
}

 

v-if  v-else-if  v-else

//若条件不等于v-if v-else-if,则输出v-else

//模板输出
<div v-if="dd==='D'">dd==='D'输出这项</div>
<div v-else-if="dd==='E'">dd==='E'输出这项</div>
<div v-else>dd的变量非DE,输出这项</div>

//data定义
data(){
    return{
        dd:'E'    //这里控制输出语句
    }
}

 v-show

//跟v-if差不多一样,只要条件为真就输出

//模板输出
<div v-show="bb">当bb为真输出此语句</div>

//data定义
data(){
    return{
        bb:true
    }
}

 

 

列表渲染

v-for循环输出数组

//模板输出
<div>
<ul>
    <li v-for="child in parents">{{child}}</li>
    <!-- 其中parents为数组变量,child为数组中的每一项数据,child名字自定以 -->
</ul>
</div>

//data定义
data(){
    return{
        parents:[1,2,3,4,5]     //数组定义
    }
}

 

v-for循环数组,带下标

//模板输出
<div>
<ul>
    <li v-for="(child,index) in parents">{{child}}下标为{{index}}</li>
    <!-- 其中parents为数组变量,child为数组中的每一项数据,index为所对应的数组下标 -->
</ul>
</div>

//data定义
data(){
    return{
        parents:[1,2,3,4,5]     //数组定义
    }
}

 

v-for循环输出对象

//模板输出
<div>
<ul>
      <li v-for="(value,key) in obj">{{key}}:{{value}}</li>
      <!-- ()里面的值,第一个必须是属性值value,其次才是key,不然容易混乱 -->
      <!-- obj为对象变量-->
</ul>
</div>

//data定义
data(){
    return{
        obj:{
          'name':'张三',
          'age':'18岁',
          'sex':'female',
          'address':'beijing'
        }
    }
}

 

事件处理器

//v-on:click的缩写是@click

行内直接执行

//模板输出
<div>
    <div>
      <p>按钮被点击了{{a}}次</p>
      <button v-on:click="a+=1">计算点击次数</button>
    </div>
</div>
//data定义
data(){
    return{
       a:0
    }
}

 

行内调用函数(不传参)

//模板输出
<div>
    <div>
      <p>按钮被点击了{{a}}次</p>
      <button v-on:click="count">计算点击次数</button>
    </div>
</div>
//data定义
data(){
    return{
       a:0
    }
}
//methods定义
methods:{
    count(){
        this.a+=1;
    }
}

 

行内调用函数(传参)

//模板输出
<div>
    <div>
      <button v-on:click="hello('打招呼实参')">调用传参的函数</button>
    </div>
</div>
//methods定义
methods:{
    hello(a){
        alert(a);
    }
}

 默认冒泡机制(不阻止)

//点击会有两个弹框
//
模板输出 <div> <div @click="hello('第二次冒泡')"> <button v-on:click="hello('第一次冒泡')">调用传参的函数</button> </div> </div> //methods定义 methods:{ hello(a){ alert(a); } }

阻止冒泡

//只会出现一个弹框
//
模板输出 <div> <div @click="hello('第二次冒泡')"> <button v-on:click="hello('第一次冒泡')">调用传参的函数</button> //阻止冒泡只需在v-on:click或@click后面加上 .stop 即可 </div> </div> //methods定义 methods:{ hello(a){ alert(a); } }

 

自定义组件

首先

在src的components下面写好组件

<template>
   <div>{{time}}</div>
</template>

<script>
 export default{
   data(){
     return{
       time:100
     }
   },
   mounted(){  //组件被挂载之后执行
   var t = this;
   //把整个data函数存储路径复制过来,这样修改time值才会改变
   //原理是引用数据类型直接赋值的是路径,而不是数据本身,直接修改的话是修改源函数
   //若直接把this.time复制过来的话,复制的是基本数据类型,更改基本数据类型的数据起不到页面数据更改的效果
   setInterval(function(){
       t.time--; //这样更改才会改变data里面的源数据
     },1000)
   }
 }
</script>

接着

在需要组件的页面上

<template>
  <div>
    <div>引入components插件</div>
    //<!-- 第四步:在模板某个地方生成组件 -->
    <daoji> 若在第三步更换了名字,则标签就是该名字 </daoji>
  </div>
</template>

<script>
//第一步:像写路由一样,把页面引进来
import daoji from '@/components/daoji.vue'

  export default{
    data(){
      return{
      }
    },
    components:{  //第二步:把引进来的组件写进去才能生效
      daoji   //第三步:可以更换名字,如:'aa':daoji,这样也能生效
    }
  }
</script>

 

添加组件样式

1、在调用组件的页面,传参到components组件页

<jj col="red">这是生成组件的标签</jj>
    //将col属性传入components页

 

2、在components组件页,script部分接收参数

//这个对象定义在export default里面
props:{ //接收数据的对象 col:{ //发送过来的col,满足下面条件才生效 type:String, //要求接收到的是字符串,String首字母一定要大写 default:'black' //默认值,没接收到数据时用 } }

 

3、在components组件页,template部分定义样式

<template>
   <p :style="{color:col}">{{time}}</p>
</template>

 

添加组件行为

1、components组件页中,当倒计时结束时,触发函数end

if(t.time == 0){
t.$emit("end"); //当time=0时,触发end,end是自定义的名称
clearInterval(dd);
}

2、在调用页中定义@end,并指定页面中触发的函数ending

<jj @end="ending"> 这是生成组件的标签 </jj>

3、同时在调用页中定义ending函数

methods:{
    ending(){
        alert("结束了");
    }
}

 

DOM操作

首先在模板文件定义ref属性,如

<div ref="hhead"></div>   //ref属性值自定义

接着在mounted下操作DOM

mounted(){  //在mounted下,所有的DOM都是真实DOM
  this.$refs.hhead.innerText = '经过Dom操作出来的内容';
 //this . $refs . 模板ref属性值 . innerText等操作
}

 

 过渡效果

 //没有过渡效果时,隐藏和出现都是一闪而过

//template模板
<div id="demo">
    <button v-on:click="show = !show">    //点击按钮实现show的真假转换
        Toggle
    </button>
    <transition name="fade">    //vue框架的过渡标签,不定义样式不起效果
        <p v-if="show">hello</p>    //通过获取show的真假,实现p标签是否输出
    </transition>
</div>
//data函数定义
data() {
    return {
        show: true
    }
}

 

//添加过渡效果,实现淡入淡出

<style>
/*获取transition标签的name属性*/
.fade-leave,.fade-enter-to{ /*一般默认opacity都是1,这项可省略*/
  opacity:1;
}
.fade-leave-active,.fade-enter-active{
  transition: opacity .5s;  /*过渡效果为opacity,在0.5秒内完成*/
}
.fade-leave-to,.fade-enter{
  opacity:0;
}
/*样式中.fade表示transition的name值*/
</style>

//(淡入)隐藏效果opacity从1到0,分为三个状态呈现
//.fade-leave(1) -> .fade-leave-active(.5) -> .fade-leave-to(0)

//(淡出)出现效果opacity从0到1,分为三个状态呈现
//.fade-enter(0) -> .fade-enter-active(.5) -> .fade-enter-to(1)

 

路由跳转(vue-router)

模板直接跳转

<div>
    <router-link to="/liebiao">列表渲染(直接跳转)</router-link>
    //<!-- router-link相当于a标签,to相当于href,to的属性值为路由表的path -->
</div>

模板带参数跳转(带params)

//视图模板(发送页)
<div>
    <router-link :to="{name:'tiaojian',params:{name:'zhangsan'}}">条件渲染(带参数跳转)</router-link>
    //<!-- :to表示v-bind:to,后面的参数可以直接用变量 -->
    //<!-- 跳转方式可以用name跳转(name:'tiaojian'),也可以用path跳转(path:'/tiaojian'),参照router下的路由表 -->
    //<!-- params后面的参数是通过get的方式发送, -->
</div>
//路由表
{
    path:'/tiaojian/:name',      //:name表示:接收name属性 所对应的对象params,及后面的对象query,的所有内容
    name:'tiaojian',
    component:tiaojian
}
//mounted函数(接收页)
mounted(){
    alert(this.$route.params.name);
    // 接收params数据用:this.$route.params.属性名
}

 

模板带参数跳转(带params & query)

//视图模板(发送页)
<div>
    <router-link :to="{ name:'bangding',params:{name:'张三',address:'北京'},query:{age:18} }">
    css与style绑定
    </router-link>
</div>
//路由表
{
    path: '/bangding/:name',  //:name表示:接收name属性 所对应的对象params,及后面的对象query,的所有内容
    name: 'bangding',
    component: bangding
}
//mounted函数(接收页)
mounted(){
    alert(this.$route.query.age);
    //接收query数据:this.$route.query.属性名
}

 

js直接跳转

//视图模板(发送页)
<div @click="toUrl">组件(js直接跳)</div>
//methods(发送页)
methods:{
    toUrl(){
        this.$router.push({ path:'/zujian' });
    }
}

 

js跳转(带params)

//视图模板(发送页)
<div v-on:click="url">事件处理(js跳,带params)</div>
//methods(发送页)
methods:{
    url(){
      this.$router.push({name:'shijian',params:{fa:'带params参数跳'}});
    }
}

//接收页的路由表
//根据实际情况选择写或不写

//mounted函数(接收页)
mounted(){
    alert(this.$route.params.fa);
}

 

js跳转(带params & query)

//视图模板(发送页)
<div @click="uurl">项目(js跳,带params & query)</div>
//methods(发送页)
methods:{
    uurl(){
      this.$router.push({ name:'xiangmu',params:{msg:'params>msg属性值'},query:{gg:'query>gg 属性值'} });
    }
}

//接收页的路由表
//根据实际情况选择写或不写

//mounted函数(接收页)
mounted(){
//路由表没有添加params的属性情况
//1、则地址栏接收不到params,但是页面实际是可以收到的
//2、地址栏可以正常接收query
      alert(this.$route.params.msg);
      alert(this.$route.query.gg);
}

 

 

建议:不带参数时用path跳转,带参数时用name跳转

posted @ 2020-04-05 20:13  JaydenQiu  阅读(265)  评论(0)    收藏  举报