• VUE 学习笔记


    VUE学习笔记

    基础知识:

    https://www.yuque.com/liaoyuanyang/web/vue

    VUE CLI 脚手架

    优点:

    脚手架是通过webpack搭建的开发环境

    使用ES6语法

    打包和压缩JS为一个文件

    项目文件在环境中编译,而不是浏览器

    实现页面自动刷新

    环境要求:

    nodejs ≥ 6.9

    npm ≥ 3.10

    安装

    $ npm install -g vue-cli

    $ vue --version

    使用

    $ vue init <template-name> <project-name>

    比如,

    $ vue init webpack my-project

    $ cd my-project

    $ npm install

    $ npm run dev

    执行流程

    index.html --> main.js --> App.vue

    精简App.vue文件
    // 1、模板:html结构 template子元素有且只能有一个
    <template>
     <div id="app">
       <h1>{{ title }}</h1>
     </div>
    </template>
    // 2、行为:处理逻辑
    <script>
    export default {
     name: 'App',
     data() {
       return {
         title: 'Hello VUE!'
      }
    }
    }
    </script>
    // 3、样式:解决
    <style>

    </style>

    Vue.js规定:在定义组件的选项时,datael选项必须使用函数。 另外,如果data选项指向某个对象,这意味着所有的组件实例共用一个data。 我们应当使用一个函数作为 data 选项,让这个函数返回一个新对象: Vue.component('my-component', { data: function() { return { title: 'Hello VUE!' } } })

    组件的注册

    全局
    // 在 main.js 中全局注册组件
    import Users from './components/Users'
    Vue.component('users', Users);
    局部
    <script>
    // 局部注册组件
    import Users from './components/Users'

    export default {
     name: 'App',
     data() {
       return {
         title: 'Hello VUE!'
      }
    },
     components: {
       "users": Users
    }
    }
    </script>

     

    组件CSS作用域

    <!-- Add "scoped" attribute to limit CSS to this component only -->

    如果在 <sytle> 中不加 scoped 则后面的属性覆盖前面的,否则每个组件各自用各自的样式。

    <style scoped>
    ...
    </style>

     

    Vue 属性传值Props

    父传子

    <!-- 给子组件传值 -->
    <users v-bind:users="users"></users>

    export default {
     name: "App",
     data() {
       return {
         title: "Hello VUE!",
         users: [
          { name: "Henry", position: "WEB", show: true },
          { name: "Bucky", position: "PHP", show: false },
          { name: "Emily", position: "C", show: true },
          { name: "Tom", position: "JAVA", show: true },
          { name: "Jerry", position: "Python", show: true },
          { name: "Tim", position: "Go", show: false },
          { name: "Bob", position: "C#", show: true }
        ]
      }
    }
    };
    export default {
     name: "Users",
     // 获取父组件的传递的值
     // props: ["users"],
     // 官方推荐的标准写法  
     props: {
       users: {
         type: Array,
         required: true
      }
    },
     data() {
       return {

      };
    }
    };

     

    传值和传引用

    传值:string、number、boolean

    引用(会改变相关数据):array、object

     

    事件传值

    <!-- 子传父 -->
    <template>
     <div class="header">
       <h1>{{ title }}</h1>
       <!-- 1、监听事件 -->
       <p @click="changeTitle">{{ app_title }}</p>
     </div>
    </template>

    methods: {
       changeTitle: function() {
         // 2、触发事件  
         this.$emit("titleChanged", "子传父");
      }
    }
    <!-- v-on 子传父 v-bind 父传子 -->
    <app-header v-on:titleChanged="updateTitle($event)" v-bind:app_title="title"></app-header>

    methods: {
       updateTitle: function(title){
         this.title = title;
      }
    }

     

    生命周期

    生命周期钩子的函数:

    beforeCreate: 组件实例化之前;可做加载动画

    created: 组件创建、属性绑定、DOM未生成;可做数据请求,付给属性,结束加载动画

    beforeMount: 组件挂在之前,页面仍未显示,虚拟DOM已配置;

    mounted: 组件挂在之后,页面已显示;

    beforeUpdate: 组件更新之前,页面仍未更新,虚拟DOM已配置;

    updated: 组件更新之后,显示新的页面;

    beforeDestory: 组件销毁之前;

    destoryed: 组件销毁之后;

     

    路由和Http

    路由:

    安装:$ npm install vue-router --save-dev

    main.js中

    import VueRouter from 'vue-router'

    Vue.use(VueRouter)

    // 配置路由

    const router = new VueRouter({
       routes: [
        {path:'/', component: Home},
        {path:'/hello', component: HelloWorld},
        {path: '*', redirect: '/' } // miss路由
      ],
      // 去除url地址中的 #
      mode: "history"
    });

    new Vue({

     router,

     el: '#app',

     components: { App },

     template: '<App/>'

    })

    App组件中

    // 在APP组件中
    <!-- 路由匹配到的组件将渲染在这里 -->
    <router-view></router-view>

    跳转

    <a href="/">Home</a>
    <router-link to="/">Home</router-link>
    // router-link 默认是 a 标签,可使用 tag 属性来改变,如 tag=“div”
    // v-bind:to 动态绑定值
    <router-link v-bind:to="homeLink" tag="div">主页</router-link>
    <script>
    export default {
     data (){
       return {
           homeLink: '/'
      }
    }
    }
    </script>
    // 或者如有注册时,name属性绑定
    const routes = [
    { path: '/', name:'homeLink', component: Home },
    ]
    <router-link v-bind:to="{name:'homeLink'}">主页</router-link>
    跨域处理:
    // 在根目录下config的index.js中的proxyTable属性配置跨域请求
    proxyTable: {
       '/apis': { //替换代理地址名称
           target: 'http://php.test', //代理地址
               changeOrigin: true, //可否跨域
                   pathRewrite: {
                       '^/apis': '' //重写接口,去掉/apis
                  }
      }
    },
    Http:

    安装 vue-resource$ npm install vue-resource --save-dev

    注:此插件已不再维护

    import VueSource from 'vue-resource'
    Vue.use(VueSource)
    created: function(){
       this.$http.get("https://jsonplaceholder.typicode.com/users")
      .then((data) => {
           // 赋值
           this.users = data.body;
      })
    }

    安装 axios$ npm install axios 安装 qs$ npm install --save qs

    import Axios from 'axios'
    import Qs from 'qs'
    Axios.defaults.headers.common['token'] = 'xxxxxxxxxx'
    Axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
    // 转为数组形式 而不是json
    Axios.defaults.transformRequest = [ function (data) {
       data = Qs.stringify(data);
       return data;
    }]

    Vue.prototype.$axios = Axios

    // 使用axios
    this.$axios.post("/apis/api/hello.php", {
       username: "tome",
       password: 123456
    }).then(result => {
       console.log(result.data);
    });

    使用fetch

    // 或者使用fetch()
    fetch("/apis/api/hello.php", { //即亲求 http://php.test/api/hello.php
       method: "post",
       headers: {
           "Content-Type": "application/json",
           token: "xxxxxxxxxx"
      },
       // 以post方法 request payload json形式发送的数据 php后台获取数据为:
       // $post = json_decode(file_get_contents('php://input'), true);
       body: JSON.stringify({ username: "tom", password: 123456 })
    }).then(result => {
       // console.log(result)
       return result.json();
    }).then(data => {
       console.log(data);
    });

     

    搭建脚手架

    $ vue init webpack-simple xxx

     

    路由跳转

    <script>
    export default {
     methods: {
       goToMenu: function() {
         // 跳转到上一个页面
         this.$router.go(-1);
         // 指定跳转的地址
         this.$router.replace('/menu');
         // 指定跳转路由的名字下
         this.$router.replace({name:'menuLink'});
         // 通过push跳转
         this.$router.push('/menu');
         this.$router.push({name:'menuLink'});
      }
    }
    };
    </script>

     

    二级路由和三级路由

    // children属性定义 三级路由雷同
    const routes = [
    {
       path: '/about', name: 'aboutLink', component: About, children: [
        { path: 'history',name:'historyLink', component: History }, // /about/history
        { path: '/delivery',name:'deliveryLink', component: Delivery },// /delivery
      ]
    }
    ]

     

    导航守卫

    全局守卫
    // 全局守卫
    router.beforeEach((to, from, next) => {
     if (to.path == '/login' || to.path == '/register') {
       // 正常展示
       next();
    } else {
       alert('请先登录!');
       next('/login');
    }

    })
    路由独享
    const routes = [
    {
       path: '/admin', name: 'adminLink', component: Admin, beforeEnter: (to, from, next) => {
         // 路由独享守卫
         alert('请先登录');
         next('/login');
         // next(false);
      }
    },
    ]
    组件内守卫
    <script>
    export default {
     data() {
       return {
         name: "Herry"
      };
    },
     beforeRouteEnter: (to, from, next) => {
       // 此时还获取不到data
       alert("Hello " + this.name);
       // 回调
       next(vm => {
         alert("Hello " + vm.name);
      });
    },
     beforeRouteLeave: (to, from, next) => {
       // 离开
       if (confirm("确定离开吗")) {
         next();
      } else {
         next(false);
      }
    }
    };
    </script>

     

    复用router-view

    // App.vue中复用orderingGuide、deliver、history组件
    <div class="container">
       <div class="row">
           <div class="col-sm-12 col-md-4">
               <router-view name="orderingGuide"></router-view>
           </div>
           <div class="col-sm-12 col-md-4">
               <router-view name="deliver"></router-view>
           </div>
           <div class="col-sm-12 col-md-4">
               <router-view name="history"></router-view>
           </div>
       </div>
    </div>
    // 路由组测分离到单独文件 routes.js
    // 复用其他路由组件 把 components 属性值改为对象形式并把组件组测进来
    // 此时 Home组件就可以复用 router-view 了
    export const routes = [
    {
       path: '/', name: 'homeLink', components: {
         default: Home,
         'orderingGuide': OrderingGuide,
         'deliver': Delivery,
         'history': History
      }
    },
    ]
    // 并在main.js中引入
    import {routes} from './routes'

     

    控制滚动行为

    // main.js
    const router = new VueRouter({
     routes,
     mode: 'history',  
     // 只在支持 history.pushState 的浏览器中
     scrollBehavior(to, from, savedPosition) {
       return { x: 0, y: 100 };
       return { selector: '.btn' }; // 跳转到 .btn 样式位置
    }
    })

    Vuex

    概述

    主要应用于Vue.js中管理数据状态的一个库

    通过创建一个集中的数据存储,供程序中所有组件访问

    安装

    $ npm install vuex --save

    使用
    // 创建 store.js
    import Vue from 'vue'
    import Vuex from 'vuex'

    Vue.use(Vuex)

    export const store = new Vuex.store({
       // 严格模式
       strict: true,
       // 存储数据
       state: {
           products: [
              { name: "马云", price: 200 },
              { name: "马化腾", price: 140 },
              { name: "马冬梅", price: 20 },
              { name: "马蓉", price: 10 }
          ]
      },
       // 获取数据
       getters: {
           newLists: (state) => {
               var newLists = state.lists.map(change => {
                   return {
                       name: '**' + change.name + '**',
                       price: change.price / 2
                  }
              });
               return newLists;
          }
      },
       // 出发事件时调用
       mutations: {
           reducePrice:(state) => {
               state.lists.forEach(element => {
                   element.price -= 1;
              });
          }
      },
       // 异步操作和传参
       actions: {
           // 传参 payload
           reducePrice: (context, payload) => {
               // 异步
               setTimeout(function () {
                   // 提交 mutations 中的方法
                   context.commit("reducePrice", payload);
              }, 3000)
          }
      }
    });

    main.js中引入

    import Vue from 'vue'
    import App from './App.vue'
    import {store} from './store/store'

    new Vue({
     store:store,
     el: '#app',
     render: h => h(App)
    })

    组件一中使用state中的lists 数据

    <template>
     <div id="productListOne">
       <h2>Product List One</h2>
       <ul>
         <li v-for="list in lists">
           <span class="name">{{ list.name }}</span>
           <span class="price">${{ list.price }}</span>
         </li>
       </ul>
     </div>
    </template>

    <script>
    export default {
     computed: {
         lists(){
             return this.$store.state.lists;
        }
    }
    };
    </script>

    组件二中使用getters中的newLists函数

    <template>
     <div id="productListOne">
       <h2>Product List One</h2>
       <ul>
         <li v-for="list in newlists">
           <span class="name">{{ list.name }}</span>
           <span class="price">${{ list.price }}</span>
         </li>
       </ul>
     </div>
    </template>

    <script>
    export default {
     computed: {
         // 使用getters中的函数,改变store中的值
         newlists(){
             return this.$store.getters.newLists;
        }
    }
    };
    </script>

    组件三中使用mutations中的函数

    <template>
     <div id="productListOne">
       <h2>Product List Two</h2>
       <ul>
         <li v-for="list in lists">
           <span class="name">{{ list.name }}</span>
           <span class="price">${{ list.price }}</span>
         </li>
       </ul>
    <!-- 定义事件 -->
       <button v-on:click="reducePrice">商品降价</button>
     </div>
    </template>

    <script>
    export default {
     computed: {
       lists() {
         return this.$store.state.lists;
      }
    },
     methods: {
       reducePrice: function() {
         //   this.$store.state.lists.forEach(element => {
         //       element.price -= 1;
         //   });
         // 出发vuex中的事件  
         this.$store.commit("reducePrice");
      }
    }
    };
    </script>

    组件四中使用actions,功能类似与mutations

    <template>
     <div id="productListOne">
       <h2>Product List Two</h2>
       <ul>
         <li v-for="list in lists">
           <span class="name">{{ list.name }}</span>
           <span class="price">${{ list.price }}</span>
         </li>
       </ul>
       <button v-on:click="reducePrice(3)">商品降价</button>
     </div>
    </template>

    <script>
    export default {
     computed: {
       lists() {
         return this.$store.state.lists;
      }
    },
     methods: {
       reducePrice: function(amount) {
          // 出发action且传参
          this.$store.dispatch('reducePrice', amount);
      }
    }
    };
    </script>

     

    Vuex-Mapping Actions & Getters

    安装语法支持:$ npm install babel-preset-stage-2 --save-dev

    // babelrc文件中设置 stage-2
    import {mapGetters} from 'vuex'
    import {mapActions} from 'vuex'
    methods: {
       reducePrice: function(amount) {
         this.$store.dispatch("reducePrice", amount);
      },
       // 简化
       ...mapActions(["reducePrice"])
    }
    computed: {
         newlists(){
             return this.$store.getters.newLists;
        },
         // 简化
         ...mapGetters([
             'newLists'
        ])
    }

     

    Tips

    谷歌插件Vue.js devtools
    问题:[npm ERR! code ELIFECYCLE]
    • npm cache clean --force

    • delete node_modules folder

    • delete package-lock.json file

    • npm install

    声明周期:

     

  • 相关阅读:
    毕业设计-1.11
    毕业设计-1.10
    毕业设计-1.09
    毕业设计-1.08
    毕业设计-1.07
    [工具]Maven的安装和配置【MyEclipse】
    毕业设计-1.06
    tomcat部署项目时省略项目名
    Jenkins实现iOS项目自动化打包(含踩坑记录)
    钉钉小程序封装网络请求
  • 原文地址:https://www.cnblogs.com/cshaptx4869/p/11185767.html
Copyright © 2020-2023  润新知