vue2.x基础知识学习笔记

一、vue环境搭建     vue官网地址:https://cn.vuejs.org/index.html

准备工作:

①安装node.js

  查看安装版本:node -v

②安装淘宝镜像加速(下载速度会更快)

  npm install cnpm

③安装vue-cli (vue脚手架)

  npm install -g @vue/cli   (新版本)

创建项目:

  管理员身份打开poweerShell或者cmd

  ①vue  create 项目名称(只能小写字母,- 组成,最好不要使用下划线)

    注:这一步如果有错误:无法加载文件,则执行下面操作:

      set-ExecutionPolicy  RemoteSigned ,之后选择 y ,再次创建即可

  ②↑ ↓选择到Manually select features回车

  ③选择Babel  ,router(空格选择)回车

  ④询问是否选择history路由模式,默认no

  ⑤询问配置信息存储位置,选择packge.json即可,也可以自定义一个文件

  ⑥询问是否将此配置保存为模板,以便下次使用

  ⑦创建完成

  ⑧用提示信息两行命令开启服务器

 

安装插件、依赖:

  安装element组件库、引入、注册    官网地址:https://element.eleme.cn/#/zh-CN

    npm install element-ui --save

  路由安装、引入、注册

    npm install vue-router@4

  axios安装    中文网地址:http://www.axios-js.com/zh-cn/docs/

    npm install axios

 

 

二、vue的七大对象:

 

  ① el

 

  ② data

 

  ③ methods

 

  ④ template

 

  ⑤ render

 

  ⑥ computed

 

  ⑦ watch

 

 

三、vue-cli脚手架目录大致结构:

  

 

 

 

四、vue基本指令:

 

 五、了解MVVM模式

 

 

 

六、vue路由基本用法:

 

 

 

七、vue生命周期(钩子函数)

 

 

 八、组件(自定义标签,可复用,一个页面就是由很多组件构成)

  1、基本用法:

    html部分:   

<div id="app">
       <chencan></chencan>
       <chenhe></chenhe>
       <chen-shan></chen-shan>
</div>

    js部分

<script>
    //组件格式:  Vue.component("自定义标签名" , {该组件的一些对象包含data,methods,computed等,vue实例包含的组件都可以用})
    /**
     *组件中的data要使用函数的形式,这样在组件复用的时候组件之间的数据就不会冲突
     *Vue实例其实就是一个组件,只不过他是一个顶层组件
     *template里面只能有一个根组件
     */
    //组件嵌套(在一个组件里面写另外一个或者多个组件),组件嵌套的时候要注意被包含的组件要写在包含的组件之前(如果是局部组件用的第二种写法的话)
    Vue.component("chencan" ,{
        template: "<div><h4 @click='adds(item)' v-for='item in this.fruits'>{{item}}</h4><chen-q></chen-q></div>",
        data: function(){
            return{
                fruits: ["苹果" , "车厘子" , "鹰嘴芒" , "西瓜" , "榴莲"]
            }
        },
        methods: {
            adds: function(obj){
                alert(obj);
            }
        },
        components: {
            "chen-q":{
                template:"<div @click='add'>{{d}}</div>",
                data: function(){
                    return{
                        d:3,
                    }
                },
                methods: {
                    add: function(){
                        return this.d += 2;
                    }
                }
            }
        }

    });
  //组件的第二种定义形式,这是第一步,第二部是在vue实例中注册组件
    var chenShan = {
        template: "<h2>{{name}}</h2>",
                data: function(){
                    return{
                        name: "局部组件😄,第二种写法",
                    }
                }
    }

  //vue实例 var vue = new Vue({ el: '#app', data: { }, methods: { }, //计算属性 computed: { }, //侦听属性(想要侦听哪个属性,方法名就是那个属性) watch: { }, //组件注册(局部组件),局部组件有两种写法,还可以把对象提到外面 components:{ chenhe: { template: "<h2>{{name}}</h2>", data: function(){ return{ name: "局部组件😄,第一种写法", } } }, chenShan, } }); </script>

  

  2、组件中属性的传值

  1、props属性 , 定义好组件之后,在自定义组件中自定义标签中定义属性,该属性绑定vue实例中的data中的某个数据(可以是引用数据,也可以是不是引用数据)
         组件中props属性接收之后,在组件中的任何一个大方都可以使用了
     2、prop属性值的验证
     3、设置属性的默认值
  
<body>
    <div id="app">
     <!--从标签中传值,绑定一个属性--> <chencan :name="list"></chencan> </div> </body> <script> var app = new Vue({ el: '#app', data: {
       //这是传的值 list:[ { name: "孙悟空", age: 500, nickname: '齐天大圣' }, { name: "猪八戒", age: 540, nickname: '天蓬元帅' }, { name: "沙悟净", age: 300, nickname: '卷帘大将' }, ], }, methods: { }, components:{ "chencan":{
          //使用{{}}插值表达式将传过来的值渲染出来 template: "<div><div v-for='item in name' :key='item.name'>{{item.nickname}}---{{item.name}}</div></div>", data: function(){ return { } }, methods:{ //方法中可以修改props中接收的值,但是不建议这样做,如果父组件也使用了这个数据的话会造成父组件的数据也改变,vue中建议使用单向数据流 //如果非常有这个必要,建议将这个方法放到vue实例中去 // btn: function(){ // return this.name[0].name = "玉皇大帝"; // } }, //prop接收组件传过来的值,prop当中的值和data中的基本一样 //对props中接受的参数做验证,例如下面的表示验证接收的参数name是否是一个数组 props:{name:Array}, } } }); </script>

  

  3、子组件向父组件传值,使用自定义事件内容分发 ( $emit()函数 )

  操作步骤:

①在子组件中定义一个事件来触发传值

②在事件中编写自定义函数 this.$emit("自定义名称" , "要传递的值");    ###要传递的值可以是普通类型,也可以是数组,也可以是对象

③在子组件标签中监听要传递的值

④在父组件中定义方法接收传过来的值

<div id="app">
   <component-b></component-b>
</div>

<script>
    //子组件
    var componentA = {
      //子组件中定义一个方法来触发传值 template:
"<div><input v-model='val'/><button @click='fn'>向父组件传递</button></div>", data: function(){ return { val: '', } }, methods: { fn: function(){
          //自定义事件$emit绑定要传的值
this.$emit("val" , this.val); } } } //父组件 var componentB = {
      //在子组件中定义接收传过来的值的方法 template:
"<div>子组件传过来的值:<span>{{val}}</span><component-a v-on:val='receive'></component-a></div>", data: function(){ return { val: '', } }, methods: {
        //父组件中定义方法接收传过来的值 receive:
function(data){ this.val = data; } }, components: { componentA } }   //vue实例 var app = new Vue({ el: '#app', data: { }, methods: { }, components:{ componentB, } }); </script>

 

  4、动态组件

 1 <div id="app">
 2         <div>
 3 
 4             <button v-for="item in coms" @click="showComName =item.name">{{item.btn}}</button>
 5            
 6         </div>
 7         <!--动态组件的标签 component 配合is属性使用  is等于那个组件就显示哪个组件 -->
 8         <!--光使用component配合is属性使用时,每次切换组件,切换之前的组件都会销毁,切换之后的组件都是重新创建,这样操作dom的频率过高-->
 9         <!--改进:再component的外面用一个<keep-alive> 标签包起来,这样就不会频繁销毁和创建-->
10         <keep-alive>
11             <component v-bind:is="showComName"></component>
12         </keep-alive>
13         
14     </div>
15     
16     
17 <script>
18 
19     var comA = {
20         template: "<div>这是组件A</div>",
21     }
22     var comB = {
23         template: "<div>这是组件B</div>",
24     }
25     var comC = {
26         template: "<div>这是组件C</div>",
27     }
28     var comD = {
29         template: "<div>这是组件D</div>",
30     }
31     var comE = {
32         template: "<div>这是组件E</div>",
33     }
34 
35     var app = new Vue({
36         el: '#app',
37         data: {
38             showComName: 'com-a',
39             coms: [{name:'com-a' , btn:'组件A'},
40             {name:'com-b' , btn:'组件B'},
41             {name:'com-c' , btn:'组件C'},
42             {name:'com-d' , btn:'组件D'},
43             {name:'com-e' , btn:'组件E'}]
44         },
45         watch: {
46             showComName: function(a , b){
47                 console.log(a);
48             }
49         },
50         components: {
51             comA,
52             comB,
53             comC,
54             comD,
55             comE
56         },
57         
58     });
59 </script>

 

 

九、网络通信 (axios) 中文官网地址:http://www.axios-js.com/zh-cn/docs/

  axios只需在需要使用的地方引入即可,无需注册

 

十、计算属性

  所谓《计算属性》重在属性两个字,它就是一个属性,与data中的属性有相同特点,这个属性的特殊之处就是它的值可以通过计算获得
  1、基本用法:

<div id="app">
        {{name}}
        {{hobby.name}}
        {{hobby.time}}
        <button @click = 'showage'>显示年龄</button>
     <!--使用插值表达式展示计算属性的值-->
        {{sum}}
        <hr>
        简易计算器
        <input type="text" v-model.number="firstNum" placeholder="请输入第一个数"/>
        <select v-model="symbol">
            <option value="+" selected>+</option>
            <option value="-">-</option>
            <option value="×">×</option>
            <option value="÷">÷</option>
        </select>
        <input type="text" v-model.number="secondNum" placeholder="请输入第二个数"/>
        = <span>{{result}}</span>
</div>
<script>
var vue = new Vue({
        el: '#app',
        data: {
            name: '陈灿',
            age: 20,
            hobby: {
                name: '打球',
                time: '3年'
            },
            x: 10,
            y: 30,
            firstNum: 10,
            secondNum: 10,
            symbol: '+',
        },
        
        //计算属性
        computed: {
            sum: function(){
                return this.x + this.y;
            },
            result: function(){
                switch(this.symbol){
                    case '+':
                        return this.firstNum + this.secondNum;
                        break;
                    case '-':
                        return this.firstNum - this.secondNum;
                        break;
                    case '×':
                        return this.firstNum * this.secondNum;
                        break;
                    case '÷':
                        return this.firstNum / this.secondNum;
                        break;
                }
            }
        }
    });


</script>

 

十一、侦听属性

  • 侦听属性是侦听一个属性(包括一般的属性和计算属性)的变化,相当于一个回调函数,当属性的值发生改变时,会执行某些操作
  •  一般用来做数据同步:比如用户修改了自己的网名,个性签名后,可以在侦听属性中发起异步请求将数据库中的数据更新
//侦听属性(想要侦听哪个属性,方法名就是那个属性)
        watch: {
            //curr:属性变化之后的值   last:属性变化之前的值
            firstNum: function(curr , last){
                console.log("变化之后的值:"+curr  + "变化之前的值:"+last);
            },
            //也可以侦听计算属性
            result: function(after , before){
                console.log("变化之后:"+after +"变化之前:"+before);

            }
        }

 

十二、过滤器

  • 针对插值(插值就是 {{}} 里面的内容)可以将原始数据进行处理
  • 过滤器可以累加,一个过滤器处理后的结果再交给另一个过滤器处理
  • 场景:给up主点赞,当赞的数量达到1000之后,显示1k、1.2k这种,当数量到达10000以上时,显示1w、1.2w类似的
    
  <div id="app">
     <!--使用的时候用 | 分隔开,左边写原始数据(需要过滤的数据),右边写过滤器的名字-->
        <span>{{yesNum | yesNumHandle}}</span>
        <button @click="addYes">点赞</button>
    </div>

//
过滤器
  data: {
      yesNum: 9998,
   },
  filters: {
     //value就是传过来的原始数据
     yesNumHandle: function(value){
     if(value >= 1000 && value < 10000){
        return (parseInt((value / 1000)*100) / 100) + "k";
     }else if(value >= 10000){
        return (parseInt((value / 10000)*100) / 100) + "w";
     }
   }
 }

 

十三、渲染函数

  •     渲染函数具有非常强大的功能,使用的时候比较繁琐,在开发中使用的非常少(可以了解vue底层的实现)
  •     渲染函数出现,body里面的所有标签都会消失
  •     格式:  createElement("标签的类型" , {属性、事件、样式} , [里面包含的标签] , "标签中的文本")
  •     例如:  createElement("div" ,{attrs:{id:"app"} , on:{click:this.btn} , style:{fontSize:"14px",color:"red"}} , [createElement("span" , "哈哈")])
     //渲染函数
        render: function(createElement){
            var divs_ = [];
            for(var i = 0 ; i < this.news.length ; i++){
                var div_ = createElement("div" , [
                            createElement("h4" , [
                                this.news[i].title,
                                createElement("span" ,{on:{click:this.btn} ,style:{color:"red" , fontSize:"13px"}} , this.yesNumHandle(this.news[i].like))
                            ])
            ])
                divs_.push(div_);
            }

            return createElement("div" , {attrs:{id: "app"}} , [
                createElement("div" , divs_)
            ]);
        }

 

 

十四、插槽

  1.  只有一个插槽的时候,标签之间的内容默认都在插槽内
  2.     有多个插槽的时候,需要给插槽指定名称,用的时候用template标签包裹起来,并使用v-slot指定使用那个插槽
  3.     具名插槽:有具体名字的插槽
  4.     默认插槽:没有名字的插槽(default)
  5.     当模板中有多个插槽时,要清楚有没有默认插槽,哪个是默认插槽,在使用中如果有多个插槽,只有一个没有名字,那这个就是默认插槽,使用的时候,不用template配合v-slot指明使用哪个插槽的话,就会使用默认插槽
  6.     直接在模板中的slot标签内写的内容称为后备内容

  1、基本使用:

<div id="app">
        <com-a>
            <!--此时这三个tmplate的位置无所谓前后了,显示的位置是按照模板中定义的位置-->
            <!--直接使用{{value}} 使用的是父元素的value值-->
           <template v-slot:slot-1>这是第一个插槽之间的内容 -- {{value}}</template>
           <!--使用v-slot:slot-2="绑定一个值"  再使用{{绑定的值.val}} 得到的值是自己的val,并且只能再自己的template里面使用-->
           <template v-slot:slot-2="toget">这是第二个插槽之间的内容 -- {{toget.val}}</template>
           <template v-slot:slot-3>这是第三个插槽之间的内容</template>
        </com-a>
</div>
<script>

    var comA = {
        template: "<div>\
<slot name='slot-1'></slot>\
<h2>标题</h2>\
<slot :val='value' name='slot-2'></slot>\
<p>开始</p>\
<slot name='slot-3'></slot>\
<p>结束</p>\
<slot></slot></div>",
        data: function(){
            return{
                value:'诸葛亮'
            }
        }
    }

    var vue = new Vue({
        el: "#app",
        data: {
            title: '我的技术栈',
            value: '周瑜',
            content: ["java" , "mysql" , "oracle" , "c++" , "python" , "go"],
        },
        components: {
            comA
        }
    });
</script>

 

 

十五、路由组件

  1、嵌套路由

父组件:
        var parent= {template:'<div>父组件中的内容<router-view></router-view></div>'}

        var child = {template:'<div>这是子组件</div>'}

        router:[
            {
                path: '/parent',
                component:parent,
                children:[
                    {
                        path:'child',//子组件的路径
                        component:child //子组件
                    }
                ]
            }
        ]

        <router-view to="/parent">显示父组件</router-view>
        <router-view to="/parent/child">显示子组件</router-view>

 

  2、命名路由

  3、动态路由

    动态传参   this.$router.push({path:'', params:{} , query:{}})    前面是path,就不可以用params传值,只能用query传值;前面是name就可以使用params,也可以使用query

    给同一个页面路由名字起别名(一个路由有多个名字)使用  alias:

  4、路由守卫,一般指(路由独享守卫)

    就是一个钩子函数(写在路由里面的)
       beforeEnter: function(to , from , next){}  to指要去到哪个页面,from表示从哪个路由过来的,next控制是否放行,跳转到哪个路由

    

    1)全局前置守卫

var router = new VueRouter({})

    router.beforeEach(function(to , from , next){

    })

 

    2)解析守卫

router.beforeResolve(function(to , from , next){})

 

    3)后置守卫

router.afterEach(function(to , from){})

 

    4)组件中的路由守卫

beforeRouteEnter:function(to , from , next){
        console.log("组件进入");
    }

    beforeRouteUpdate:function(to , from , next){
        console.log("组件被复用的情况下调用(数据变动的时候)");
    }

    beforeRouteLeave:function(to , from , next){
        console.log("离开组件的时候");
    }

 

  5、路由守卫的全部过程分析

  •   导航被触发。
  •     在失活的组件里调用 beforeRouteLeave 守卫。
  •     调用全局的 beforeEach 守卫。
  •     在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)。
  •     在路由配置里调用 beforeEnter。
  •     解析异步路由组件。
  •     在被激活的组件里调用 beforeRouteEnter。
  •     调用全局的 beforeResolve 守卫(2.5+)。
  •     导航被确认。
  •     调用全局的 afterEach 钩子。
  •     触发 DOM 更新。
  •     调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

 

十六、history路由模式和hash路由模式

  路由重定向: 在路由中加参数  redirect: '/login'

     history路由模式请求地址中不会有 '#' 字符

  

 

十七、404通配符

通过通配符  * 作为path,将该路由放到最后,如果所有路由都匹配完都没有匹配上,则会匹配404页面
routes:[
        //放在最后面
        {
            path:'*'
            component:notFound  //组件的名称
        }
    ]

 

 

十八、命名视图

  有名字的视图(可以在一个页面显示多个组件)
<router-view name="left"></router-view>
    <router-view name="right"></router-view>

    var left = {template:'<div><p>左边</p></div>'}
    var right = {template:'<div><p>右边</p></div>'}

    routes:[
        {
            path:'/a'
            components:{
                left:'left',
                right:'right'
            }
        }
    ]

 

 

  

 

posted @ 2022-03-17 14:46  手可摘星陈1024  阅读(165)  评论(0编辑  收藏  举报