首页 > 技术文章 > vue

alongup 2019-01-05 22:14 原文

  1 1.Vue项目的创建
  2     (1) 检测node版本号 node-v
  3     (2) 检测webpack的版本号 webpack -v
  4     (3) npm i vue-cli -g
  5     (4) vue init webpack -y 
  6     (5) cd '文件名'
  7     (6) npm start
  8 2.Vue项目使用Sass
  9       1.npm install node-sass sass-loader --save-dev
 10       2.打开webpack.base.config.js在loaders里面加上  module -- rules (vue2.0)
 11       {
 12         test: /\.scss$/,
 13         loaders: ["style", "css", "sass"]
 14       }
 15 3.Vue中使用Less
 16       1.npm install less less-loader --save-dev
 17       2.打开webpack.base.config.js在loaders里面加上  module -- rules (vue2.0)
 18       {
 19             test: /\.less$/,
 20             loader: "style-loader!css-loader!less-loader",
 21       }
 22 4.pug模板引擎安装
 23       1.npm install  pug-cli -g
 24       2.
 25         {
 26           test: /\.pug$/,
 27           loader: 'pug'
 28         }
 29 5.生命周期钩子函数
 30     注:所有的声明周期钩子都是自动绑定this,因此你可以在钩子函数中对属性和方法进行计算。(不可以使用箭头函数)
 31       1.beforeCreate:在实例化初始之后,数据观测和event/watcher事件配置之前被调用;
 32       2.created:在实例化创建完成之后立即被调用,这个时候,实例化已经完成以下配置:数据监测,属性和方法的运算,watch/event事件的回调。然而,挂载还没开始,$el属性目前不可见。
 33       3.beforeMount:在挂载开始之前被调用:相关的render函数首次被调用;
 34       4.mounted:el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。
 35       5.beforeUpdate:数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
 36       6.updata:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。
 37       7.activated:keep-alive 组件激活时调用。
 38       8.deactivated:keep-alive 组件停用时调用。
 39       9.beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
 40       10.destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
 41       11.errorCaptured:类型:(err: Error, vm: Component, info: string) => ?boolean
 42       当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
 43 
 44 6.Vue路由传参
 45       1.配置路由 {name:'user',path:'/user/:id',component:user}
 46       2.跳转时对<router-link>进行配置
 47          <router-link to="/user/123" >登录123</router-link>
 48          <router-link :to="{name:'user',params:{id:'456'},query:{a:1,b:2}}">登录456</router-link>
 49       3.在user组件中取到传过来的参数
 50          取到user组件的路径{{this.$route.path}}
 51          取到传过来的id{{this.$route.params.id}}
 52          取到传过来的对象{{this.$route.query}}
 53 
 54 7.Vuex
 55      vuex是一个专门为vue.js设计的集中式状态管理架构。
 56      1.State:单一状态树,也被人做为是唯一数据源。(存储数据)
 57      2.Getter:可以认为是store的计算属性,getter的返回值会根据它的依赖被缓存起来,只有它的依赖发生了改变才会被重新计算。
 58      3.Mutation:更改store的状态的方法就是提交mutatin,这个api类似于一个事件,每个mutation都会有一个字符串的事件类型和一个回调函数,在回调函数中处理状态更改。
 59      4.Action:类似于Mutation,不同的是在Action提交的是mutation,而不是直接变更状态。Action可以包含任意异步的操作
 60      5.module:使用单一状态树,应用所有的状态都会集中到一个比较大对象。当应用比较庞大的时候,store就会变得很臃肿。这时候就可以将store分割成模块module。每个模块都拥有自己的state,getter,mutation,action
 61 
 62 8.脚手架3.0安装
 63       npm i -g vue-cli@3.0
 64 
 65 9.1指令
 66       1.文本插值 v-once
 67             <span>Message: {{ msg }}</span>
 68             <span v-once>This will never change: {{ msg }}</span> 通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新    
 69       2.纯HTML v-html
 70             <div v-html="rawHtml"></div>  双大括号会将数据解释为纯文本,而非 HTML
 71       3.条件判断 v-if
 72             <p v-if="seen">Now you see me</p>   v-if 指令将根据表达式 seen 的值的真假来移除/插入 <p> 元素。
 73       4.v-bind
 74             <a v-bind:href="url"></a>     这里 href 是参数,告知 v-bind 指令将该元素的 href 属性与表达式 url 的值绑定。
 75       5.v-on
 76             <a v-on:click="doSomething">  用于监听DOM事件
 77             <a @click="doSomething">
 78       6.v-model 数据的双向绑定
 79       7.<form v-on:submit.prevent="onSubmit"></form>  .prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()
 80       8.v-text
 81       9.v-for
 82       10.v-show
 83 9.2指令缩写
 84       1.v-bind缩写
 85             <a v-bind:href="url"></a>     <!-- 完整语法 -->
 86             <a :href="url"></a>     <!-- 缩写 -->
 87       2.v-on缩写
 88             <a v-on:click="doSomething"></a>    <!-- 完整语法 -->
 89             <a @click="doSomething"></a>  <!-- 缩写 -->
 90 10.计算属性computed
 91       1.默认开始会计算一次
 92       2.必须要有return返回值
 93       3.依赖的值发生改变时,会重新开始计算返回新的值
 94 11.Class与Style的绑定
 95       1.对象语法
 96             classactive 的更新将取决于数据属性 isActive 是否为真值
 97       2.数组语法
 98             <div v-bind:class="[activeClass, errorClass]">  
 99             data: {
100               activeClass: 'active',
101               errorClass: 'text-danger'
102             }
103             --><div class="active text-danger"></div>
104       3.1绑定内联样式
105             <div v-bind=“{ color: activeColor, fontSize: fontSize + 'px' }”></div>
106             data: {
107               activeColor: 'red',
108               fontSize: 30
109             }
110       3.2绑定对象
111             <div v-bind:style="styleObject"></div>
112             data: {
113               styleObject: {
114                 color: 'red',
115                 fontSize: '13px'
116               }
117             }
118       3.3数组语法
119             <div v-bind:style="[baseStyles, overridingStyles]">
120 12.事件修饰符
121       1.阻止事件冒泡    event.stopPropagation()
122       2.阻止默认事件    event.preventDefault()
123       3.
124             <!-- 阻止单击事件冒泡 -->
125             <a v-on:click.stop="doThis"></a>
126       4.
127             <!-- 提交事件不再重载页面 -->
128             <form v-on:submit.prevent="onSubmit"></form>
129       5.
130             <!-- 阻止默认事件  -->
131             <a v-on:click.stop.prevent="doThat"></a>
132       6.
133             <!-- 添加事件侦听器时使用事件捕获模式 -->
134             <div v-on:click.capture="doThis">...</div>
135       7.
136             <!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
137             <div v-on:click.self="doThat">...</div>
138       8.
139             全部的按键别名:enter、tab、delete (捕获 “删除” 和 “退格” 键)、esc、space、up、down、left、right
140             可以通过全局 config.keyCodes 对象自定义按键修饰符别名:
141             // 可以使用 v-on:keyup.f1
142             Vue.config.keyCodes.f1 = 112
143       9.
144             <!-- 只有在 keyCode 是 13 时调用 vm.submit() -->
145             <input v-on:keyup.13="submit">
146             <input v-on:keyup.enter="submit">
147             <input @keyup.enter="submit">
148 13.表单事件绑定
149       1.
150             <input v-model="message" placeholder="edit me">
151             <p>Message is: {{ message }}</p>
152       2.多个勾选框,绑定到同一个数组
153             <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
154             <label for="jack">Jack</label>
155             <input type="checkbox" id="john" value="John" v-model="checkedNames">
156             <label for="john">John</label>
157             <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
158             <label for="mike">Mike</label>
159             <br>
160             <span>Checked names: {{ checkedNames }}</span>
161             new Vue({
162               el: '...',
163               data: {
164                 checkedNames: []
165               }
166             })
167       3.单选按钮
168             <input type="radio" id="one" value="One" v-model="picked">
169             <label for="one">One</label>
170             <br>
171             <input type="radio" id="two" value="Two" v-model="picked">
172             <label for="two">Two</label>
173             <br>
174             <span>Picked: {{ picked }}</span>
175             new Vue({
176               el: '...',
177               data: {
178                 picked: ''
179               }
180             })
181       4.单选列表
182             <select v-model="selected">
183               <option>A</option>
184               <option>B</option>
185               <option>C</option>
186             </select>
187             <span>Selected: {{ selected }}</span>
188             new Vue({
189               el: '...',
190               data: {
191                 selected: ''
192               }
193             })
194       5.在默认情况下, v-model 在 input 事件中同步输入框的值与数据,但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步
195             <input v-model.lazy="msg" >
196       6.如果想自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN 则返回原值),可以添加一个修饰符 number 给 v-model 来处理输入值
197             <input v-model.number="age" type="number">
198       7.如果要自动过滤用户输入的首尾空格,可以添加 trim 修饰符到 v-model 上过滤输入
199             <input v-model.trim="msg">
200 14.组件
201       1.组件注册(全局)
202             Vue.component('my-component', {
203               template: '<div>A custom component!</div>'
204             })
205       2.组件注册(局部)
206             var Child = {
207               template: '<div>A custom component!</div>'
208             }
209             new Vue({
210               // ...
211               components: {
212                 // <my-component> 将只在父模板可用
213                 'my-component': Child
214               }
215             })
216 15.Props
217       一般用于父->子传递数据,单向,不可逆,不可变
218       <child message="hello!"></child>
219       Vue.component('child', {
220         // 声明 props
221         props: ['message'],
222         // 就像 data 一样,prop 可以用在模板内
223         // 同样也可以在 vm 实例中像 “this.message” 这样使用
224         template: '<span>{{ message }}</span>'
225       })
226       (误区)1
227             <!-- 传递了一个字符串"1" -->
228             <comp some-prop="1"></comp>
229             <!-- 传递实际的数字 -->
230             <comp v-bind:some-prop="1"></comp>
231 16.单向数据流
232       prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。
233       另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop 。如果你这么做了,Vue 会在控制台给出警告。
234 17.自定义事件
235       使用 $on(eventName) 监听事件
236       使用 $emit(eventName) 触发事件
237       尽管它们的运行类似,但是$on 和 $emit 不是addEventListener 和 dispatchEvent 的别名。
238 18.非父子间通讯
239       var bus = new Vue()
240       // 触发组件 A 中的事件
241       bus.$emit('id-selected', 1)
242       // 在组件 B 创建的钩子中监听事件
243       bus.$on('id-selected', function (id) {
244         // ...
245       })
246 19.使用slots内容分发
247       <slot></slot>
248 20.keep-alive
249       如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数
250       <keep-alive>
251         <component :is="currentView">
252           <!-- 非活动组件将被缓存! -->
253         </component>
254       </keep-alive>
255 21.子组件索引
256       ref $refs
257 22.异步组件
258       Vue.component('async-example', function (resolve, reject) {
259         setTimeout(function () {
260           resolve({
261             template: '<div>I am async!</div>'
262           })
263         }, 1000)
264       })
265 23.内联模板
266       <my-component inline-template>
267         <div>
268             <p>内联模板</p>
269         </div>
270       </my-component>
271 24.使用v-once的低级静态组件(当组件中包含大量静态内容时,可以考虑使用 v-once 将渲染结果缓存起来)
272       Vue.component('terms-of-service', {
273         template: '\
274           <div v-once>\
275             <h1>Terms of Service</h1>\
276             ... a lot of static content ...\
277           </div>\
278         '
279       })
280 25.单元素组件的过渡
281       Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加 entering/leaving 过渡
282       v-enter: 定义进入过渡的开始状态。在元素被插入时生效,在下一个帧移除。
283       v-enter-active: 定义进入过渡的结束状态。在元素被插入时生效,在 transition/animation 完成之后移除。
284       v-leave: 定义离开过渡的开始状态。在离开过渡被触发时生效,在下一个帧移除。
285       v-leave-active: 定义离开过渡的结束状态。在离开过渡被触发时生效,在 transition/animation 完成之后移除。
286 26.自定义指令
287       el: 指令所绑定的元素,可以用来直接操作 DOM 。
288       binding: 一个对象,包含以下属性:
289       name: 指令名,不包括 v- 前缀。
290       value: 指令的绑定值, 例如: v-my-directive="1 + 1", value 的值是 2291       oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
292       expression: 绑定值的字符串形式。 例如 v-my-directive="1 + 1" , expression 的值是 "1 + 1"293       arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 "foo"294       modifiers: 一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。
295       vnode: Vue 编译生成的虚拟节点,查阅 VNode API 了解更多详情。
296       oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
297       1.全局指令
298             <div v-theme:column="'narrow'"></div>
299             Vue.directive('theme',{
300                   bind(el,binding,vnode,oldVnode){
301                         if (binding.value == 'wide') {
302                               el.style.maxWidth = "1260px";
303                         } else if (binding.value == 'narrow') {
304                               el.style.maxWidth = "560px";
305                         }
306                         if (binding.arg == 'column') {
307                               el.style.background = 'rgba(16, 199, 190, 0.5)';
308                               el.style.padding = '20px';
309                         }
310                   }
311             })
312       2.局部指令
313             directive('theme',{
314                   bind(el,binding,vnode,oldVnode){
315                         if (binding.value == 'wide') {
316                               el.style.maxWidth = "1260px";
317                         } else if (binding.value == 'narrow') {
318                               el.style.maxWidth = "560px";
319                         }
320                         if (binding.arg == 'column') {
321                               el.style.background = 'rgba(16, 199, 190, 0.5)';
322                               el.style.padding = '20px';
323                         }
324                   }
325             })
326 27.组件通讯
327       1.父->328             1.1父组件
329                   Children(:name='msg')
330                   data () {
331                     return {
332                       msg: '我是father的数据'
333                     }
334                   }
335             1.2子组件
336                   定义:
337                         1.props: ['name']
338                         2.props: {
339                               name: Array  //希望传递的数据为数组类型 如果不是会发出警告
340                         }
341                         3(推荐写法).props: {
342                               childMsg: {
343                                     type: Array,
344                                     default: [0,0,0] //这样可以指定默认的值
345                               }
346                         }
347                   调用:{{name}}
348       2.子->349             2.1通过在子组件上定义方法,子组件通过this.$emit发送数据(父组件)
350                   Children(@hand='hand')
351                   hand (msg) {
352                     alert(msg)
353                   }
354             2.2(子组件)
355                   input(type='button' value='clickMe' @click='handle')
356                   handle () {
357                     this.$emit('hand', this.msg)
358                   }
359       3.
360             this.$parent     访问父组件
361 
362             this.$children   访问子组件(是一个数组)
363 
364             this.$root       根实例的后代访问根实例
365       4.兄弟组件传值
366             1.引入事件线
367                   定义一个组件做为桥梁,并引入到兄弟组件中
368                   import Vue from 'vue'
369                   export default new Vue()
370             2.第一个兄弟组件
371                   button(@click='show') 向on组件传值
372                   show () {
373                     bus.$emit('user', 'haha')
374                   }
375             3.第二个兄弟组件
376                   .cont 接受emit组件的数据:{{msg}}
377                   mounted () {
378                     let self = this
379                     bus.$on('user', (msg) => {
380                       self.msg = msg
381                     })
382                   }
383 
384 28.vue图片懒加载
385   https://www.cnblogs.com/xyyt/p/7650539.html
386   1.安装插件: npm i vue-lazyload --sava-dev
387   2.mai.js引入插件:
388     import VuewLazyLoad from 'vue-lazyload'
389     Vue.use(VuewLazyLoad,{
390       error: './static/error.png',
391       loading: './static/loading.png'
392     })
393   3. vue文件中将需要懒加载的图片绑定 v-bind:src 修改为 v-lazy 
394     <img class="item-pic" v-lazy="newItem.picUrl"/>
395 
396 29.vue自定义指令
397   例:自定义一个全局指令 v-focus自动或焦
398   Vue.directive('focus',{
399     inserted: function (el) {
400       el.focus()
401     }
402   })
403 
404 30.vue导航回弹组件
405   https://github.com/ScoutYin/ly-tab
406 
407 31.Vue路由守卫
408   1.全局守卫
409     router.beforeEach((to, from, next) => { //默认调用
410       // console.log(to)
411       // console.log(from)
412       next()
413     })
414 
415     router.afterEach((to, from) => {  // 作用:查明路由去向 to-from
416       // console.log(to)
417       // console.log(from)
418     })
419   2.组件内守卫
420     2.1)beforeRouteEnter 是组件内的路由导航守卫,在确认渲染该组件的对应路由前调用。该守卫不能访问 this,但我们通过传一个回调给 next,就可以使用上面的 vm 来访问组件实例。守卫的参数说明如下:
421       to:即将要进入的目标路由;
422       from:当前导航正要离开的路由,from.name 是路由的名称,对应路由配置中的 name;
423       next:一个用来 resolve 当前钩子的方法,需要调用该方法来确认或者中断导航;
424     2.2)参数 to 和 from 都是 路由对象 (route object),表示当前激活的路由的状态信息,其常用的属性有:
425       name:路由的名称,如 'Register'426       path:路由的路径,如 '/auth/register'427       params:路由参数对象,如 { id: "1" };
428       query:URL 查询参数对象,如 { page: "1" };
429       meta:元信息对象,如 { auth: true };
430       beforeRouteEnter(to, from, next) {  //进入组件执行
431         next(vm => {
432           // 通过 vm 参数访问组件实例
433           if (vm.$store.state.isLogin) {
434           }else{
435             console.log('组件内守卫');
436           }
437         })
438       },
439       beforeRouteLeave(to, from, next) {  //离开组件执行
440         if(confirm("确定离开吗?") == true){
441           next()   //跳转到另一个路由
442         }else{
443           next(false);//不跳转
444         }
445       }
446     3.路由独享守卫
447       {
448        path: '/foo',
449        component: Foo,
450        beforeEnter: (to, from, next) => {
451         // ...
452        }
453       }
454 
455 32.解决跨域问题
456   1.万能(后台更改)
457     header('Access-Control-Allow-Origin:*');//允许所有来源访问 
458     header('Access-Control-Allow-Method:POST,GET');//允许访问的方式
459   2.jsonp
460     methods: { 
461       getData () { 
462         var self = this 
463         $.ajax({ 
464           url: 'http://f.apiplus.cn/bj11x5.json', 
465           type: 'GET', 
466           dataType: 'JSONP', 
467           success: function (res) { 
468             self.data = res.data.slice(0, 3) 
469             self.opencode = res.data[0].opencode.split(',') 
470           } 
471         }) 
472       } 
473     }   
474   3.使用http-proxy-middleware 代理解决
475     例如请求的url:“http://f.apiplus.cn/bj11x5.json”
476     3.1、打开config/index.js,在proxyTable中添写如下代码:
477       proxyTable: { 
478         '/api': {  //使用"/api"来代替"http://f.apiplus.c" 
479           target: 'http://f.apiplus.cn', //请求的地址 
480           changeOrigin: true, //改变源 
481           pathRewrite: { 
482             '^/api': 'http://f.apiplus.cn' //路径重写 
483             } 
484         } 
485       }
486       3.2、使用axios请求数据时直接使用“/api”:
487         getData () { 
488          axios.get('/api/bj11x5.json', function (res) { 
489            console.log(res) 
490          })
491       3.3通过这中方法去解决跨域,打包部署时还按这种方法会出问题。解决方法如下:
492         let serverUrl = '/api/'  //本地调试时 
493           // let serverUrl = 'http://f.apiplus.cn/'  //打包部署上线时 
494           export default { 
495             dataUrl: serverUrl + 'bj11x5.json' 
496           }
497 33.获取服务器时间接口
498   http://f.apiplus.net/time.json

 学习vue的一些笔记,希望可以帮助到大家,减少一些弯路,不懂得多多交流.这些都是我一点点总结下来的,可能有写的不好的地方,还希望大家多多支出,一起学习,一起进步.喜欢的可以关注一下哈,后面我会经常更新的哈...   

做自己喜欢的事,是一件很开心、很幸福的事情,希望你们一直能坚持自己的初衷,不要放弃,在这条路上越走越远.

推荐阅读