zoukankan      html  css  js  c++  java
  • vue笔记

    # vue笔记

    一、vue项目文件加载顺序

    index.html、main.js、app.vue、routerindex.js、helloword.vue

    二、new Vue

     new Vue({
     el: '#app',
     components:{App},
     template: '<App/>'
     })
    • components 是声明有哪些组件

    • template 是使用哪个组件

    • el: '#app' 是index.html 的<div id="app"></div>

    • App.vue <div id="app">xxxxxxxx</div> 会替换和index中的<div id="app"></div>

    • index.html 中<div id="app"></div> 这个是convention(约定、习俗),可以改。只要id和生成Vue实例时el的参数值保持一致即可。

    vue 2.0以上可以写成

     new Vue({
     router,
     store,
     render: h => h(App)
     }).$mount('#app')
    • render函数是vue通过js渲染dom结构的函数createElement,约定可以简写为h; 实际渲染和components:{App},template: '<App/>'一样

    • 在Vue构造函数时,需要配置一个el属性,如果没有没有el属性时,可以使用.$mount('#app')进行挂载。

    三、export和export default区别

    1. 导出

    • export

    export 可以直接导出或者先定义后导出都可以。 示例: export let i = “hello”; export function myFun(){}; 上面的直接导出,也可以使用下面先定义后导出。 let i = “hello"; function myFun(){}; export {i , myFun}

    • export default

    export default是模块的默认对外接口,只有一个,所以只能出现一次。

    export default只能直接输出,不能先定义后导出。

    1. 导入

    通过两者导出的对象,导入时也存在写法上的差别。

    • export导出的对象,导入时写法:

    import {i, myFun}

    • export default导出的对象,导入时写法:

    import 变量名 from ‘模块’ 很明显,模块只有一个默认的导出的接口,所以只有一个对象被导出,导出的对象可以自定义一个变量名

    四、Vue.use()使用插件:

    1. 编写插件

    Vue.js插件应该公开一个install方法。该方法将以Vue构造函数作为第一个参数以及可能的选项进行调用:

     MyPlugin.install = function (Vue, options) {
      // 1. add global method or property
      // new Vue().myGlobalMethod
      Vue.myGlobalMethod = function () {
      }
     
      // 2. add a global asset
      // v-my-directive
      Vue.directive('my-directive', {
        bind (el, binding, vnode, oldVnode) {
        }
      })
     
      // 3. inject some component options
      Vue.mixin({
        created: function () {
        }
      })
     
      // 4. add an instance method
      // this.$myMethod
      Vue.prototype.$myMethod = function (methodOptions) {
      }
     }
    1. 使用插件

    通过调用Vue.use()全局方法来使用插件:

     Vue.use(MyPlugin)

    您可以选择传递一些选项:

     Vue.use(MyPlugin, { someOption: true })

    Vue.use 会自动阻止你多次使用同一个插件,所以在同一个插件上多次调用它只会安装一次插件。

    五、@和./的区别

    ./表示相对路径,具体代表当前目录下的同级目录,遵从的是从后往前找文件

    @/的意思: 表示的是相对路径(当然这也是简写啦),因为这个在根目录/build/webpack.base.conf.js文件中@是配置的, 比如我的配置文件中@就代表src目录,遵从的是从前往后找,比如’@/components/login’ 就表示的是src/components/login文件

    • /build/webpack.base.conf.js

       resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
          'vue$': 'vue/dist/vue.esm.js',
          '@': resolve('src'),
        }
      },

    六、Vue.prototype.$xx = xx

    为什么初始化的时候运行了Vue.prototype.$utils, 然后就可以在任意组件内部运行this.$utils()了呢?

    每一个vue组件都是Vue的实例,所以组件内this可以拿到Vue.prototype上添加的属性和方法。

    七、过滤器

    1. 定义

    分为全局定义和局部定义两种方式:

     // 全局注册
     Vue.filter('toRMB', function (value) {
      return `¥${value}`
     })
     
     // 局部注册 (和method同级)
      filters: {
        toFixed: function(money) {
          return money.toFixed(1)
        },
      },
    1. 使用

    在双花括号中使用管道符(pipeline) |隔开,或者v-bind表达式(v2.1.0以上支持)

     <h2>过滤器的使用-添加前缀</h2>
     <p>{{352.11 | toRMB}}</p>
     <p>{{657 | toRMB}}</p>
     <p>{{657.22 | toFixed }}</p>
     <p>{{money | toFixed }}</p>

    还可以链式使用,注意先后的顺序,如下面的先添加¥符号再进行小数位变换将会出错,因此要注意先后顺序

     <p>{{ money | toFixed | toRMB }}</p>
    1. 过滤器函数的多层参数

    是指接收的参数不止value这一个,还可以添加lengthsuffix参数

     suffix参数
     
     <h2>多重参数</h2>
     <p>{{text}}</p>
     <p>{{text | readMore(20,'...')}}</p>
     new Vue({
      el: '#app',
      data: {
        text: 'hello I love u, will u love me ?',
      },
      filters: {
        readMore: function (value,length,suffix) {
      return value.substr(0,length) + suffix;
        },
      }
     })

    八、axios

    语法:

     axios.post('/user', {
        firstName: 'Fred',
        lastName: 'Flintstone'
      })
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
     
     axios.get('/user', {
        params: {
          ID: 12345
        }
      })

    可以通过向 axios 传递相关配置来创建请求 axios(config):

     // 发送 POST 请求
     axios({
      method: 'post',
      url: '/user/12345',
      data: {
        firstName: 'Fred',
        lastName: 'Flintstone'
      }
     });

    可以使用自定义配置新建一个axios 实例,并配置好基础属性

     const instance = axios.create({
      baseURL: 'https://some-domain.com/api/',
      timeout: 1000,
      headers: {'X-Custom-Header': 'foobar'}
     })
      //再使用具体相关配置发送请求:
     instance(config);

    在使用axios发送post请求时,默认的请求头Content-Type的属性值为application/json

    改变Content-Type可以使用:

     import qs from 'qs';
     const data = { 'bar': 123 };
     const options = {
      method: 'POST',
      headers: { 'content-type': 'application/x-www-form-urlencoded' },
      data: qs.stringify(data),
      url,
     };
     axios(options);

    拦截器

    在请求被 then 或 响应被 catch前处理前拦截它们。

     // 添加请求拦截器
     axios.interceptors.request.use(function (config) {
        // 在发送请求之前做些什么
        return config;
      }, function (error) {
        // 对请求错误做些什么
        return Promise.reject(error);
      });
     
     // 添加响应拦截器
     axios.interceptors.response.use(function (response) {
        // 对响应数据做点什么
        return response;
      }, function (error) {
        // 对响应错误做点什么
        return Promise.reject(error);
      });

    如果你想在稍后移除拦截器,可以这样:

     const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
     axios.interceptors.request.eject(myInterceptor);

    可以为自定义 axios 实例添加拦截器

     const instance = axios.create();
     instance.interceptors.request.use(function () {/*...*/});

    validateStatus:可以放在config里面,统一配置正确的请求返回状态码

     validateStatus: function (status) {
      return status >= 200 && status < 300; // 结果返回true都显示请求成功
     },

    Promise

    参考链接

    具体使用时: resolve —>对应then reject —>对应catch 另外,只有调用了resolve 或者reject 才会触发 then 和 catch

    九、package.json和package-lock.json的区别

    package.json文件只能锁定大版本,即版本号的第一位,不能锁定后面的小版本,你每次npm install时候拉取的该大版本下面最新的版本。所以为了稳定性考虑我们不能随意升级依赖包,而package-lock.json就是来解决包锁定不升级问题的。

    如果要升级package-lock.json里面的库包,怎么操作呢?

    npm install packageName 或 npm install packageName@x.x.x

    十、Computed和Watch的用法及区别

    1. 计算属性compute(由多个值计算出这个值)

         <div id="app">
            {{ changewords }} // 渲染 不用写()
         </div>
     </body>
     <script>
         var vm = new Vue({
                 el: "#app",
                 data:{},
             // 计算属性
                 computed:{
                     changewords(){
                         return this.myname.substring(0,1).toUpperCase() + this.myname.substring(1)
                    }
                }
          })
     </script>

    总结

    • 变量不在 data中定义,而是定义在computed中,写法跟写方法一样,有返回值。函数名直接在页面模板中渲染,不加小括号 。

    • 根据传入的变量的变化 进行结果的更新。

    • 计算属性基于响应式依赖进行缓存。如其中的任意一个值未发生变化,它调用的就是上一次 计算缓存的数据,因此提高了程序的性能。而methods中每调用一次就会重新计算 一次,为了进行不必要的资源消耗,选择用计算属性。

    1. 监听属性(监听到这个值发生变化从而去改变其它的值)

     new Vue({
        el: '#id',
        template: `<div>
            // ...
         </div>`,
        data: {
            firstName: 'Leo',
            lastName: 'Alan',
            obj1: {
                a: 0
            }
        },
        watch: {
            // 监听firstName,当firstName发生变化时就会执行该函数
            firstName () {
                // 执行需要的操作...
                // 注:初始化不会执行,只有当被监听的值(firstName)发生变化时才会执行
            },
     
            // 监听lastName
            lastName: {
                handler (newName, oldName) {
                    // 执行需要的操作...
                },
                immediate: true // true: 初始化时就会先执行一遍该监听对应的操作    
            },
     
            obj1: {
                handler () {
                    // 执行需要的操作...
                },
                deep: true // 该属性默认值为false.
                // 当被监听的值是对象,只有deep为true时,对应属性的值(obj1.a)发生变化时才能触发监听事件,但是这样非常消耗性能
            },
     
            // 监听对象具体的属性, deep就不需要设置为true了
            'obj1.a': {
                handler () {
                    // 执行需要的操作...
                }
            }
        }
     })
    1. 计算属性 和 属性监听的区别:

    • 计算属性变量在computed中定义,属性监听在data中定义。

    • 计算属性是声明式的描述一个值依赖了其他值,依赖的值改变后重新计算结果更新DOM。属性监听的是定义的变量,当定义的值发生变化时,执行相对应的函数。

    十一、$nextTick的使用

    当你修改了data的值然后马上获取这个dom元素的值,是不能获取到更新后的值,因为dom元素还没有更新。 你需要使用$nextTick这个回调,让dom元素更新修改后的data值之后再获取,才能成功。

    • 在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作并无作用,而在created()里使用this.$nextTick()可以等待dom生成以后再来获取dom对象

    • 在下面方法里直接打印的话, 由于dom元素还没有更新, 因此打印出来的还是未改变之前的值,而通过this.$nextTick()获取到的值为dom更新之后的值

      methods: {
          get() {
            this.value = '你好啊';
            console.log(this.$refs['hello'].innerText);
            this.$nextTick(() => {
              console.log(this.$refs['hello'].innerText);
            });
          }
        },

    十二、渐进式框架的理解

    答:主张最少;不必一开始就使用全家桶,可以根据不同的需求选择不同的层级;

    十三、双向绑定

    https://www.cnblogs.com/webcabana/p/11077628.html

    https://segmentfault.com/a/1190000014274840

    img

    • observer就是利用 Object.defineProperty当属性发生变化时,会触发set方法,在set里面触发更新函数

    • warcher里面定义了根据data改变view的方法-更新函数,从而更新视图。

    • compile为每个指令的dom绑定了warcher的更新函数 。还有根据view改变data值的方法,此时会触发observer。

    十四、生命周期

    vue实例有一个完整的生命周期,生命周期也就是指一个实例从开始创建到销毁的这个过程

    • beforeCreate() 在实例创建之间执行,数据未加载状态

    • created() 在实例创建、数据加载后,能初始化数据,dom渲染之前执行

    • beforeMount() 虚拟dom已创建完成,在数据渲染前最后一次更改数据

    • mounted() 页面、数据渲染完成,真实dom挂载完成

    • beforeUpadate() 重新渲染之前触发

    • updated() 数据已经更改完成,dom 也重新 render 完成,更改数据会陷入死循环

    • beforeDestory()destoryed() 前者是销毁前执行(实例仍然完全可用),后者则是销毁后执行

    十五、父子组件之间的传值

    1. 父向子传值props 父:<child :title="name"> 子:

       props: {
          title: {
            type: String,
            default: 'hello world'
          }
        }
    2. 子组件向父组件传值$emit 父:<child v-on:func="childByValue"></child> 子:this.$emit('childByValue', this.name)

    3. 在子组件中加上ref即可通过this.$refs.method调用 父: <children ref="refName"></children> this.$refs.refName.childMethods();

    4. 可以通过$parent和$children获取父子组件的参数

    十六、路由router

    • 动态路径参数

    1. query传参

    路由:

     var router = new VueRouter({
      routes: [
        { path: '/login', component: login },
        { name:'register',path: '/register', component: register }
      ]
     })

    导航:

     // 注意:这是 query 两种传参方式 一种是直接跳转把字符串传过去 一种是传描述目标位置的对象
     <router-link to="/login?id=10&name=zs">登录</router-link>
     <router-link :to="{path:'/register',query:{id:5,name:'lili'}}">注册</router-link>
     
     <router-link :to="{name:'register',query:{id:5,name:'lili'}}">注册</router-link>

    ** 注意:jquery可以通过name或path来引入路由**

    1. params传参

    路由:

     var router = new VueRouter({
      routes: [
        { path: '/login/:id/:name', component: login },// 这里不传入对应的参数(:/id/:name) 刷新页面 参数会消失,页面中就丢失了数据
        { name:'register', path: '/register/:id/:name', component: register }
      ]
     })

    导航:

     // 注意:这是 params 两种传参方式 一种是直接跳转把字符串传过去 一种是传描述目标位置的对象
         <router-link to="/login/12/ls">登录</router-link>
         <router-link :to="{name:'register',params:{id:10,name:'lili'}}">注册</router-link>
     等同于:
      this.$router.push('/login/12/ls')
      this.$router.push({name:'register',params:{id:10,name:'lili'}})

    注意:params只能通过name来引入路由,path会undefined

    params 是路由的一部分,在请求地址上。query 是拼接在 url 后面的参数 params 不设置的时候,刷新页面或者返回参数会丢,query 则不会有这个问题

     

    • 当使用一个通配符时,$route.params 内会自动添加一个名为 pathMatch 参数。它包含了 URL 通过通配符被匹配的部分:

     // 给出一个路由 { path: '/user-*' }
     this.$router.push('/user-admin')
     this.$route.params.pathMatch // 'admin'
     // 给出一个路由 { path: '*' }
     this.$router.push('/non-existing')
     this.$route.params.pathMatch // '/non-existing'
    • $route和$router的区别

    $routerVueRouter 实例,想要导航到不同 URL,则使用 $router.push 方法$route 为当前 router 跳转对象里面可以获取 namepathqueryparams

    • 嵌套路由传参

     const router = new VueRouter({
       routes: [
        {
           path: '/user/:id',
           component: User,
           children: [
                // 当 /user/:id 匹配成功,
             // UserHome 会被渲染在 User 的 <router-view> 中
            { path: '', component: UserHome },
            {
               // 当 /user/:id/profile 匹配成功,
               // UserProfile 会被渲染在 User 的 <router-view> 中
               path: 'profile',
               component: UserProfile
            },
            {
               // 当 /user/:id/posts 匹配成功
               // UserPosts 会被渲染在 User 的 <router-view> 中
               path: 'posts',
               component: UserPosts
            }
          ]
        }
      ]
     })

     

  • 相关阅读:
    asp 后台批量管理程序
    面经
    单例模式(singleton)解析例子
    互联网产品经理必读书籍
    Struts2中的OGNL表达式
    阿里巴巴面经
    Servlet/JSP如何控制页面缓存于squid中
    Java陷阱一箩筐面试题集及解答
    阿里巴巴笔经http://bbs.yingjiesheng.com/forum.php?mod=viewthread&tid=696098&extra=page%3D1%26filter%3Dtypeid%26typeid%3D6356%26typeid%3D6356
    阿里巴巴java笔试
  • 原文地址:https://www.cnblogs.com/liuyuan1227/p/14599500.html
Copyright © 2011-2022 走看看