今天也是阳光正好

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

# vue笔记

一、vue项目文件加载顺序

index.html、main.js、app.vue、router\index.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
        }
      ]
    }
  ]
 })

 

posted on 2021-03-30 23:51  今天也是阳光正好  阅读(95)  评论(0编辑  收藏  举报