Vue学习笔记

此学习笔记是看网易云课程的学习笔记。

Vue全套精品课 - 网易云课堂

#下载node,配置环境变量

#初始化一个vue项目
  npm install -g vue-cli  #安装 vue-cli
  vue init webpack test1  #初始化一个vue项目
  cd test1                #进入项目
  npm install             #安装依赖
  npm run dev             #运行项目

#项目目录结构
    index.html 项目根目录视图
    .postcssrc.js: postcss配置文件
    static: 静态文件目录

#模版语法
    Vue 组件
      包含三个部分:
        templete: 视图
        script: 逻辑
        style: 样式
    
    Mustache:模版
      表现语法: {{ 语法 }}  只能存在单行语句,并且不能作用在HTML属性
    
    Vue基本指令:
      v-html: 渲染文本
      v-text: 渲染文本
      v-bind: 绑定     简写: v-bind:title == :title
    

    条件渲染:
      v-if
      v-else
      v-else-if
      v-show
      v-if与v-show区别:
          v-if是"真正"的条件渲染,因为它会确保在切换过程中条件块内的事件监听器
        和子组件适当地被销毁和重建
          v-if 也是惰性的: 如果在初始渲染时条件为假,则什么也不做一直到条件第
        一次变为真时,才会开始渲染多件块。
          相比之下,v-show就简单得多,不管初始化条件是什么,元素总会被渲染,
        并且只是简单地基于css进行切换。
          一般来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此,
        如果需要非常频繁地切换,则使用v-show较好,如果在运行时条件很少改变,
        则使用v-if较好
    

    列表渲染:
      v-for:
        例子:
          names: ["lisa","qiqi","mali","deyi"]
          


                   
  • {{name}}--{{index}}

  •              

    

    事件监听:
      v-on:    简写: v-on:click == @:click
      methods: 
      事件参数:
         可以加 $event参数,代表事件本身
         eg:
           {{age}}
        methods: {
            add: function(event) {
            this.age ++;
            console.log(event);
            }
        }

      修饰符:
         事件修饰符
         .stop     阻止冒泡
         .prevent  阻止默认方法
         .capture
         .self
         .once     事件只有一次
         .passive

         按键修饰符
         .enter
         .tab
         .delete (捕获“删除”和“退格”键)
         .esc
         ...


    数组更新检测:
       如果此数组总在了视图,使用下列方法触发数组,会对视图进行更新。
       push()
       pop()
       shift()
       unshift()
       splice()
       sort()
       reverse()
      eg:
              data () {
            return {
              names: ["lisa","qiqi","mali","deyi"]
            }
          },
          methods: {
            push: function () {
              this.names.push(["zhangsan"]);
            }
          

  • {{name}}--{{index}}

           push ele
      变异方法:上面方法,会引起视图更新
      替换数组:不会引起视图更新
    

    显示过滤/排序结果: filter
      for后面指定的是一个方法,方法中显式地使用了filter,对数组进行过滤并返回
         eg:
          

  • {{ n }}
  •             data: {
              numbers: [ 1, 2, 3, 4, 5 ]
            },
            computed: {
              evenNumbers: function () {
                return this.numbers.filter(function (number) {
                  return number % 2 === 0
                })
              }
            }

        计算属性和观察者
           computed
           计算属性和Methods区别:
                计算属性是基于它们的依赖进行缓存的。
            只在相关依赖发生改变时它们才会重新求值。
            这就意味着只要 message 还没有发生改变,
            多次访问 reversedMessage 计算属性会立即
            返回之前的计算结果,而不必再次执行函数。
        

        表单输入绑定: 双向数据绑定(用在表单输入)
          v-model
            eg:
              
                   

    Message is: {{ message }}


          
          修饰符:
             .lazy    当输入完成后,在model中才显示
             .number  自动将Str -> number
             .trim    删除左右空额
            eg:
              
        

        绑定HTML Class
           v-bind:class
              eg:
                


            data: {
              isActive: true,
              hasError: false
            }
           v-bind:class="[activeClass, errorClass]"
           v-bind:class="[isActive ? activeClass : '', errorClass]"
           v-bind:class="[{ active: isActive }, errorClass]"   //与上面的相同


        绑定内联样式: v-bind:style 
          


          data: {
            activeColor: 'red',
            fontSize: 30
          }


    ##单文件组件:  component
       1.三个部分组成
          1.Template
             只能存在一个根元素
          2.Script
          3.Style
             Scoped: 样式只在当前组件内生效 (npm)
       
       2.子父组件交互(通信)
          父 -> 子: props
             例子:静态数值
            Vue.component('blog-post', {
              // 在 JavaScript 中是 camelCase 的
              props: ['postTitle'],
              template: '

    {{ postTitle }}

    '
            })        
            
          数组:
              props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
          
          使用v-bind进行动态赋值:
            
             data : {
               postTitle : 'this is  test!!';
             }

           Prop验证: 数据类型验证、多数据类型验证、必选项、默认值、obj,arr数据类型的默认值
            props: {
                // 基础的类型检查 (`null` 匹配任何类型)
                propA: Number,
                // 多个可能的类型
                propB: [String, Number],
                // 必填的字符串
                propC: {
                  type: String,
                  required: true
                },
                // 带有默认值的数字
                propD: {
                  type: Number,
                  default: 100
                },
                ,
                // 带有默认值的对象
                propE: {
                  type: Object,
                  // 对象或数组默认值必须从一个工厂函数获取
                  default: function () {
                return { message: 'hello' }
                  }
                },
                // 自定义验证函数
                propF: {
                  validator: function (value) {
                // 这个值必须匹配下列字符串中的一个
                return ['success', 'warning', 'danger'].indexOf(value) !== -1
                  }
                }
            }

          子 -> 父: emit Event
         


       3.插槽  父给子传组件,子父都可以渲染插槽内的组件
         eg:
           th is the parent   //父中用子组件,并在子组件中定义自定义内容
          

         //子组件定义 注解,父组件自定义内容在此显示
              this is the child
              
          

           具名插槽:当有多个插槽时,父类自定义内容需要传入不同的插槽内,就需要具名插槽
              //父组件引用子组件
              

    this is insert into slot-a


              

    this is insert into slot-b


          

          

       //自定义子组件
              this is child
              
              ----------------------------
              
          

        

        作用域插槽:子给父传递数据,展示效果由父来决定
            

    {{scope.text}}

      //父引用   //slot-scope从子组件获取数据
                          //自定义   //text定义子要传递给父的内容
        
        
        动态组件:keep-alive
            组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题,就需要使用到keep-alive
            当不是实时更新的的组件的话,可以使用缓存,像table动态获取,表单动态提交,就不能使用缓存
           
           {{comp_view}}
               

           import comp1 from './components/comp1';
           import comp2 from './components/comp2';
          export default {
            name: 'App',
            components: {
              comp1,
              comp2
            },
            data () {
              return {
                comp_view: "comp1"
              }
            },
            methods:{
              changeView() {
                 if (this.comp_view == 'comp1'){
                 this.comp_view = "comp2";
                 }  else{
               this.comp_view = "comp1";
                 }
              }
            }
          }


    ###css过度与动画      定义 name属性,并将动画的进出的css名为:.name-enter{}
       在CSS过渡和动画中自动应用 class
            过渡类名:
           v-enter: 进入开始
           v-enter-active:执行过程中
           v-enter-to:结束动画
           v-leave:离开开始
           v-leave-active:执行过程中
           v-leave-to:结束动画
          eg:
              
              
                

    hello


              

              .slide-fade-enter, .slide-fade-leave-to
              {
                 transform: translateX(10px);
              opacity: 0;
              }

       使用动画:  可以使用reverse,进行将动画反向操作
           
             

    this is the xichuan test


           
        .bounce-leave-active{
          animation:bounce-in 3s ease reverse ;
        }
        @keyframes bounce-in {
          0% {
            transform: scale(0);
          }
          50% {
            transform: scale(1.5);
          }
          100% {
            transform: scale(1);
          }
        }

       自定义过渡的类名 : 使用第三方库: animate.css
         
         
             

    this is the xichuan test two!!!!!!


         


    ###自定义指令  directive
       全局指令:
       

        Vue.directive('focus', {
          // 当被绑定的元素插入到 DOM 中时……
          inserted: function (el) {
            // 聚焦元素
            el.focus()
          }
        })
       局部指令:
        export default {
          name: 'App',
          data () {
            return {
              show : true
            }
          },
          directives: {
            focus: {
              // 指令的定义
              inserted: function (el) {
            el.focus()
              }
            }
          }
        }

       钩子函数: 钩子函数可以传多个参数(在官网;了解)
          bind:指令第一次绑定到元素时调用
          inserted:被绑定元素插入父节点时调用
          update: 
          componentUpdated:
          unbind:  指令与元素解绑时调用
         

    ### 过滤器  filter
       全局过滤:
        {{name | lowCase}}
        Vue.filter('lowCase', function (value) {
          return value.toLowerCase()
        })

        局部过滤:
        export default {
          name: 'App',
          data () {
            return {
              name : 'this is the tesT!'
            }
          },
          filters:{
            upCase : function (val) {
            return val.toUpperCase();
            }
          }

    ###Axios
      1.安装: npm install axios
      2.引用加载:
          import Axios from "axios"
          Vue.prototype.$axios = Axios
      3请求:
         GET请求:
        this.$axios.get('http://127.0.0.1/api/saying',{
           params:{
             ID: xichuan
           }
        })
        .then(function (response) {
            console.log(response.data);
        }).catch(function (error) {
            console.log(error);
        });
         
         POST请求:  url后面直接加参数
            form-data: ?name=xichuan&age=20
        x-www-urlencoded: {name:"xichuan",age:20}
            axios接收的post请求参数的格式是form-data格式

        import qs from "qs"

          axios.post('/user', qs.stringify({
            firstName: 'Fred',
            lastName: 'Flintstone'
          }))
          .then(function (response) {
            console.log(response);
          })
          .catch(function (error) {
            console.log(error);
          });
     
       4.全局设置参数:
        Axios.defaults.baseURL = 'http://127.0.0.1';
        Axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

        5.拦截请求
           import qs from 'qs'

        // 添加请求拦截器
        Axios.interceptors.request.use(function (config) {
            if(config.method == "post"){
              config.data == qs.stringify(config.data)
            }
            return config;
          }, function (error) {
            return Promise.reject(error);
          });

        // 添加响应拦截器
        Axios.interceptors.response.use(function (response) {
            // 对响应数据做点什么
            return response;
          }, function (error) {
            // 对响应错误做点什么
            return Promise.reject(error);
          });
        
        6.跨域问题


    ###Mock 数据模型
        1.自己创建JSON文件,使用get请求形式访问数据
           有点: 方便,快捷
           缺点:只能存在get请求
        2.项目中集成服务器,模拟各种接口
           优点:模拟真实线上环境
           缺点:增加开发成本
        3.直接使用线上数据
           优点;真实
           缺点:不一定每一个项目都存在
       
        1.安装与初始化
        npm install mockjs
        2.使用
           import Mock from "mockjs"
           Vue.prototype.Mock = Mock

        var data = this.Mock.mock({
              'list|1-10': [{
            'id|+1': 1
              }]
            });
        console.log(data)

    ####Router
        1.安装
          npm install vue-router
        2.引用:
          import VueRouter from 'vue-router'
          Vue.use(VueRouter)
        3.使用
        const router = new VueRouter({
          routes:[
            {path: "/",component: HelloWorld}
          ]
        })

        new Vue({
          el: '#app',
          router,
          components: { App },
          template: ''
        })

        4.视图
           

        5.跳转(导航)   相当于标签,但最好不要使用标签
           

        Go to Foo
     

        6.路由嵌套
        在父父中定义组件
        const router = new VueRouter({
          routes:[
            {path: "/",component: HelloWorld},
            {
              path:"/helloVue",
              component:HelloVue,
              children:[
            {path: "child1",component: Child1},   //这里的child1使用的是名称,并不是相对路径
            {path: "child2",component: Child2}
              ]
            }
          ]
        })

        在父父页面显示父组件
        


            hello1
            hello2
            
          

        在父组件显示子组件
        


            this is the test helloVue
            chld1    //这里to使用的是相对路径
            child2
            
        

        7.路由传递参数
           const router = new VueRouter({
        routes:[
           {name:"helloWorld",path: "/hello/:count",component: HelloWorld}   //传递参数,必须加上name这个字段,且参数名:count形式
        ]});
        
         //这个写法也可以
        hello1 //router-link中要改为  :to,且参数为json格式

        在子元素中展示数据:
        {{$route.params.count}}

        8.路由高亮效果
        1.在index.js 中, 添加 路由选中class名
        默认是 router-link-active, 更改
        const router = new VueRouter({
          mode: "history",    //
          linkActiveClass: "active",   //将router-link-active名字改为active
          routes:[
             {name:"helloWorld",path: "/hello/:count",component: HelloWorld}   //传递参数,必须加上name这个字段,且参数名:count形式
        ]});
          
        2.在全局中配置, css 样式
          .active {
            color: red
          }
        3.对于匹配 / 的, 会始终显示高亮, 需要添加 exact 属性; 
        

  • 首页

  • ###Element-UI 
        1.安装:
           npm i element-ui -S
        
        2.安装按需加载依赖
            npm install babel-plugin-component -D
        
        3.修改 .babelrc文件
        {
          "presets": [["es2015", { "modules": false }]],
          "plugins": [
            [
              "component",
              {
            "libraryName": "element-ui",
            "styleLibraryName": "theme-chalk"
              }
            ]
          ]
        }

      
    ### VueX
        Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
          它采用集中式存储管理应用的所有组件的状态,
          并以相应的规则保证状态以一种可预测的方式发生变化
       
        1.什么时候使用Vuex?
        虽然 Vuex 可以帮助我们管理共享状态,
        但也附带了更多的概念和框架。这需要对短期和长期效益进行权衡。

        如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。
        确实是如此——如果您的应用够简单,您最好不要使用 Vuex。
        一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,
        您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。
        
        2.Vuex状态管理
          View -> (dispatch) Action ->(Commit) Mutations ->(Mustate)Sate -> View
          注意:Action不是必需品,如果有异步操作才能用到Action,否则可以不使用
        
        3.Actions:  
          Action 提交的是mutation,而不是直接变更状态。
          Action 可以包含任意异步操作。    当前本地操作,使用Mutations,有异步操作使用Action

    1.index.js

    // vuex
    import Vue from 'vue'
    import Vuex from 'vuex'

    Vue.use(Vuex)

    const store = new Vuex.Store({
      state:{          //定义公共变量的地方
        count: 5
      },
      // 更改store的状态
      mutations: {
        increment (state) {
          state.count++
        },
        decrement (state) {
          state.count--
        }
      },
      // 有异步的时候, 需要action
      actions: {
        increment(context) {
          context.commit('increment')
        },
        decrement (context) {
          setTimeout(function () {
            context.commit("decrement")
          }, 10)
        }
      },
      // 通过getter 进行数据获取
      getters: {
        getState(state) {
          return state.count > 0 ? state.count : 0;
        }
      }
    })
    export default store


    2.在main方法中引用

    import store from './index'
    new Vue({
      el: '#app',
      store,
      components: { App },
      template: ''
    })


    3.引用


          获取值 --
          {{ getCount }}

         
         
       

    computed: {
        // 避免编程负数, 需要通过方法进行获取
        getCount() {
          // return this.$store.state.count
          return this.$store.getters.getState;
        }
      },
      methods: {
        add() {
          this.$store.commit("increment")
        },
        des() {
          // 使用 action中的异步方法
          this.$store.dispatch("decrement")
        }
      }


    ##iView  
        1.安装
           npm install iview --save
        2.按需引用·
           npm install babel-plugin-import --save-dev

        // .babelrc
        {
          "plugins": [["import", {
            "libraryName": "iview",
            "libraryDirectory": "src/components"
          }]]
        }
        
        //main.js

        import { Button, Table } from 'iview';
        Vue.component('Button', Button);
        Vue.component('Table', Table);

       github上有更多的笔记:Raray-chuan (兮川) · GitHub

    你可能感兴趣的:(前端,Vue学习笔记)