• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

VUE笔记

武飞扬头像
左丘超然
帮助1

VUE

00.学习vue的大致思路:

1.学习本阶段的作用

能够熟练使用 vue.js技术栈开发前端项目

2.vue.js技术栈

  1. vue.js
  2. vue-router
  3. webpack
  4. axios
  5. vue-cli3
  6. vuex
  7. vue组件库(element-UI…)

学习目标

  1. 掌握vue.js基础语法⭐
  2. 掌握vue组件
  3. 掌握vue路由⭐
  4. 掌握axios⭐
  5. 理解webpack⭐
  6. 掌握vue-cli3和Element-UI的使用⭐
  7. 掌握vuex⭐
  8. 能够熟练使用vue技术栈开发前端项目

⭐:重难点

4.本阶段包含案例项目展示

  1. 电商后台管理系统

5.阶段模块和学习方法建议

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SMcmveAN-1649165714784)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220330154633003.png)]

01.常用特性概述与表单效果概览

input 单行文本

textarea 多行文本

select 下拉多选

radio 单选框

checkbox 多选框

02.侦听器基本用法

应用场景:数据变化时执行异步或者开销较大的操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xjRFLq08-1649165714785)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220328090839031.png)]

属性的名称和里面方法的名称要相同,这样才可以绑定数据的变化

03.MVVM设计思想分析

  1. M(model) 模型:提供数据的
  2. V(view) 视图:提供页面展示效果
  3. VM(View-Model) 实现控制逻辑,把两者结合在一起

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-owoWFX9s-1649165714785)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220328091740343.png)]

设计思想:分治

把视图层和数据层分开 他们两个通过vue来连接起来

从视图通过事件监听到数据

从数据通过数据绑定到视图层

04.双向数据绑定和v-model指令用法

数据与页面的交互是双向数据绑定

页面变化会引起数据发生改变

数据也可以填充到页面中影响页面布局

v-model = ‘data中的数据’

双向数据绑定主要体现在表单输入域中

05.v-model底层原理分析

属性绑定+事件绑定

  1.  

//$event是一个标准的事件对象

  1.  

methods:{

handle:function(event){

//使用输入域中最新的数据覆盖原来的数据

this.msg = event.target.value //target就是input本身

}

}

  1.  

v-bind:value 数据绑定

v-on:input 事件绑定

06.数据响应式概念和v-once用法

如何理解响应式?

  1. html5中的响应式:屏幕尺寸的变化导致样式的变化
  2. 数据的响应式(数据的变化导致页面内容的变化)

什么是数据绑定?

  1. 数据绑定:将数据填充到标签中

v-once只编译一次

  1. 显示内容之后不再具有响应式功能
  2. v-once的应用场景:如果显示的信息后续不需要再修改

我们可以使用v-once,这样可以提高性能

07.过滤器

过滤器的作用是什么?

格式化数据(处理数据),比如将字符串格式化为首字母大写,将日期格式化为指定的格式等

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TUnDvAJU-1649165714786)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220328154821821.png)]

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <input type="text" v-model = 'msg'>
    <div>{{msg | upper }}</div>
</div>

<script>
    //过滤器
    Vue.filter('upper',function (val) {
        return val.charAt(0).toUpperCase()   val.slice(1);  //这边要有返回值!!!
    })
    var vl = new Vue({
        el:"#app",
        data:{
            msg:'hello'
        }
    })
</script>
</body>
</html>
学新通

2.自定义过滤器

Vue.filter('过滤器名称',function(value){
    //过滤器业务逻辑
})

3.过滤器的使用

{{msg | upper}}
<div>{{msg | upper | lower}}</div>  <--
    叠加:即先大写在小写
    -->
<div v-bind:id = 'id | formatId'></div>
//也可以属性绑定

4.局部过滤器

filters:{
    capitalize:function(){}
}  //写在new  Vue里面

5.带参数的过滤器

Vue.filter('format',function(value,argu1){
    //value是过滤器传递过来的参数,要调用参数从第二个开始
})

6.过滤器的使用

<div>{{date | format('yyyy-MM-dd')}}</div>

08.组件

定义:

组件是vue.js最强大的功能之一

组件可以扩展HTML元素,封装可重用的代码

组件系统可以让我们用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fkaSVyGT-1649165714786)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220328162624420.png)]

注册一个全局组件语法格式:

Vue.component(tagName,option)
//tagName为组件名,options为配置选项
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <runoob></runoob>
</div>

<script>
    //定义全局组件
    Vue.component('runoob',{
        template:'<h1>自定义组件!!</h1>'
    })
    //创建根实例
    var vl = new Vue({
        el:"#app",
        data:{}
    })
</script>
</body>
</html>
学新通

在实例选项中注册一个局部组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <runoob></runoob>
</div>

<script>
    //定义全局组件
    var child = {
        template:'<div>注册一个局部组件</div>'
    }
    //创建根实例
    var vl = new Vue({
        el:"#app",
        data:{},
        components:{
            //<runoob>将只在父模板中可用
            'runoob':child
        }
    })
</script>
</body>
</html>
学新通

Prop(父组件向子组件传值)

prop是子组件用来接受父组件传递过来的数据的一个自定义属性

父组件的数据需要通过props把数据传给子组件,子组件需要显式地用props选项声明“prop”:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <child message = "hello!"></child>
</div>
<script>
    //注册
    Vue.component('child',{
        //声明props
        props:['message'],
        //同样也可以在vm实例中像“this.message”这样使用
        template:'<span>{{message}}</span>'
    })
    //创建根实例
    new Vue({
        el:'#app'
    })
</script>
</body>
</html>
学新通

动态绑定:

类似于用v-bind绑定HTML特性到一个表达式,也可以用v-bind动态绑定props的值到父组件的数据中,每当父组件的数据变化时,改变话会传递到子组件中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <child message = "hello!"></child> //静态绑定
    <child message = "hello!" :che = 'ch'></child>   //同时也可以绑定多个,后面的是动态绑定
</div>
<script>
    //注册
    Vue.component('child',{
        //声明props
        props:['message','che'],
        //同样也可以在vm实例中像“this.message”这样使用
        template:'<span>{{message   "------"   che}}</span>'
    })
    //创建根实例
    new Vue({
        el:'#app',
        data:{
            ch:'6666'
        }
    })
</script>
</body>
</html>
学新通

注意:prop是单向绑定的:当父组件的属性变化时,将传递给子组件,但是不会反过来

prop命名规则:在prop中可以使用驼峰式命名

但是到HTML中必须使用短横线命名规则

prop支持不同类型字符串

在number中

HTML中: :pnum = “12” 则返回的一个数字,可以在template中支持运算

如果是pnum = “12”,则返回的是一个字符串

布尔值也是类似道理

注意点:凡是遇到v-for循环,都要加一个:key = ’index‘

如:

<li :key = 'index' v-for = '(item,index) in parr'>item</li>

子组件向父组件传递参数

子组件向父组件传递信息:

1.子组件通过自定义事件向父组件中传递信息

2.父组件监听子组件的事件

<button v-on:click = '$emit("enlarge-text")'>扩大字体</button>  //第一步  其中$emit函数是固定的

<menu-item v-on:enlarge-text = "fontSize  = 0.1"></menu-item>	//第二步

携带参数:

3.子组件通过自定义事件向父组件传递信息

4.父组件监听子组件的事件

<button v-on:click = '$emit("enlarge-text",0.1)'>扩大字体</button>		//第二个值就是子组件传递要携带的参数
<menu-item v-on:enlarge-text = "fontSize  = $event"></menu-item>	//父组件中通过$event来接受子组件传递过来的参数

或者在父组件中直接用handle($event),具体实现流程在下面methods中实现

兄弟组件之间数据交互

非父子之间传值

1.单独的事件中心管理组件间的通信

var eventHub = new Vue()  //单独创建的vue实例对象就是事件中心管理组件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xHorVae0-1649165714787)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220330161749298.png)]

2.监听事件和销毁事件

eventHub.$on('add-todo',addTodo)  //第一个参数是事件名称,第二个参数是事件函数
eventHub.$off('add-todo')

3.触发事件

eventHub.$emit('add-todo',id)

实例:

<div>
	<button @click = 'handle'>销毁事件</button>    
</div>
<test-tom></test-tom>
<test-jerry></test-jerry>
//定义事件中心
var hub = new Vue();
Vue.component('test-tom',{
    data:function(){
        return{
            num:0
        },
            template:`
            	<div>
            		<div>TOM:{{num}}</div>
            		<div>
            			<button @click = "handle">点击</button>
            		</div>
            	</div>
            `,methods:{
                   handle:function(){
                       //触发兄弟组件的事件
                       hub.$emit('jerry-event',1)
                   }
              },
            mounted:function(){
                //在钩子函数中,代表页面已经加载完成,监听事件
				hub.$on('tom-event',(val) => {
                    this.num  =val
                })
            }
               
    }
})
Vue.component('test-jerry',{
    data:function(){
        return{
            num:0
        },
            template:`
            	<div>
            		<div>JERRY:{{num}}</div>
            		<div>
            			<button @click = "handle">点击</button>
            		</div>
            	</div>
            `,
               methods:{
                   handle:function(){
                       hub.$emit('tom-event',1)
                   }
               },
               mounted:function(){
                //在钩子函数中,代表页面已经加载完成,监听事件
				hub.$on('jerry-event',(val) => {
                    this.num  =val
                })
    }
})
    
    
    
 			var vm = new Vue({
    el:"#app",
    data:{
    
},
              methods:{
              handle:function(){
                hub.$off('tom-event')
                hub.$off('jerry-event')
}
              }
})
学新通

组件插槽的作用:

组附件向子组件传递内容

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yxJCeNyl-1649165714787)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220330163945202.png)]

父组件中间有值

<div id="app">
    <runoob>666</runoob>
</div>

    //定义全局组件
    Vue.component('runoob',{
        template:`<h1>自定义组件!!</h1>
                   <div>
                   <slot></slot>
</div>
`
    })

最终将组件插槽中的数据传给slot隐藏组件

最后结果就是 自定义组件!!666

如果slot和插槽中都有内容

则slot原先的内容被默认覆盖

具名插槽用法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qbtkcOFO-1649165714788)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220330164550943.png)]

作用域插槽

应用场景:父组件对子组件的内容进行加工处理

  1. 插槽定义
<div id="app">
    <fruit-list :list = 'list'>
        //在组件中间提供内容,使用特殊标签temlpate,通过slot-scope获取子组件中的数据
        <template slot-scope="slotProps"> //用于接受子组件的数据
            <strong v-if = 'slotProps.info.id == 2'  class="current">{{slotProps.info.name}}</strong> //代码高亮
//利用v-if父元素实现对子元素的加工处理
            <span v-else>{{slotProps.info.name}}</span>
        </template>  //利用template将控制逻辑写在里面
    </fruit-list>
</div>


//js:
    //定义全局组件
    Vue.component('fruit-list',{
        props:['list'],
        template:`
        <div>
            <li :key="item.id" v-for = "item in list">
                <slot :info = 'item'>{{item.name}}</slot>
            </li>
        </div>
`
    })
学新通

在父组件中可以获取到子组件中的数据并且对数据进行加工处理

得到的数据就是从子组件的slot中的info的值获取到,info是自定义的,用来传递给父组件

样式绑定

class样式处理

//对象语法  通过true  flase来实现控制逻辑
<div v-bind:class = "{active: isactive}"></div>
//数组语法  通过直接赋值实现控制逻辑
<div v-bind:class = "{activeClass,errorClass}"></div>
//对象绑定和数组绑定结合使用
<div v-bind:class = "{activeClass,errorClass,{active: isactive}}"></div>

样式绑定相关语法细节:

1.对象绑定和数组绑定可以结合使用

2.class绑定的值可以简化操作

用数组或对象包含多个值

3.默认的class如何处理?

默认的class会保留

注意点:

v-bind绑定样式

v-on绑定事件

methods中调用属性记得加this.xxx

style样式处理:

//对象语法  直接写的css样式,不过css样式在data中定义
<div v-bind:style = "{color:activeColor,fontsize:fontSize}"></div>
//数组语法   放多个对象
<div v-bind:style = "{baseStyles,overStyles}"></div>

生命周期

主要阶段:

  1. 挂载(初始化相关属性) 如:methods watch

beforeCreate created beforeMount mounter

  1. 更新(dom元素或者组件的管更操作)

beforUpdate updated

  1. 销毁(销毁相关属性),释放资源

beforeDestroy destroyed

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WJfOH0uU-1649165714789)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220329113214424.png)]

另外特别注意mounted 只有它加载完成之后才能调用后台接口往里面填入数据

vue路由

基本概念与原理:

本质:对应关系

1.后端路由:

概念:根据不同的用户的url请求,返回不同的内容

本质:url请求地址与服务器资源之间的对应关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ePNfaZey-1649165714789)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220329142354123.png)]

2.SPA

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tLMIAaFN-1649165714789)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220329142607552.png)]

2.前端路由

概念:根据不同的用户事件,显示不同的页面内容

本质:用户事件和事件处理函数之间的对应关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IQBLyJ44-1649165714790)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220329142854878.png)]

3.实现简易的前端路由

基于url中的hash实现(点击菜单的时候改变url的hash,根据hash的变化控制组件的切换)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cLVWCr1s-1649165714790)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220329143144280.png)]

//监听window的onhashchange事件,根据获取到的最新的hash值,切换要显示的组件的名称
window.onhashchange = function(){
    //通过location.hash获取到最新的hash值
}
1.利用手动的方式完成一个简单的前端路由
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <!--被vue实例控制的div区域-->
    <div id="app">
        <!--切换组件的超链接-->
        <a href="#/zhuye">主页</a>
        <a href="#/keji">科技</a>
        <a href="#/caijing">财经</a>
        <a href="#/yule">娱乐</a>

        <!--href里面的值就是hash值,即每个a链接的身份证-->

        <!-- 根据 :is属性指定的组件名称,把对应的组件渲染到component 标签所在的位置-->
        <!--可以把 component 标签当作是【组件的占位符】-->
        <component :is = "comName"></component>

    </div>

    <script>
        //实现动态切换,点击a链接切换信息

        //#region定义需要被切换的4个组件
        const zhuye = {
            template:'<h1>主页信息</h1>'
        }
        const keji = {
            template:'<h1>科技信息</h1>'
        }
        const caijing = {
            template:'<h1>财经信息</h1>'
        }
        const yule = {
            template:'<h1>娱乐信息</h1>'
        }
    </script>
    <script>
        const vm = new Vue({
            el:'#app',
            data:{
                comName:zhuye
            },
            //注册私有组件
            components:{
               zhuye,
               keji,
               caijing,
               yule
            }
        })

        //监听 window的onhashchange 事件,根据获取到的最新的hash值,切换要显示的组件的名称
        window.onhashchange = function () {
            //通过 location.hash获取到最新的hash值
            //console.log(location.hash.slice(1))
                //slice(1)代表从索引为1的位置往后取,就没有#啦
                //用case条件判断switch
            switch (location.hash.slice(1)) {
                case '/zhuye':
                    vm.comName = 'zhuye'
                break
                case '/keji':
                    vm.comName = 'keji'
                break
                case '/caijing':
                    vm.comName = 'caijing'
                break
                case '/yule':
                    vm.comName = 'yule'
                break
            }

        }
    </script>
</body>
</html>
学新通

vue router

vue router是vue.js官方的路由管理器

它和vue.js的核心深度集成,可以非常方便的用于SPA应用程序的开发

扩展:SPA:单页Web应用(single page web application,SPA),就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序。

vue router包含的功能有

  1. 支持HTML5历史模式或hash模式
  2. 支持嵌套路由
  3. 支持路由参数
  4. 支持编程式路由
  5. 支持命名路由

vue router的基本使用步骤

1.引入相关的库文件

先引入vue 在引入vue-router 因为后者依赖于前者

2.添加路由链接

router-link 是vue中提供的标签,默认会被渲染为a标签

to 属性默认会被渲染为 href标签

to 属性的值默认会被选认为 #开头的hash地址

<router-link to = "/user">User</router-link>
<router-link to = "/register">Register</router-link>

3.添加路由填充位

路由填充位也叫做路由占位符

将来通过路由规则匹配到的组件,都会被渲染到 router-view所在的位置

<router-view></router-view>

4.定义路由组件

 var User = {
            template:'<div>User</div>'
        }
var Register = {
            template:'<div>Register</div>'
        }

5.配置路由规则并创建路由实例

//创建路由实例对象
var router = new VueRouter({
    //routes 是路由规则数组
    routes:[
        //每个路由规则都是一个配置对象,其中至少包含path和component
        //path表示当前路由规则匹配的hash地址
        //component表示当前路由规则对应要展示的组件
        {path:'/user',component:User},
    	{path:'/register',component:Register}
   ]
})

6.把路由挂载到Vue根实例中

new Vue({
    el:'#app',
    //为了能够让路由规则生效,必须把路由对象挂载到vue实例中
    router
})

路由重定向

路由重定向指的是:用户在访问地址A的时候,强制用户跳转到地址C,从而展示特定的组件页面;通过路由规则的redirect属性,指定一个新的路由地址,可以很方便的设置路由的重定向

比如访问一个页面,直接跳转到展开内容的页面

var router = new VueRouter({
    routes:{
        //其中,path表示需要被重定向的原地址,redirect表示将要被重定向到的新地址
        {path:'/',redirect:'/user'},
    	{path:'/user',compnent:User},
        {path:'/register',component:Register}
    }
})

嵌套路由

1.嵌套路由功能分析:

  1. 点击父级路由链接显示模板内容
  2. 模板内容中又有子级路由链接
  3. 点击子级路由链接显示子级模板内容

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wxsXyE1A-1649165714790)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220329204931117.png)]

 const User = {
        template: '<h1>User</h1>'
    }
    const Register = {
        //子级路由链接  和子级路由填充位放在register下面
        //``是模板字符串
        template: `<div>
                        <h1>Register</h1>
                        <hr/>


                        <router-link to = "/register/tab1">Tab1</router-link>
                        <router-link to = "/register/tab2">Tab2</router-link>

                        <rounter-view>
                    </div>`
    }

        //子路由占位符
    const Tab1 = {
        template:'<h3>tab1 子组件</h3>'
    }
    const Tab2 = {
        template:'<h3>tab2 子组件</h3>'
    }
    //创建路由实例对象
    const router = new VueRouter({
        //routes 是路由规则数组
        routes: [
            //每个路由规则都是一个配置对象,其中至少包含path和component
            //path表示当前路由规则匹配的hash地址
            //component表示当前路由规则对应要展示的组件
            {path: '/user', component: User},  //component只接受组件对象不接受字符串
            {path: '/register',
             component: Register,
                //通过children属性,为/register 添加子路由规则
                //children数组表示子路由规则
                children:[
                    {path:'/resgister/tab1',component:Tab1},
                    {path:'/resgister/tab2',component:Tab2}
                ]

            }
        ]
    })
学新通

动态路由匹配

如果某部分路由规则他们的一部分是一样的,另一部分是变化的,我们可以把这变化的那一部分形成路由参数 ,路由参数就叫路由匹配

var router = new VueRouter({
    routers:[
        //动态数据参数,以冒号开头
        {path:'/user/:id',component:User}
    ]
})
const User = {
    //路由组件中通过$route.params获取路由参数
    template:'<div>User {{$route.params.id}}</div>'
}

上面conponent中的值就是下面实现方法的名称

路由组件传递参数

$route与对应路由行成高度耦合,不够灵活,所以可以使用props将组件和路由解耦关联

1.props的值为布尔类型

const router = new VueRouter({
    routes:[
        //如果props被设置为true,route.params将会被设置为组件属性
        {path:'/user/:id',component:User,props:true}
    ]
})

const User = {
    props:['id']  //使用props接受路由参数  即id值
    template:'<div>用户ID:{{ id }}</div>'  //使用路由参数
}

2.props的值为对象类型

const router = new VueRouter({
    routes:[
        //如果props是一个对象,它会被按原样设置为组件属性
        {path:'/user/:id',component:User,props:{uname:'zcr',age:18}}
    ]
})

const User = {
    props:{'uname','age'},
    template:'<div>用户信息:{{ uname   '----'   age}}</div>'
}  

这里访问的是uname和age的值,id算是废了

那么如何既能访问到uname和age,又能访问到id的值呢?

第三种方法来袭:props的值为函数类型

const router = new VueRouter({
    routes:[
        //如果props是一个函数,则这个函数接受route对象对自己的形参
        {
            path:'/user/:id',
            component:User,
            props:route => ({
                uname:'zcr',
                age:18,
                id:route.params.id
            })
        }
    ]
})

const User = {
    props:['uname','age','id'],
    template:'<div>用户信息:{{uname   "----"   age   "-----"   id}}</div>'
}
学新通

命名路由:

命名路由的配置原理:

为了更加方便地表示路由的路径,可以给路由规则起一个别名,即为“命名路由”

const router = new VueRouter({
    routes:[
        {
            path:'/user/:id',
            name:'user',
            component:User
        }
    ]
})
<router-link :to = "{name : 'user',params:{id:123}}">User</router-link>

//编程式导航
router.push({ name:'user' , params :{id : 123}})

不仅可以根据路径跳转,还可以根据name和id

编程式导航

页面导航的两种方式:

  1. 声明式导航:通过点击链接实现导航的方式,叫做声明式导航

例如:普通网页中的a链接或者vue中的rounter-link

  1. 编程式导航:通过调用JS形式的API实现导航的方式,叫做编程式导航

例如:普通网页中的location.href

基本用法:

常见的编程式导航API如下:

this.$router.push(‘hash地址’) 跳转到某个哈希地址

this.$router.go(n) 前进n或者后退n步

const User = {
    template:'<div><button @click = "goRegister">跳转到注册页面</button></div>'
    methods:{
    goRegister:function(){
        //用编程的方式控制路由跳转
        this.$router.push('/register')
    }
}
}

router.push()方法的参数规则

//字符串(路径名称)
router.push('/home')
//对象
router.push({path:'/home'})
//命名的路由(传递参数)
router.push({name:"/user",params:{userid:123}})
//带查询参数,变成/register?uname = lisi
router.push({path:'/register',query:{uname:'lisi'}})

异步vue

axios的基本特性:

axios是一个基于Promise用于浏览器和node.js的HTTP客户端

axios是一个专门用于调用后台接口的js库 需要引入

它具有以下特性:

  1. 支持浏览器和node.js
  2. 支持promise
  3. 能拦截请求和响应
  4. 自动转换json数据
axios.get('/adata')  //发起请求
	.then(ret=>{
    // data属性名称是固定的,用于获取后台响应的数据
    console.log(ret.data)
})


//后台接口
app.get('/adata',(req,res) => {
    res.send('Hello axios!')
})

axios的常用API

1.GET传递参数

1)通过URL传递参数

//第一种
axios.get('http://localhost:3000/adata?id = 123')
	.then(ret=>{
    console.log(ret.data)
})

//后台接口
app.get('/axios?id = 123',(req,res)=>{
    res.send('axios get 传递参数'   req.query.id)
})


//第二种
axios.get('http://localhost:3000/adata/123')
	.then(ret=>{
    	console.log(ret.data)
})

//后台接口
app.get('/axios/:id',(req,res)=>{
    res.send('axios get (Restful) 传递参数'   req.params.id)
})
学新通

2)通过params选项传递数据(传递多参数这个更方便)

axios.get('http://localhost:3000/adata',{
    params:{
        id:789
    }
})
	.then(ret=>{
    console.log(ret.data)
})

//后台接口
app.get('/axios/:id',(req,res)=>{
    res.send('axios get (Restful) 传递参数'   req.params.id)
})

2.delete传递参数

参数传递方式与get类似

只不过后台只用query 不用params了

//第一种
axios.delete('http://localhost:3000/adata',{
    params:{
        id:789
    }
})
	.then(ret=>{
    console.log(ret.data)
})

//后台接口
app.delete('/axios/:id',(req,res)=>{
    res.send('axios DELETE (Restful) 传递参数'   req.query.id)
})

//第二种
axios.delete('http://localhost:3000/adata?id = 123')
	.then(ret=>{
    console.log(ret.data)
})

//后台接口
app.delete('/axios?id = 123',(req,res)=>{
    res.send('axios DELETE 传递参数'   req.query.id)
})


//第三种
axios.delete('http://localhost:3000/adata/123')
	.then(ret=>{
    	console.log(ret.data)
})

//后台接口
app.delete('/axios/:id',(req,res)=>{
    res.send('axios DELETE (Restful) 传递参数'   req.query.id)
})




学新通

3.post传递参数

通过选项传递参数(默认传递的是json格式的数据)

axios.post('/adata',{
    uname:'tom',
    pwd:123
}).then(ret=>{
    console.log(ret.data)
})

//后台接口
app.post('/axios',(req,res)=>{
    res.send('axios post 传递参数'   req.body.uname   req.body.pwd)
})

通过URLSearchParams传递参数(表单传递)

//先准备一个实例对象,把数据填充到实例对象中
const params = new URLSearchParams();
params.append('uname','zcr');
params.append('pwd','123');
axios.post('http://loacahost:8000/axios',params).then(ret=>{
    console.log(ret.data)
})

//后台接口
app.post('/axios',(req,res)=>{
    res.send('axios post 传递参数'   req.body.uname   req.body.pwd)
})

4.put请求

参数传递方式和POST非常类似

axios.put('/adata/123',{  //做信息修改,加上id
    uname:'zcr',
    pwd:123
}).then(ret=>{
    console.log(ret.data)
})

//后台接口
app.put('/axios/:id',(req,res)=>{
    res.send('axops put 传递参数'   req.params.id   '--'   req.body.uname   '--'   req.body.pwd)
})

JSON比起表单形式的传递参数方式更加方便

axios的响应结果

响应结果的主要属性:

  1. data:实际响应回来的数据
  2. headers:响应头信息
  3. status:响应状态码
  4. statusText:响应状态信息

axios的全局配置

配置请求的基准URL地址

axios.defaults.baseURL= "http://localhost:3000/"

axios.get('adata?id = 123')
	.then(ret=>{
    console.log(ret.data)
})


设置请求头,需要在后台设置允许传递

//后台  : 设置允许跨域访问该服务
app.all('*',function(req,res,next){
    res.header('Access-Control-Allow-Headers','mytoken')
})

//前端
axios.defaults.headers['mytoken'] = 'dawfagaddafags' //某一个字符串 

设置超出时间

axios.defaults.timeout = 3000 //超出时间

axios拦截器

在请求发出之前设置一些信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gLPEZfx0-1649165714791)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220330113221856.png)]

//添加一个请求拦截器
axios.interceptors.request.use(function(config)){
                               //在请求发出之前进行一些信息设置
                               return config;
                               },function(err){
    //处理一些响应的错误信息
}


//axios实例
axios.intercepors.request.use(function(config){
    console.log(config.url)     //可以打印出当前访问的url
    config.headers.mytoken = 'nihao';
    return config
},function(err){
    console.log(err)
})
axios.get("http://localhost:3000/adata").then(function(data){
 console.log(data)
    	
})
学新通

第一个函数进行信息配置,第二个函数做错误警告

响应拦截器

在获取数据之前对数据做一些加工处理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CKCfutuz-1649165714791)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220330114028611.png)]

//添加一个响应拦截器
axios.interceptors.response.use(function(res){
    //在这里对返回的数据进行处理.
    return res;
},function(err){
    //处理响应的错误信息
})

//实例:
axios.interceptors.response.use(function(res){
        console.log(res)     //此时打印出来的是对象
        var data = res.data  //对数据进行拦截处理
		return data
},function(err){
    console.log(err)
})
axios.get('http://localhost:3000/adata').then(function(data){
    console.log(data)  //此时打印出来的就是数据
})

)
学新通

async/await的基本用法

async/await是ES7引入的新语法,可以更加方便的进行异步操作

async 关键字用于函数上,(async函数的返回值是Promise实例对象)

await 关键字用于async函数当中(await可以得到异步的结果)

async function queryData(id){
    const ret = await axios.get('/data');  
    //后面的ret就是promise实例对象
    return ret;
}
queryData.then(ret=>{
    console.log(ret)
})

//这样就不用then了


//实例:
axios.defaults.baseURL = "http:localhost:3000";
/*axios.get('adata').then(function(ret){
    console.log(ret.data)
})*/
//第一种方法
async function queryData(){
    var ret = await axios.get('adata');
    console.log(ret.data)
}
queryData();
//第二种方法
async function queryData(){
    var ret = await axios.get('adata');
    //await后面要跟一个promise实例对象
    //在promise中我们可以处理异步任务
    //console.log(ret.data)
    return ret.data;
}
queryData().then(function(data){
    console.log(data)
});

//第三种方法
async function queryData(){
    var ret = await new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve('nihao')
        },1000)
        return ret;
    })
    //await后面要跟一个promise实例对象
    //在promise中我们可以处理异步任务
   	//这里我们直接换成promise
    
}
queryData().then(function(data){
    console.log(data)
});
学新通

async返回值是一个新的promise实例对象

可以直接用then调用promise实例对象

async/await 处理多个异步请求

多个异步请求的场景

在async中顺序的写请求

async function queryData(id){
    const info = await axios.get('/async1')
    const ret = await axios.get('async2?info = '   info.data)
    return ret
}
queryData.then(ret=>{
    console.log(ret)
})

//后台接口
app.get('/async1',(req,res) =>{
    res.send('hello')
})
app.get('/async2',(req,res) =>{
    if(req.query.info == 'hello'){
        res.send('world')
    }else{
        res.send('error')
    }
})
学新通

vuex

复习:

组件之间共享数据的方式

父向子传值:v-bind属性绑定

子向父传值:v-on事件绑定

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

  1. $on 接收数据的那个组件
  2. $emit 发送数据的那个组件

但上述方法都是小范围的进行数据共享

大范围的数据共享还得靠vuex

vuex是什么

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RZf8go5i-1649165714792)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220330193906566.png)]

如果没有vuex,那么组件之间的数据是靠链条一层一层的进行共享,非常复杂,如果用vue,他会建立一个全局共享数据store,那么就可以直接从store中取数据,非常方便,不需要进行复杂的数据传递。

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

  1. 能够在vuex中集中管理共享的数据,易于开发和后期维护
  2. 能够高效地实现组件之间的数据共享,提高开发效率
  3. 存储在vuex中的数据都是响应式的,能够实时保持数据和页面的同步

什么样的数据适合存储到vuex中

一般情况下,只有组件之间共享的数据,才有必要存储到vuex中

对于组件中的私有数据,依旧存储到组件自身的data中即可

vuex的基本使用

1.安装vuex依赖包

npm i vuex --save

2.导入vuex包

import Vuex from 'vuex'
Vue.use(Vuex)

3.创建store对象

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

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

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

vuex的核心概念

State

State提供唯一的公共数据源,所有共享的数据都要统一放到Store的State中进行提供

//创建store数据源,提供唯一的公共数据
const store = new Vuex.Store({
    state:{ count: 0 }
})

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

this.$store.state.全局数据名称

在template中this可以省略

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

//1.从vuex中按需导入mapState 函数
import {mapState} from 'vuex'

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

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

Mutation

Mutation用于变更Store中的数据

  1. 只能通过mutation变更Store数据,不可以直接操作Store中的数据
  2. 通过这种方式虽然从做起来稍微繁琐一些,但是可以集中监控所有数据的变化
//定义Mutation   在store.js中
const store = new Vuex.Store({
    state:{
        count:0
    },
    mutations:{
        add(state){
            //变更状态
            state.count  
        }
    }
})



//在组件中触发mutation
methods:{
    handle1(){
        //触发mutations的第一种方式
        this.$store.commit('add')
    }
}
学新通

可以在触发Mutation时传递参数

//定义Mutation
const store = new Vuex.Store({
    state:{
        count:0
    },
    mutations:{
        addN(state,srep){
            //变更状态
            state.count  = step
        }
    }
})
//触发mutation
methods:{
    handle2(){
        //在调用commit函数
        //触发mutations时携带参数
        this.$store.commit('addN',3)
    }
}

调用mutation的第二种方式:

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

//1.从vuex中按需导入mapMutations函数
import {mapMutations} from 'vuex'

通过刚才导入的mapMutations函数,将需要的mutations函数,映射为当前组件的methods方法

//2.将指定的mutations函数,映射为当前组件的methods函数
methods:{
    ...mapMutations(['add','addN'])
}

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

Action

Action用于处理异步任务

如果通过异步操作变更数据,必须通过Action

而不能使用Mutation,但是在Action中还是要通过Mutation的方式间接变更数据

//定义Action
const store = new Vuex.Store({
    // 省略其他代码
    mutations:{
        add(state){
            state.count  
        }
    },
    actions:{
        addAsync(context){
            setTimeout(() =>{
                context.commit('add')
            },1000)
        }
    }
})
学新通
//触发Action
methods:{
    handle(){
        //触发actions的第一种方式
        this.$store.dispatch('addAsync')
    }
}

携带参数,和mutation类似

//定义action
const store = new Vuex.Store({
    //其他代码
    mutations:{
        addN(state,step){
            state.count  = step
        }
    },
    acrions:{
        addNAsync(context,step){
            setTimeout(()=>{
                context.commit('addN',step)
            },1000)
        }
    }
})



//触发action

methods:{
    handle(){
        //在调用dispatch
        //触发actions时携带参数
        this.$store.dispatch('addNAsync',5)
    }
}
学新通

触发action的第二种方式

this.$store.dispatch()是触发actions的第一种方式

触发actions的;第二种方式

//1.从vuex中按需导入mapActions函数
import {mapActions} from 'vuex'

通过刚才导入的mapActions函数,将需要的actions函数,映射为当前组件的methods方法

//通过刚才导入的actions函数,映射为当前组件的methods函数
methods:{
    ...mapActions(['addASync','addNASync'])
}

Getter

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

  1. getter可以对store中已有的数据加工处理之后行成新的数据,类似vue的计算属性
  2. store中数据发生变化,getter的数据也会跟着变化
//定义Getter
const store = new Vue.Store({
    state:{
        count:0
    },
    getters:{
        showNum:state =>{
            return '当前最新的数量是['   state.count   '']'
        }
    }
})

使用getters的第一种方式

this.$store.getters.名称

第二种方式

import {mapGetters} from 'vuex'

computed:{
    ...mapGetters(['showNum'])
}

电商后台管理项目

1.1电商项目基本业务概述

根据不同的应用场景,电商系统一般都提供了pc端、移动app端、微信小程序端、移动web等多种终端访问方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4GE2JesI-1649165714792)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220403101301741.png)]

1.2电商后台管理系统的功能

电商后台管理系统用于管理用户账号、商品分类、商品信息、订单、数据统计等业务功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TYKNw7TB-1649165714792)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220403101411659.png)]

1.3 电商后台管理系统的开发模式(前后端分离)

电商后台管理系统整体采用前后端分离的开发模式,其中前端项目是基于Vue技术栈的SPA项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6zPu09eR-1649165714793)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220403101707864.png)]

1.4电商后台管理系统的技术选型

1.前端项目技术栈

  1. Vue
  2. Vue-router
  3. Element-UI
  4. Axios
  5. Echarts

2.后端项目技术栈

  1. Node.js
  2. Express
  3. Jwt(状态保持的工具,模拟类似于session的功能)
  4. Mysql
  5. Sequelize

2.1前端项目初始化步骤

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WklZ9THu-1649165714793)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220403102032674.png)]

2.2后台项目的环境安装配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NaYLLZO6-1649165714793)(C:\Users\命与超然\AppData\Roaming\Typora\typora-user-images\image-20220403112206958.png)]
参数,和mutation类似

//定义action
const store = new Vuex.Store({
    //其他代码
    mutations:{
        addN(state,step){
            state.count  = step
        }
    },
    acrions:{
        addNAsync(context,step){
            setTimeout(()=>{
                context.commit('addN',step)
            },1000)
        }
    }
})



//触发action

methods:{
    handle(){
        //在调用dispatch
        //触发actions时携带参数
        this.$store.dispatch('addNAsync',5)
    }
}
学新通

触发action的第二种方式

this.$store.dispatch()是触发actions的第一种方式

触发actions的;第二种方式

//1.从vuex中按需导入mapActions函数
import {mapActions} from 'vuex'

通过刚才导入的mapActions函数,将需要的actions函数,映射为当前组件的methods方法

//通过刚才导入的actions函数,映射为当前组件的methods函数
methods:{
    ...mapActions(['addASync','addNASync'])
}

Getter

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

  1. getter可以对store中已有的数据加工处理之后行成新的数据,类似vue的计算属性
  2. store中数据发生变化,getter的数据也会跟着变化
//定义Getter
const store = new Vue.Store({
    state:{
        count:0
    },
    getters:{
        showNum:state =>{
            return '当前最新的数量是['   state.count   '']'
        }
    }
})

使用getters的第一种方式

this.$store.getters.名称

第二种方式

import {mapGetters} from 'vuex'

computed:{
    ...mapGetters(['showNum'])
}

电商后台管理项目

1.1电商项目基本业务概述

根据不同的应用场景,电商系统一般都提供了pc端、移动app端、微信小程序端、移动web等多种终端访问方式

[外链图片转存中…(img-4GE2JesI-1649165714792)]

1.2电商后台管理系统的功能

电商后台管理系统用于管理用户账号、商品分类、商品信息、订单、数据统计等业务功能

[外链图片转存中…(img-TYKNw7TB-1649165714792)]

1.3 电商后台管理系统的开发模式(前后端分离)

电商后台管理系统整体采用前后端分离的开发模式,其中前端项目是基于Vue技术栈的SPA项目

[外链图片转存中…(img-6zPu09eR-1649165714793)]

1.4电商后台管理系统的技术选型

1.前端项目技术栈

  1. Vue
  2. Vue-router
  3. Element-UI
  4. Axios
  5. Echarts

2.后端项目技术栈

  1. Node.js
  2. Express
  3. Jwt(状态保持的工具,模拟类似于session的功能)
  4. Mysql
  5. Sequelize

2.1前端项目初始化步骤

[外链图片转存中…(img-WklZ9THu-1649165714793)]

2.2后台项目的环境安装配置

[外链图片转存中…(img-NaYLLZO6-1649165714793)]

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhggcibc
系列文章
更多 icon
同类精品
更多 icon
继续加载