写点什么

【初级】个人分享 Vue 前端开发教程笔记

用户头像
魔王哪吒
关注
发布于: 2021 年 02 月 01 日
【初级】个人分享Vue前端开发教程笔记

大家好,我是魔王哪吒,很高兴认识你~~


哪吒人生信条:如果你所学的东西 处于喜欢 才会有强大的动力支撑


每天学习编程,让你离梦想更新一步,感谢不负每一份热爱编程的程序员,不论知识点多么奇葩,和我一起,让那一颗四处流荡的心定下来,一直走下去,加油,2021加油!欢迎点赞、收藏和评论


不要害怕做梦,但是呢,也不要光做梦,要做一个实干家,而不是空谈家,求真力行。



前言


如果这篇文章有帮助到你,给个❤️关注,❤️点赞,❤️鼓励一下作者,接收好挑战了吗?文章公众号首发,关注 程序员哆啦 A 梦 第一时间获取最新的文章


❤️笔芯❤️~



作为一名 Vue 开发使用者,必须了解其使用规则。


Vue.js 的发展


前端发展的行业非常快,大部分学习者赶不上发展的速度,每天都在学习GoogleAngularJSFackbookReactJS,这些前端MVCMVVM)框架和组件化学习,加上Vue.js的出现,越来越多的前端投入了学习中。❤️


Vue.js是一个用来开发web界面的前端库,轻量级,具有响应式编程和组件化的特点。


hello world


引入vue.js


<script src="http://cdnjs.xxx"></script> // 使用CDN方法
复制代码


通过NPM进行安装:


npm install vue
复制代码


示例:


<div id="#app"> <h1>{{message}}</h1></div>
var vm = new Vue({ el: '#app', data: { message: 'hello world, 我是掘金,魔王哪吒' }})
复制代码


特点:数据绑定


在浏览器控制台vm.message='hello vue',输出结果hello vue,表示vm.message和视图中{{message}}是绑定的。


绑定用户输入的数据,视图会随着用户的输入而变化❤️


<div id="app"> <h1>dadaqianduan is {{message}}</h1>  <input type="text" v-model="message"></div>
复制代码


vm.message的值会随着用户在input中输入的值的变化而变化,而无需我们手动去获取DOM元素的值再同步到js中。


特点:组件化


可以自己定义html标签,在模板中使用它


示例:


<div id="app"> <message content="dadaqianduan"></message></div>
<script type="text/javascript"> var Message = Vue.extend({ props: ['content'], template: '<h1>{{content}}</h1>' }) Vue.component('message', Message); var vm = new Vue({ el: '#app', })</script>
复制代码


命令行工具:


$npm install --global vue-cli
$vue init webpack my-project
$cd my-project
$npm install
$npm run dev
复制代码


Vue 实例


vue.js的使用是通过构造函数Vue({option})创建一个vue的实例:var vm = new Vue({})


一个Vue实例相当于一个MVVM模式中的ViewModel,做图如下:



在实例化的时候,可以传入一个选项对象(数据,模板,挂载元素,方法,生命周期钩子) 等。


模板


el类型是字符串,DOM元素或者是函数,作用是为实例提供挂载元素。一般来说我们会使用css选择符,或是原生的DOM元素。


如:el:'#app',指定了el,实例将立即进入编译过程。


template类型为字符串,默认会将template值替换挂载元素,el值对应的元素,合并挂载元素和模板根节点的属性。


数据


vue实例中可以通过data属性定义数据,这些数据可以在实例对应的模板中进行绑定并使用。


示例:


var data = {a:1}

var vm = new Vue({ data: data})
vm.$data === data // truevm.a === data.a // true
vm.a = 2data.a // 2
data.a = 3vm.a // 3
复制代码


在模板中使用{{a}}就会输出vm.a的值,修改vm.a的值,模板中的值会随之改变,称为响应式数据。


组件类型的实例可以通过props获取数据,同data一样,也需要在初始化时预设好。


<my-component title="myTitle" content="myContent"></my-component>
var myComponent = Vue.component("my-component",{ props: ['title','content'], template: '<h1>{{title}}</h1><p>{{content}}</p>'})
复制代码


方法


methods对象中来定义方法,示例:


<button v-on:click="daBtn">dadaqianduan</button>
new Vue({ el: '#app', data: {a:1}, methods: { daBtn: function(){ console.log(this.a); } }});
复制代码


生命周期


beforeCreate,在实例开始初始化时同步调用,此时数据观测,事件等都尚未初始化。


created,在实例创建之后调用,此时已完成数据绑定,事件方法,但尚未开始DOM编译,即是未挂载到document中。


beforeMount,在mounted之前运行。


mounted,在编译结束时调用,此时所有指令已生效,数据变化已能触发DOM更新,但不保证$el已插入文档。


beforeDestroy,在开始销毁实例时调用。


destroyed,在实例被销毁之后调用,此时所有绑定和实例指令都已经解绑,子实例也被销毁。


updated,在实例挂载之后,再次更新实例并更新完DOM结构后调用。


activated,需要配合动态组件keep-live属性使用,在动态组件初始化渲染的过程中调用该方法。


文本插值


数据绑定基础形式是文本插值,使用{{}},为Mustache语法:


<span>hello {{name}}</span>
复制代码


单次插值:


<span v-once>{{name}}</span>
复制代码


HTML 属性


示例:


<div v-bind:id="'id-'+id"/></div>
<div :id="'id-'+id"></div>
复制代码


绑定表达式


放在Mustache标签内的文本内容称为绑定表达式。每个绑定中只能包含单个表达式,并不支持JavaScript语句,不支持正则表达式。


过滤器


vue允许在表达式后添加可选的过滤器,以管道符 "|"指示,可以有多个过滤器链式使用:


{{time | paramsTime}}
复制代码


计算属性


var vm = new Vue({ el: '#app', data: {  firstName: 'da',  lastName: '哪吒', } computed: {  fullName: function() {   // this 指向vm实例   return this.firstName + ' ' + this.lastName  } }});
<p>{{firstName}}</p><p>{{lastName}}</p><p>{{fullName}}</p>
复制代码


Setter


示例:


var vm = new Vue({ el: '#el', data: {  num: 100, } computed: {  price: {   set: function(newValue){    this.num = newValue * 100;   },   get: function() {    return (this.num/100).toFixed(2);   }  } }});
复制代码


表单控件


输入框示例:


<input type="text" v-model="message"/>
<span>dadaqianduan {{message}}</span>
复制代码


单选框示例:


<label><input type="radio" value="male" v-model="gender"> 男 </label><label><input type="radio" value="famale" v-model="gender"> 女 </label>
<p>{{gender}}</p>
复制代码


checkbox复选框,单个勾选框和多个勾选框


<input type="checkbox" v-model="checked"/>
<span>dadaqianduan{{checked}}</span>
复制代码


多个勾选框,v-model使用相同的属性名称,且属性为数组:


<label><input type="checkbox" value="1" v-model="multiChecked">1</lable><label><input type="checkbox" value="2" v-model="multiChecked">2</lable><label><input type="checkbox" value="3" v-model="multiChecked">3</lable><p>{{multiChecked.join('|')}}</p>
复制代码


select:


单选:


<select v-model="selected"> <option selected>A</option> <option>B</option> <option>C</option></select><span>dadaqianduan: {{selected}}</span>
复制代码


多选:


<select v-model="multiSelected" multiple> <option selected>A</option> <option>B</option> <option>C</option></select><span>dadaqianduan: {{multiSelected.join('|')}}</span>
复制代码


绑定 value


表单控件的值同样可以绑定在vue实例的动态属性上。


// checkbox<input type="checkbox" v-model="checked" v-bind:true-value="a" v-bind:false-value="b">
复制代码


选中:vm.checked==vm.a
未选中:vm.hchecked==vm.b
复制代码


class 与 style 绑定


class属性,绑定的数据可以是对象和数组


<div class="da" v-bind:class="{'active':active, 'unactive':!active}"></div>
vm实例中需要包含:data: { active: true}
复制代码


渲染结果:<div class="tab active"></div>


数组语法


<div v-bind:class="[classA, classB]"></div>
data: { classA: 'class-a', classB: 'class-b',}
复制代码


渲染结果:`<div class="class-a class-b'></div>


内联样式绑定


  1. 对象语法:直接绑定符合样式格式的对象


<div v-bind:style="dada"></div>
data: { dada: { color: 'green', fontSize: '10px' }}
复制代码


<div v-bind:style="{ fontSize: color: 'green' }"></div>
复制代码


  1. 数组语法:v-bind:style允许将多个样式对象绑定到统一元素上。


<div v-bind:style="[ styleObjectA, styleObjectB ]"></div>
复制代码


模板渲染


前端渲染的优点:


第一,业务分离,后端只需要提供接口,前端在开发时也不需要部署对应得后端环境,通过一些代理服务器工具就能远程获取后端数据进行开发,能够提升开发效率。


第二,计算量得转移,原本需要后端渲染得任务交给了前端,减轻了服务器得压力。


后端渲染的优点:


第一,对搜索引擎比较友好。


第二,首页加载时间端,后端渲染加载完成后就直接显示html,但前端渲染在加载完成后还需要有段js渲染的时间。


条件渲染


v-ifv-else的作用是根据数据值来判断是否输出该DOM元素,以及包含的子元素。


v-else必须紧跟v-if,不然该指令不起作用。


v-show元素的使用会渲染并保存在DOM中。只是切换元素的css属性display


v-ifv-show的条件发生变化时,v-if引起了dom操作级别的变化,而v-show仅仅发生了样式的变化,从切换的角度来说,v-show消耗的性能要比v-if小。


v-if切换时,vue.js会有一个局部编译/卸载的过程,因为 v-if 中的模板也可能包括数据绑定或子组件。v-if 会确保条件块在切换当中适当地销毁与中间内部的事件监听器和子组件。


v-if 是惰性的,如果在初始条件为假时,v-if 本身什么都不会做,而v-show 则仍会进行正常的操作,然后把 css 样式设置为 display:none


v-if 有更高的切换消耗而 v-show 有更高的初始渲染消耗


列表渲染


示例:


<ul><li v-for="item in items">   <h3>{{item.web}}</h3>   <p>{{item.da}}</p> </li></ul>var vm = new Vue({el : '#app', data: {   items : [    { title : 'web-1', description : 'da-1'},    { title : 'web-2', description : 'da-2'},    { title : 'web-3', description : 'da-3'},    { title : 'web-4', description : 'da-4'}   ] }});
复制代码


v-for 内置了 $index 变量,输出当前数组元素的索引,也可以自己指定索引的别名。`<li v-for="(index,item) in items">{{index}} –

{{$index}} – {{item.title}}</li>`


vue.js中提供了$set方法,修改数据的同时进行试图更新。


vm.$set('item[0]', {title: 'da'})
复制代码


修饰符


.stop: 等同于调用 event. stopPropagation()。


.prevent: 等同于调用 event.preventDefault()。


.capture: 使用 capture 模式添加事件监听器。

.self: 只当事件是从监听元素本身触发时才触发回调。


示例:


<form v-on:submit.prevent="onSubmit"></form> // 阻止表单默认提交事件
<form v-on:submit.stop.prevent="onSubmit"></form> // 阻止默认提交事件且阻止冒泡
<form v-on:submit.stop.prevent></form> // 也可以只有修饰符,并不绑定事件
复制代码


Vue.extend()


Vue.js 提供了 Vue.extend(options) 方法,创建基础 Vue 构造器的“子类”


Vue.component('child', Child) // 全局注册子组件<child ….></child> // 子组件在其他组件内的调用方式
var Child = Vue.extend({template : '#child',data : function() {   return {    ….   } }….})
复制代码


内置指令


v-bind用于动态绑定DOM元素属性attribute,元素属性实际的值是由vm实例中的data属性提供的。


<img v-bind:src="avatar"/>new Vue({ data: {  avatar: 'http://' }})
复制代码


v-text 需要绑定在某个元素上,能避免未编译前的闪现问题。


v-ref作用于子组件上,实例可以通过$refs访问子组件。


示例:


<message v-re:title content="title"></message><message v-ref:sub-title content="subTitle"></message>
var Message = Vue.extend({ props: ['content'], template: '<h1>{{content}}</h1>'});Vue.component('message', Message);
复制代码


v-pre指令,表示跳过编译这个元素和子元素,显示原始的{{}}Mustache标签,用来减少编译时间。


v-clock指令相当于在元素上添加一个[v-cloak]的属性,直到关联的实例结束编译。可以和css规则[v-cloak]{display:none}一起使用,可以隐藏未编译的Mustache标签直到实例准备完毕。


<div v-cloak>{{msg}}</div>
复制代码


v-once指令是用于标明元素或 组件只渲染一次,即使随后发生绑定数据的变化或更新,该元素或组件以及包含的子元素都不会再次被编译和渲染。


自定义指令


通过Vue.directive(id,definition)方法注册一个全局自定义指令,接收参数id和定义对象。id是指令的唯一标识,定义对象就是指令的相关属性以及钩子函数。


Vue.directive('global-directive', definition)


<div v-global-directive></div>
复制代码


局部注册:


var com = Vue.extend({ directives: {  'localDirective': {} }});
复制代码


指令实例属性


  1. el指令绑定的元素

  2. vm,该指令的上下文ViewModel,可以为new Vue()的实例,也可以为组件实例。

  3. expression,指令的表达式,不包括参数和过滤器

  4. arg,指令的参数

  5. name,指令的名字

  6. modifiers,一个对象,包含指令的修饰符

  7. descriptor,一个对象,包含指令的解析结果


过滤器


vue.js可以在表达式后面添加可选的过滤器,以管道符表示:


{{time | paramsTime }}
复制代码


过滤器的本质是一个函数,接受管道符前面的值作为初始值,同时也能接受额外的参数,返回值为经过处理后的输出值。


Vue.filter('date', function(value){ if(!value instanceof Date) return value; return value.toLocalDateString();})
</div> {{ date | date }}</div>var vm = new Vue({ el: '#app', data: { date: new Date() }})
复制代码


组件注册


示例:


var MyComponent = Vue.extend({...})
复制代码


vue.js提供了两种注册方式,分别是全局注册和局部注册。


Vue.component('my-component', MyComponent);
复制代码


使用方法:


<div id="app"> <my-component></my-component></div>
var MyComponent = Vue.extend({template : '<p>掘金 魔王哪吒</p>'})
Vue.component('my-component', MyComponent)var vm = new Vue({el : '#app'});
复制代码


局部注册


var Child = Vue.extend({template : '<p>dadaqianduan.cn</p>'});
var Parent = Vue.extend({template: '<div>    <p>dada</p>   <my-child></my-child>   </div>', components: {   'my-child': Child }});
复制代码


注册语法糖


示例:


// 全局注册Vue.component('my-component', {template : '<p>dadaqianduan.cn</p>'})
// 局部注册var Parent = Vue.extend({template: '<div>    <p>掘金 魔王哪吒</p>     <my-child></my-child>   </div>', components: {   'my-child': {    template : '<p>dada</p>'   } }});
复制代码


组件 props


props将父组件的数据传递给子组件,子组件在接受数据时,需要显示声明props


示例:


Vue.component('my-child', {props : ['parent'],template: '<p>{{ parent }} is from parent'})<my-child parent="魔王哪吒"></my-child>
复制代码


prop: Number,接受的参数为原生构造器,String,Number,Boolean,Function,Object,Array,也可接受null,意味任意类型均可。


多种类型:prop: [Number,String],;参数必需:prop:{type: Number, required: true}


参数默认:prop: {type: Number, default: 12},


示例:


prop: { type: Object, default: function() {  return {a: 'a'} }}
复制代码


组件间通信


vue.js提供了三个属性对其父子组件以及根实例进行直接访问。


  • $parent,父组件实例

  • $children,包含所有子组件实例

  • $root,组件所在的根实例


建议使用props在组件间传递数据。

$emit


示例:


events : {'add' : function(msg) {   this.todo.push(msg); }}methods: {onClick : function() {   this.$emit('add', 'dada'); }}
复制代码


$dispatch


示例:


父组件:
events : {'add' : function(msg) {   this.todo.push(msg); }}
子组件:
methods: {toParent : function() {   this.$dispatch('add', 'dada'); }}
复制代码


子组件索引


vue.js提供了直接访问子组件的方式,除了this.children外,还给子组件绑定一个v-ref指令。


<child-todo v-ref:first></child-todo>
复制代码


在父组件中就可以通过 this.$refs.first 的方式获取子组件实例。


组件缓存


keep-alive如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。


<keep-alive> <component :id="currentView"> </component></keep-alive>
复制代码


生命周期:


// 组件被创建之前beforeCreate(){ console.log("组件被创建之前")}created(){ console.log("组件被创建之后")}beforeMount(){ console.log("组件被渲染之前")}mounted(){ console.log("组件被渲染之后")}beforeUpdate(){ console.log("数据改变渲染之前")}updated() { console.log("数据改变渲染之后}beforeDestory(){ // 组件销毁之前}destoryed(){ // 销毁之后}
复制代码


自定义指令和过滤器


// 注册一个全局自定义指令Vue.directive('focus', { inserted: function(el){  // 聚焦元素  el.focus() }})
复制代码


注册局部指令,组件中也接受一个directives的选项:


directives: { focus: {  // 指令的定义  inserted: function(el){   el.focus();  } }}
复制代码


过滤器


vue.js过滤器可以用在两个地方:双花括号插值v-bind表达式。


{{message | capitalize}}
<div v-bind:id="rawId | formatId"></div>
复制代码


可以在一个组件的选项中定义本地的过滤器:


filters: { capitalize: function(value) {  if(!value) return ''  value = value.toString()  return value.charAt(0).toUpperCase() + value.slice(1); }}
复制代码


Vue.filter("author",function(value){ return value+"-dadaqianduan";})
Vue.filter("money", function(value){ return "$"+value;})
复制代码


axios 基础 get 请求


axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。


特点:


  1. 从浏览器中创建XMLHttpRequests

  2. node.js创建http请求

  3. 支持Promise api

  4. 拦截请求和响应

  5. 转换请求数据和响应数据

  6. 取消请求

  7. 自动转换JSON数据

  8. 客户端支持防御XSRF


安装:


使用npm


npm install axios
复制代码


执行GET请求:


axios.get('/user?ID=123') .then(function(response){  console.log(response); }) .catch(function(error){  console.log(error); });
axios.get('/user', { paras: { ID: 123 }}).then(function(response){ console.log(response);}).catch(function(error){ console.log(error);});
复制代码


执行 post 请求


axios.post('/user', { firstName: 'da', lastName: 'jeskson'}).then(function(response){ console.log(response);}).catch(function(error){ console.log(error);});
复制代码


执行多个并发请求


function getUserAccount() { return axios.get('/user/123');}function getUserPermissions() { return axios.get('/user/123/permissions');}axios.all([getUserAccount(),getUserPermissions()]).then(axios.spread(function(acct, perms){}));
复制代码


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


// axios(config)axios({ method: 'post', url: '/user/123', data: {  firstName: 'dada',  lastName: 'dadaqianduan' }});
复制代码


axios(url[,config])


// 发送get请求axios('/user/123');
复制代码


示例:


created(){ this.$axios.get("http://xxx") .then(res=>{  this.axiosData = res.data }) .catch(error => {  console.log(error); })}}
复制代码


vue-axio 全局配置和拦截器


全局的axios默认值:


axios.defaults.baseURL='http://xxx';
复制代码


自定义实例默认值:


// 创建实例时设置的默认值var instance = axios.create({ baseURL: 'http://xxx'});
复制代码


拦截器:在请求或响应被thencatch处理前拦截它们。


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


添加请求拦截器


Axios.interceptors.request.use(function(config){ // 在发送请求之前做些什么 if(config.method === 'post'){  config.data = qs.stringify(config.data); } console.log(config); return config;},function(error){// 对请求错误做些什么return Promise.reject(error);});
复制代码


vue-axio 跨域处理


proxy: { host: '127.0.0.1', port: 9000, auth: {  username: 'jeskson',  password: '123' }}
复制代码


路由基础


<div id="app"> <router-view></router-view></div>
const User = { template: '<div>User</div>`}
const router = new VueRouter({ routes: { {path: '/user/:id', component: User} }})
复制代码


router-link


<router-link>组件支持用户在具有路由功能的应用中导航,通过to属性指定目标地址,默认渲染成带有正确链接的<a>标签,可以通过配置tag属性生成别的标签。另外,当目标路由成功激活时,链接元素自动设置一个表示激活的css类名。


<router-link>比起写<a href="...">会好一些。


  1. 无论是html5 history模式还是hash模式,它的表现行为一致,所以,当你要切换路由模式,或者在ie9降级使用hash模式,无须作任何变动。

  2. html5 history模式下,router-link会守卫点击事件,让浏览器不在重新加载页面。

  3. 当你在html5 history模式下使用base选项之后,所有的to属性都不需要写基路径了。


路由嵌套


要在嵌套的出口中渲染组件,需要在VueRouter的参数中使用children配置:


const router = new VueRouter({ routes: [  {path: '/user/:id', component:User,  children: [   {    path: 'profile',    component: UserProfile   },   {    path: 'posts',    components: UserPosts   } ]})
复制代码


路由参数传递:


<router-link :to="{name: 'dada', params: {id:'111', count: 12} }">魔王哪吒</router-link>
复制代码


vue 框架对比


vue:


  1. 模板和渲染函数的弹性选择

  2. 简单的语法以及项目创建

  3. 更快的渲染速度和更小的体积


react:


  1. 更适用于大型应用和更好的可测试性

  2. 同时适用于 web 端和原生 app

  3. 更大的生态圈带来的更多的支持和工具


vue 核心思想


数据驱动 和 组件化


nodejs 和 npm 的安装和环境搭建


  1. Webpack代码模块化构建打包工具

  2. Gulp基于流的自动化构建工具

  3. GruntJavaScript世界的构建工具

  4. Babel是使用最新的规范来编写js

  5. vue是构建数据驱动的web界面的渐进式框架

  6. Express是基于Node.js平台,快速,开放,极简的web开发框架


下载地址:https://nodejs.org/en/download/


vue 环境搭建以及 vue-cli 使用


vue多页面应用文件引用:


<script src="https://unpkg.com/vue/dist/vue.js"></script>


vue-cli构建spa应用


npm install -g vue-cli
vue init webpack-simple demo
vue init webpack demo2
复制代码


a vue.js project
npm install
npm run dev
npm run build
复制代码


vue 基础语法


模板语法:Mustache语法:{{msg}}


  • html赋值:v-html=""

  • 绑定属性:v-bind:id=""

  • 使用表达式:{{ok?'yes':'no'}}

  • 文本赋值:v-text=""

  • 指令v-if=""

  • 过滤器:{{message | capitalize}}


classstyle绑定


  • 对象语法:v-bind:class="{active: isActive, 'text-danger': hasError}">

  • 数组语法:<div v-bind:class="[activeClass,errorClass]">

  • style绑定对象语法:v-bind:style="{color:activeColor,fontSize:fontSize+'px'}"


vue 组件


  1. 全局组件和局部组件

  2. 父子组件通讯-数据传递

  3. Slot


Vue-router


什么是前端路由:就是根据不同的 url 地址展示不同的内容或页面


vue-router用来构建spa


<router-link></router-link>或者this.$router.push({path:''})
<router-view></router-view>
复制代码


  • 动态路由匹配

  • 嵌套路由

  • 编程式路由

  • 命名路由和命名视图


什么是动态路由匹配



示例:


import GoodsList from './../views/GoodsList'Vue.use(Router)export default new Router({ routers: [  {   path: '/goods/:goodsId',   name: 'GoodsList',   component: GoodsList  } ]})
<template> <div> <span>{{$route.params.goodsId}}</span> </div></template>
复制代码


什么是嵌套路由


// App.vue<template> <div id="app">  <img src="./assets/logo.png">  <router-view></router-view> </div></template>
复制代码


import GoodsList from './../views/GoodsList'import Title from '@/views/Title'import Image from '@/views/Image'Vue.use(Router)export default new Router({ routers: [  {   path: '/goods',   name: 'GoodsList',   component: GoodsList,   children: [    {      path: 'title',      name: 'title',      component: Title     },     {      path: 'img',      name: 'img',      component: Image     }   ]  } ]})
<template> <div> <span>{{$route.params.goodsId}}</span> <router-link to="/goods/title">显示商品标题</router-link> <router-link to="/goods/image">显示图片</router-link> <div> <router-view></router-view> </div> </div></template>
复制代码


什么是编程式路由


通过 js 来实现页面的跳转。


$router.push("name")
$router.push({path:"name"})
$router.push({path:"name?a=123"})或者$router.push({path:"name",query:{a:123}})
$router.go(1)
复制代码


import GoodsList from './../views/GoodsList'import Title from '@/views/Title'import Image from '@/views/Image'import Cart from '@/views/Cart'Vue.use(Router)export default new Router({ routers: [  {   path: '/goods',   name: 'GoodsList',   component: GoodsList,   children: [    {      path: 'title',      name: 'title',      component: Title     },     {      path: 'img',      name: 'img',      component: Image     }   ]  },  {   path: '/cart',   component: Cart  } ]})
<template> <div> <span>{{$route.params.goodsId}}</span> <router-link to="/goods/title">显示商品标题</router-link> <router-link to="/goods/image">显示图片</router-link> <div> <router-view></router-view> </div> <router-link to="/cart">购物车</router-link> <button @click="jump">跳转购物车</button> </div></template>
...
methods: { jump() { this.$router.push("/cart"); // ({path: '/cart?id=123'}); }}
复制代码


命令路由和命名视图


给路由定义不同的名字,根据名字进行匹配


给不同的router-view定义名字,通过名字进行对应组件的渲染


<router-link v-bind:to="{name: 'cart'}">跳转到购物车页面</router-link>
<router-link v-bind:to="{name: 'cart', params:{cartId:123}}">跳转到购物车页面</router-link>
路由:{ path: '/cart/:cartId", name: 'cart', component: Cart}
复制代码


app.vue 代码如下:


<template> <div id="app">  <img src="./assets/logo.png">  <router-view></router-view>  <router-view name="title"></router-view>  <router-view name="img"></router-view> </div></template>
复制代码


router/index.js


import Vue from 'vue'import Router from 'vue-router'import GoodsList from './../views/GoodsList'import Title from '@/views/Title'import Image from '@/views/Image'import Cart from '@/views/Cart'
Vue.use(Router);
export default new Router({ routers: { { path: '/', name: 'GoodsList', components: { default: GoodsList, title: Title, img: Image } }, { path: '/cart/:cartId', name: 'cart', components: Cart } }})
复制代码


Vue-resource 和 Axios


下载安装方式:


<script src="https://cdn.jsdelivr.net/vue.resource/1.3.1/vue-resource.min.js"></script>
npm install vue-ressource -save
复制代码


vue-resource的请求api是按照rest风格设计的,提供 7 个请求 api:


get(url, [options])
head(url, [options])
delete(url, [options])
jsonp(url, [options])
post(url, [body], [options])
put(url, [body], [options])
patch(url, [body], [option])
复制代码


全局拦截器interceptors


Vue.http.interceptors.push{(request, next) => { // 请求发送前的处理逻辑 next((response) => {  // 请求发送后的处理逻辑  return response })})
复制代码


vue-resource.html(全局拦截器)


mounted() { Vue.http.interceptors.push(function(request,next){  next(function(response){   return response;  }); });}
复制代码


axios 的使用


<script src="https://unpkg.com/axios/dist/aios.min.js"></script>
npm install axios -save
复制代码


示例:


function getUserAccount(){ return axios.get('/user/12345');}
function getUserPermissions(){ return axios.get('/user/12345/permissions');}
axios.all([getUserAccount(), getUserPermissions()]).then(axios.spread(function(acct, perms){
}));
复制代码


mounted: function(){ axios.interceptors.request.use(function(config){  return config; }) axios.interceptors.response.use(function(response){  return response; })}
复制代码


ES6 常用命令


函数的 Rest 参数和扩展,Promise 使用,module.exportses6 import/export的使用


let checkLogin = function () { return new Promise(function(resolve,reject){  let flag = document.cookie.indexOf("userId") > -1 ? true:false    if(flag) {   resolve({    status: 0,    result: true   })  }else{   reject("error");  } })};
checkLogin().then(function(res){if(res.status==0){ console.log("login success");}}).catch((error)=>{ console.log(`error:${error}`);})
复制代码


一旦有了名字就要大块来接收


export let sum = (x,y)=>{ return x+y;}
export let minus = (m,n) => { return m-n;}
import {sum, minus} from './util'sum()
console.log(`sum:${sum(1,2)}`);
复制代码


import * as util from './util'
// util.sum(1,2)
复制代码


AMD,CMD,CommonJS 和 ES6


  • AMDRequireJS在推广过程中对模块定义的规范化产出

  • CMDSeaJS在推广过程中对模块定义的规范化产出

  • CommonJS规范-module.exports


示例:


exports.area = function(r){ return Math.PI * r * r;};
复制代码


脚手架


Vue 基础:环境搭建,模板,计算属性,类与样式,条件,列表渲染,事件处理,深入了解组件,路由基础,Vuex 基础。


vue-cli@3vue@2.5
// 第一种搭建npm install -g @vue/cli
// 第二种搭建yarn global add @vue/cli
复制代码


v-bind 缩写


// 完整语法<a v-bind:href="url">...</a>
// 缩写<a :href="url">...</a>
复制代码


v-on 缩写


// 完整语法<a v-on:click="doSomething">...</a>
// 缩写<a @click="doSomething>...</a>
复制代码


自定义指令


声明自定义指令的名称,通过vue.directive声明,设置钩子函数,在什么时机做什么事情:


// 注册一个全局自定义指令 v-focusVue.directive('focus', { // 当被绑定的元素插入到DOM中时 inserted: function(el){  // 聚焦元素  el.focus() }})
复制代码


钩子函数


一个指令定义对象可以提供如下几个钩子函数:


(初始化的操作)

bind,只调用一次,指令第一次绑定到元素时调用,在这里可以进行一次性的初始化设置。


inserted,被绑定元素插入父节点时调用,(仅保证父节点存在,但不一定已被插入文档中)。


update,所在组件的VNode更新时调用,但是可能发生在其子VNode更新之前。指令的值可能发生了改变,也可能没有,但是你可以通过比较更新前后的值来忽略不必要的模板更新。


componentUpdated,指令所在组件的VNode及其子VNode全部更新后调用。


unbind,只调用一次,指令与元素解绑时调用。


指令钩子函数会被传入以下参数


el,指令所绑定的元素,可以用来直接操作DOM


binding,一个对象,包含以下属性:


  1. name,指令名,不包含v-前缀


  1. value,指令的绑定值,例如,v-my-directive="1+1"中,绑定值为 2


  1. oldValue,指令绑定的前一个值,仅在updatecomponentUpdated钩子中可用,无论值是否改变都可用。


  1. expression,字符串形式的指令表达式,例如v-my-directive="1+"中,表达式为"1+1"


  1. arg,传给指令的参数,可选。例如v-my-directive:foo中,参数为"foo"


  1. modifiers,一个包含修饰符的对象,例如:v-my-directive.foo.bar中,修饰符对象为{foo:true,bar:true}


  1. vnodevue编译生成的虚拟节点。


  1. oldVnode,上一个虚拟节点,仅在updatecomponentUpdated钩子中可用。


除了el外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的dataset来进行。


计算属性


示例:


<div id="jeskson"> <p>{{message}}</p> <p>{{reversedMessage}}</p></div>
复制代码


应用场景:具有依赖关系的数据监听。


事件


  • 事件的定义以及缩写

  • 事件传参和事件对象

  • 快速结合键盘事件提升效率


事件修饰符


在事件处理程序中调用event.preventDefault()event.stopPropagation()是非常常见的需求。


vue.jsv-on提供了事件修饰符:


.stop
.prevent
.capture
.self
.once
.passive
复制代码


深入了解组件


props, 组件的参数传递;slot,插槽在组件抽象设计中的应用;自定义事件,父子组件的通信方式。


生命周期钩子


  1. beforeCreate组件创建前

  2. created组件创建前

  3. beforeMount组件挂载前

  4. mounted组件挂载完毕

  5. beforeUpdate组件更新之前

  6. updated组件更新完毕

  7. beforeDestory组件销毁前

  8. destory组件销毁完毕


示例:


<div id="app"> <h1>{{dada}}</h1> <button v-on:click="updateInfo">修改数据</button> <button v-on:click="destoryComponent">销毁组件</button></div>
var vm = new Vue({ el: '#app', data: { info: 'dadaqianduan.cn‘ }, beforeCreate: function(){ console.log("beforeCreated,组件创建前"); console.log(this.$el); console.log(this.$data); }, created: function(){ console.log("created,组件创建完毕"); console.log(this.$el); console.log(this.$data); console.log(this.$data.info); }, beforeMount: function() { console.log("beforeMounted,组件挂载前"); console.log(this.$el); console.log(this.$data); console.log(this.$data.info); }, mounted: function(){ console.log("mounted,组件挂载完毕"); console.log(this.$el); console.log(this.$data); console.log(this.$data.info); }, beforeUpdate: function(){ console.log("beforeUpdate,组件更新前"); console.log(this.$el); console.log(this.$data); console.log(this.$data.info); }, updated: function(){ console.log("updated,组件更新完毕"); console.log(this.$el); console.log(this.$data); console.log(this.$data.info); }, beforeDestroy: function(){ console.log("beforeDestory,组件销毁前"); console.log(this.$el); console.log(this.$data); console.log(this.$data.info); }, destroyed: function(){ console.log("destoryed,组件销毁完毕"); console.log(this.$el); console.log(this.$data); console.log(this.$data.info); },})
复制代码


组件创建前-beforeCreate:组件创建前,组件需要挂载的 DOM 元素 el 和组件的数据 data 都未被创建。


el: undefined
data: undefined
复制代码


组件创建完毕-created:组件的数据已经创建完毕,但是 DOM 元素的 el 还没被创建


el: undefined
data: {info: 'dadaqianduan.cn’}
复制代码


组件挂载前-beforeMount:DOM 元素被创建,而 data 中的数据还没有


el有值,data有值,info没值
复制代码


组件挂载完毕-mounted:data 中的数据有值。el,data,info都有值。


组件更新前-beforeUpdate:data 数据已经更新,dom 元素的内容也同步更新。


组件更新完毕-updated:data 数据已经更新,dom 元素的内容也同步更新。


组件销毁之前-beforeDestroy:销毁前,不再受vue管理,但是可以继续更新数据,但模板已经不再更新了。


组件销毁之前-destroyed:组件销毁完毕,不再受vue管理。


生命周期阶段


  1. new Vue(),新建vue实例


  1. 初始化,事件和生命周期


  1. beforeCreate


  1. 初始化,注入和校验


  1. created


  1. 是否指定el选项,是直接走判断(是否指定template选项),否-当调用vm.$mount(el)函数时(是否指定template选项)


  1. 是否指定template选项-(是:将template编译到render函数中,否:将el外部的html作为template编译)


  1. beforeMount


  1. 创建vm.$el并用其替换el


  1. mounted


  1. 挂载完毕(如当data被修改时,调用beforeUpdate-,进入虚拟DOM重新渲染并应用更新,调用updated


  1. 当调用vm.$destroy()函数时。


  1. beforeDestroy


  1. 解除绑定,销毁子组件以及事件监听器


15.销毁完毕-destroyed


父子组件通信


父组件可以通过props传递给子组件,子组件可以通过$parent,$emit传递父组件。


// 组件引用<dada></dada>
// 引入import Dada from './components/Dada'export default { name: 'App', // 注册 components: {Dada}}
复制代码


流程:引入,注册,使用。


props


示例:


Vue.component('da-da', { props: ['textTitle'], template: '<h2>{{textTitle}}</h2>'})
// 使用<da-da text-title="dadaqianduan.cn"></da-da>
复制代码


prop类型如下:


props: {  title: String,  likes: Number,  isPublished: Boolean,  commentIds: Array,  author: Object,  callback: Function,  contactsPromise: Promise}
复制代码


传递静态或动态 prop


<da-da title="dadaqianduan.cn"></da-da>
复制代码


prop可以通过v-bind动态赋值:


// 动态赋值<da-da v-bind:title="dada.title"></da-da>
<da-da v-bind:title="dada.title+'da da'+dada.author.name"></da-da>
复制代码


父组件prop的更新会向下流动到子组件中,但是反过来则不行,这样会防止从子组件意外变更父级组件的状态,表示你不应该在一个子组件内部改变prop,否则vue会在浏览器的控制台中发出警告。


这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data property 并将这个 prop 用作其初始值


示例:


props: ['dada'],data: function () {  return {    counter: this.dada  }}
复制代码


以一种原始的值传入且需要进行转换。


示例:


props: ['size'],computed: {  normalizedSize: function () {    return this.size.trim().toLowerCase()  }}
复制代码


prop验证


示例:


Vue.component('my-component', {  props: {    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)    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      }    }  }})
复制代码


类型检查


type可以是下列原生构造函数中的一个:通过 instanceof 来进行检查确认。


StringNumberBooleanArrayObjectDateFunctionSymbol
复制代码


$emit


子组件通过$emit向父组件传递通信。


vm.$emit(eventName,[...args])
参数:1. {string} eventName2. [...args]
触发当前实例上的事件,附加参数都会传给监听器回调。
复制代码


子组件中执行$emit(eventName)时,就会触发父组件中对应的event。


'$parent:$parentvue`的一个实例属性,它表示的是当前组件的父实例


假如父组件中有一个方法为sayDa,在子组件中可以直接使用this.$parent.sayDa去调用父组件的方法。


Vuex 项目实战


  1. Vuex 的基本使用步骤

  2. Vuex 的核心概念

  3. Vuex 实现业务功能


Vuex 概述


组件之间共享数据的方式


如果父组件要向子组件传值,使用 v-bind 属性绑定


如果子组件要向父组件传值,使用 v-on 事件绑定


兄弟组件之间共享数据:EventBus


  • $on接收数据的那个组件

  • $emit发送数据的那个组件


Vuex 是什么


vuex 是实现组件全局状态数据管理的一种机制,可以方便的实现组件之间数据的共享。


使用 vuex 统一管理状态的好处


1.能够在 vuex 中集中管理共享的数据,易于开发和后期维护


2.能够高效地实现组件之间的数据共享,提高开发效率


3.存储在 vuex 中的数据都是响应式的,能够实时保持数据与页面的同步


什么样的数据可以存储到 vuex 中


一般情况下,只有组件之间共享的数据,才有必要存储到 vuex 中,对于组件中私有的数据,存储在组件自身的 data 中。


vue 的基本使用


  1. 安装 vuex 依赖包


npm install vuex --save
复制代码


  1. 导入 vuex 包


import Vuex from 'vuex'Vue.use(Vuex)
复制代码


  1. 创建 store 对象


const store = new Vuex.Store({ // state中存放的是全局共享的数据 state: {count:0}})
复制代码


  1. 将 store 对象挂载到 vue 实例中


new Vue({ el: '#app', render: h=>h(app), router, // 将创建的共享数据对象,挂载到Vue实例中 // 所有的组件,就可以直接从store中获取全局的数据 store})
复制代码


vuex 的核心概念


组件访问 state 中数据的第一种方式:


this.$store.state.全局数据名称
复制代码


组件访问 state 中的数据第二种方式:


// 从vuex中按需导入mapState函数import {mapState} from 'vuex'
复制代码


通过刚导入的mapState函数,将当前组件需要的全局数据,映射为当前组件的computed计算属性:


// 将全局数据,映射为当前组件的计算属性computed: { ...mapState(['count'])}
复制代码


Mutation用于修改 store 的数据


  1. 只能通过mutation变更Store数据,不可以直接操作Store中的数据。

  2. 通过这种方式虽然操作起稍微繁琐一些,但是可以集中监控所有数据的变化。


// 定义Mutation
const store = new Vue.store({ state: { count: 0 }, mutations: { add(state) { // 变更状态 state.count++ } }})
复制代码


// 触发mutation
methods: { handle1() { // 触发mutations的第一种方式 this.$store.commit('add') }}
复制代码


可以在触发mutations时传递参数:


// 定义Mutationconst store = new Vuex.Store({ state: {  count: 0 }, mutations: {  addN(state,step){   // 变更状态   state.count += step  } }})
复制代码


// 触发mutationmethods: { handle2() {  // 在调用commit函数  // 触发mutations 时携带参数  this.$store.commit('addN',1) }}
复制代码


this.$store.commit()是触发mutations的第一种方式,第二种如下:


// 从vuex中按需导入mapMutations函数import {mapMutations} from 'vuex'
复制代码


将需要的mutations函数,映射为当前组件的methods方法:


methods: { ...mapMutations(['add','addN'])}
复制代码


不要在 mutations 函数中,执行异步操作


Action 用于处理异步任务。


如果通过异步操作变更数据,必须通过 Action,而不能使用 Mutation,但是在 Action 中还是通过触发 Mutation 的方式间接变更数据。


// 定义Actionconst store = new Vuex.store({ mutations: {  add(state){   state.count();  } }, actions: {  addAsync(context){   setTimeout(()=>{    context.commit('add')   },1000)  } }
复制代码


// 触发Actionmothods: { handle() {  // 触发actions的第一种方式  this.$store.dispatch('addAsync'); }}
复制代码


触发 action 异步任务时携带参数:


this.$store.dispatch('addNAsync',5)
复制代码


触发 actions 的第二种方式:


// 从vuex中按需导入mapActions函数import {mapActions} from 'vuex'
复制代码


将需要的 actions 函数,映射为当前组件的 methods 方法:


methods: { ...mapActions(['addAsync','addNASync'])}
复制代码


import {mapState,mapMutations,mapActions} from 'vuexcomputed: { ...mapState(['count'])},methods: { ...mapMutations(['sub','subN']), ...mapActions(['subAsync']), btnHandler1(){  this.sub() }, btnHandle2(){  this.subN() }}
复制代码


getter


vuex 中的 getter


Getter 用于对 Store 中的数据进行加工处理形成新的数据


  1. Getter 可以对 Store 中已有的数据加工处理后形成新的数据。

  2. Store 中数据发生变化,Getter 的数据会跟着改变


const store = new Vuex.store({ state: {  count: 0 }, getters: {  showNum: state => {   return state.count  } }})
复制代码


使用 getters 的第一种方式:


this.$store.getters.名称
复制代码


使用 getters 的第二种方式:


import { mapGetters } from 'vuex'
computed: { ...mapGetters(['showNum'])}
复制代码


点赞、收藏和评论


我是Jeskson(达达前端),感谢各位人才的:点赞、收藏和评论,我们下期见!(如本文内容有地方讲解有误,欢迎指出☞谢谢,一起学习了)


我们下期见!


文章持续更新,可以微信搜一搜「 程序员哆啦 A 梦 」第一时间阅读,回复【资料】有我准备的一线大厂资料,本文 http://www.dadaqianduan.cn/#/ 已经收录


github收录,欢迎Starhttps://github.com/webVueBlog/WebFamily


发布于: 2021 年 02 月 01 日阅读数: 756
用户头像

魔王哪吒

关注

微信搜:程序员哆啦A梦 2018.05.08 加入

面向JavaScript爱好人员提供:Web前端最新资讯、原创内容、JavaScript、HTML5、Ajax、jQuery、Node.js、Vue.js、React、Angular等一系列教程和经验分享。 博客首发:http://www.dadaqianduan.cn/#/

评论

发布
暂无评论
【初级】个人分享Vue前端开发教程笔记