MVVM(Model-View-ViewModel),其实就是所谓的数据的双向绑定mvc
Model:对应数据层的域模型,它主要做域模型的同步。通过 Ajax/fetch 等 API 完成客户端和服务端业务 Model 的同步。在模型层间关系里,它主要用于抽象出 ViewModel 中视图的 Model。个人理解:后端提供API,后端服务架构是 控制器+数据模型 或者 纯控制器。
View:View是作为视图模板,用于定义结构、布局。它自己不处理数据,只是将ViewModel中的数据展现出来。此外为了和ViewModel产生关联,那么还需要做的就是数据绑定的声明,指令的声明,事件绑定的声明。ViewModel和View之间是双向绑定,意思就是说ViewModel的变化能够反映到View中,View的变化也能够改变ViewModel的数据值。
ViewModel:ViewModel起着连接View和Model的作用,同时用于处理View中的逻辑。在MVC框架中,视图模型通过调用模型中的方法与模型进行交互,然而在MVVM中View和Model并没有直接的关系,在MVVM中,ViewModel从Model获取数据,然后应用到View中。个人理解:Web前端的webserver对View进行双向绑定渲染。
整个MVVM实际上实现了前后端分离,通过api来实现前后端交互,前端通过纯js或者双向绑定框架来渲染页面。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
{{message}}
div>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript">
//创建vue js的核心对象,核心Vue对象就是vm
var vm = new Vue({
//配置vm对象管理的html
el: '#app',
//data配置就是数据模型M,它本身是一个字面量对象
//其中字面量对象属性名即数据名,字面量对象的属性值即数据值
data: {
message: 'hello vue',
num:20,
flage:true,
list:['aa','bb','dd'],
obj:{
name: 'xxx',
age:24
}
}
});
script>
body>
html>
<div id="app">
h1>
<p v-text="msg">p>
<h1 v-html="message">h1>
<p v-html="msg">p>
div>
<script type="text/javascript" src="js/vue.js">script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
message: 'hello vue',
msg:'超链接'
}
});
script>
<div id="app">
<h1 title="你好">{{message}}h1>
<h1 v-bind:title="msg">{{message}}h1>
<p :title="msg">{{message}}p>
div>
<script type="text/javascript" src="js/vue.js">script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
message: 'hello vue',
msg:"你好啊"
}
})
script>
<div id="app">
<p><button type="button" v-on:click="myFun1">按键1button>p>
<p><button type="button" @click="myFun2">按键2button>p>
div>
<script type="text/javascript" src="js/vue.js">script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
message: 'hello vue'
},
//事件函数
method: {
myFun1: function () {
console.log("函数1执行了。。。")
},
//简化
myFun2() {
//在函数中可以使用data中的数据,但是必须以this(vue对象)调用
console.log("函数2执行了。。。" + this.message);
}
}
});
script>
用法
vue对象
<script type="text/javascript" src="js/vue.js">script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
message: 'hello vue',
genderVal: 'female',
login: false,
hobbys: ['篮球v', '排球v'],
edu: '',
array: []
}
});
script>
文本框 (单行 多行)
<h1>文本框h1>
<p><input type="text" v-model="message">p>
<p><textarea cols="30" rows="10" v-model="message">textarea>p>
<h1>date中的数据:{{message}}h1>
单选按钮
<h1>单选按钮h1>
<p>
<label><input type="radio" name="gender" value="male" v-model="genderVal">男性label>
<label><input type="radio" name="gender" value="female" v-model="genderVal">女性label>
p>
<p>date中的数据:{{genderVal}}p>
复选框
<h1>复选框h1>
<p>
<label><input type="checkbox" v-model="login">十天免登录label>
p>
<p>
<label><input type="checkbox" name="hobby" value="足球v" v-model="hobbys">足球label>
<label><input type="checkbox" name="hobby" value="篮球v" v-model="hobbys">篮球label>
<label><input type="checkbox" name="hobby" value="乒乓球v" v-model="hobbys">乒乓球label>
<label><input type="checkbox" name="hobby" value="羽毛球v" v-model="hobbys">羽毛球label>
<label><input type="checkbox" name="hobby" value="排球v" v-model="hobbys">排球label>
p>
<p>data中的数据:{{hobbys}}p>
下拉列表
<h1>下拉列表h1>
<p>
<select v-model="edu">
<option value="1">幼儿园option>
<option value="2">小学option>
<option value="3">中学option>
<option value="4">高中option>
<option value="5">大学option>
select>
p>
<p>data中的数据:{{edu}}p>
<p>
<select multiple v-model="array">
<option value="aa">选项1option>
<option value="bb">选项2option>
<option value="cc">选项3option>
<option value="dd">选项4option>
<option value="ee">选项5option>
select>
p>
<p>data中的数据:{{array}}p>
<div id="app">
<p><button type="button" @click="islLogin=!islLogin">登录与退出button>p>
<div v-if="isLogin">当前登陆用户:{{username}}div>
<div v-else>请登陆div>
<p>data中的数据:{{isLogin}}p>
<hr>
<div>
<div v-if="gender == '1'">男性div>
<div v-else-if="gender == '2'">女性div>
<div v-else-if="gender == '3'">保密div>
<div v-else>有误div>
div>
<hr>
<div v-show="isLogin">v-show指令div>
div>
<script type="text/javascript" src="js/vue.js">script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
message: 'hello vue',
username: '张三',
isLogin: true,
gender: '5'
}
})
script>
列表渲染
<div id="app">
<ul>
<li v-for="name in nameList">{{name}}li>
ul>
<hr>
<ul>
<li v-for="name of nameList">{{name}}li>
ul>
<hr>
<ul>
<li v-for="(name, index) of nameList">{{name}}--{{index}}li>
ul>
<hr>
<ul>
<li v-for="(name, index) of nameList" :key="index">{{name}}--{{index}}li>
ul>
<hr>
<table border="1" width="500" align="center">
<tr>
<th>编号th>
<th>姓名th>
<th>年龄th>
<th>成绩th>
tr>
<tr v-for="student in studentList" :key="student.id">
<td>{{student.id}}td>
<td v-text="student.name">td>
<td v-text="student.age">td>
<td v-text="student.score">td>
tr>
table>
div>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
message: 'hello vuejs',
nameList: ['张三', '李四', '王五', '赵柳', '小七', '大巴'],
studentList: [
{id: 101, name: '小明', age: 20, score: 90},
{id: 102, name: '小红', age: 21, score: 87},
{id: 103, name: '小张', age: 23, score: 76},
{id: 104, name: '小王', age: 20, score: 69},
{id: 105, name: '小李', age: 22, score: 100}
]
}
});
script>
<div id="app">
<p>{{message}}p>
<p>{{message.split(' ').reverse().join(' ')}}p>
<p>{{msg}}p>
div>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
message: 'hello vuejs'
},
//计算属性: 处理data中的数据
computed: {
msg: function (){
var array = this.message.split(' ');
array.reverse();
//计算属性的函数必须有返回值
return array.join('$$');
}
}
});
script>
<div id="app">
<p>姓名:<input type="text" v-model="name">p>
<p>{{name}}p>
div>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
message: 'hello vuejs',
name: ''
},
//侦听器:监听data数据的变化
watch: {
/**
* 侦听函数
* 名称:与侦听的数据名一致
* 参数:1数据变化之后的值 2数据变化之前的值
*/
name: function (newVal, oldVal){
console.log('新数据', newVal);
console.log('老数据', oldVal);
}
}
});
script>
钩子函数:生命周期的某个阶段会执行的函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TqWeHOY9-1661774468138)(E:\JAVA\DLJD\我的笔记\myImages\Vue知识点总结\lifecycle.16e4c08e.png)]
<div id="app">
<p>{{ message }}p>
<p><button type="button" @click="message += '2022'">按钮button>p>
div>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
message: 'hello vuejs'
},
methods: {
myFun(){
console.log('myFun....')
}
},
//生命周期钩子函数
beforeCreate(){
//vue对象已经创建,但是data数据与method函数没有初始化
console.log('beforeCreate', this.message);
// this.myFun();
},
created(){
//data数据与method函数已经初始化完成
console.log('created', this.message);
this.myFun();
},
beforeMount(){
//mount挂载:解析模板(动态的内容被替换成静态数据)
//模板没有被解析
var dom = document.querySelector('#app > p');
console.log('beforeMount', dom.innerHTML);
},
mounted(){
//模板已经解析完成
var dom = document.querySelector('#app > p');
console.log('mounted', dom.innerHTML);
},
beforeUpdate(){
//vue对象运行期间,当data数据变化时
//data数据已经变化,但没有渲染到页面
console.log('beforeUpdate-data', this.message);
var dom = document.querySelector('#app > p');
console.log('beforeUpdate-html', dom.innerHTML);
},
updated(){
//data数据已经变化,也渲染到页面
console.log('updated-data', this.message);
var dom = document.querySelector('#app > p');
console.log('updated-html', dom.innerHTML);
},
beforeDestroy(){
},
destroyed(){
}
});
script>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style type="text/css">
.red {
color: red;
}
.size {
font-size: 25px;
}
.back {
background-color: green;
}
style>
head>
<body>
<div id="app">
<h2>内联样式h2>
<div style="color: red; font-size: 20px; background-color: green;">{{message}}div>
<h2>样式类h2>
<div class="red size back">{{message}}div>
<h2>对象h2>
<div :class="{red: true, size: true, back: false}">{{message}}div>
<div :class="obj">{{message}}div>
<h2>数组h2>
<div :class="['red', 'size', flag?'back':'']">{{message}}div>
<p><button type="button" @click="flag = !flag">按钮button>p>
div>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
message: 'hello vuejs',
obj: {
red: true,
size: true,
back: true
},
flag: true
}
});
script>
body>
html>
作用:处理数据
全局定义
Vue.filter(过滤器名,过滤函数(源数据,参数1,参数2...){})
局部定义
var vm = new Vue({
...
filters: {
过滤函数名: (source){
return source+'局部过滤器'
}
}
});
<div id="app">
<p>{{ message }}p>
<p>{{ message | msgFormat1 }}p>
<p>{{ message | msgFormat2('夏向向') }}p>
<p>{{ message | msgFormat3('小王','小盼') }}p>
<p>{{ message | msgFormat4 }}p>
div>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript">
/**
* 过滤器:处理数据,数据格式化
* 1.全局定义
* Vue.filter(过滤器名,过滤函数(源数据,参数1,参数2...){})
*/
Vue.filter('msgFormat1', function (source) {
//过滤器返回值,处理数据后的结果
//只改一个
// return source.replace('vue', 'java');
//改所有匹配的(区分大小写)
// return source.replace(/vue/g, 'java');
//改所有匹配的(不区分大小写)
return source.replace(/vue/ig, 'java');
});
//传入一个或多个参数
Vue.filter('msgFormat2',function (source,param) {
return source.replace(/vue/ig, param);
});
Vue.filter('msgFormat3',function (source,param1,param2) {
return source.replace(/vue/ig, param1+" and "+param2);
});
var vm = new Vue({
el: '#app',
data: {
message: '我爱vue,vue爱我,Vue真牛!'
},
//2.局部过滤器
filters: {
//过滤函数
msgFormat4(source){
return source+'局部过滤器'
}
}
});
script>
Vue.component(组件名称, 组件配置);
三种使用方式
<div id="app">
<login>login>
<login>login>
<register>register>
<tabs>tabs>
div>
<template id="tabs">
<div>
<table border="1" width="300">
<tr>
<th>表头1th>
<th>表头2th>
<th>表头3th>
tr>
<tr>
<td>数据11td>
<td>数据12td>
<td>数据13td>
tr>
<tr>
<td>数据21td>
<td>数据22td>
<td>数据23td>
tr>
table>
div>
template>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript">
/**
* 全局组件
* Vue.component(组件名称, 组件配置);
*/
//方式一
Vue.component('login', {
//html模板
template: '用户登录组件
'
});
//方式二 (不推荐,麻烦)
var register = Vue.extend({
template: '用户注册组件
'
});
Vue.component('register', register);
//方式三:使用组件模板
Vue.component('tabs', {
template: '#tabs'
});
var vm = new Vue({
el: '#app',
data: {
message: 'hello vuejs'
}
});
script>
<div id="app">
<pageheader>pageheader>
<pagefooter>pagefooter>
div>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript">
var pageheader = {
template: '页面顶部组件
'
};
var pagefooter = {
template: '页面底部组件
'
};
var vm = new Vue({
el: '#app',
data: {
message: 'hello vuejs'
},
//注册局部组件
components: {
//字面量对象
//属性名为组件的名称,属性值为组件的配置
pageheader: pageheader,
//字面量对象的简化写法(属性名与属性值一致时可简化)
pagefooter
}
});
script>
<div id="app">
<my-main>my-main>
<my-main1>my-main1>
<mymain2>mymain2>
div>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript">
Vue.component('my-main',{
template: '使用-命名:my-main
'
}),
Vue.component('MyMain1',{
template: '使用驼峰命名:MyMain1
'
}),
Vue.component('mymain2',{
template: '第一个div第二个div'
})
var vm = new Vue({
el: '#app',
data: {
message: 'hello vuejs'
}
});
script>
<div id="app">
<list-nav>list-nav>
<list-nav>list-nav>
<list-nav>list-nav>
div>
<template id="listNav">
<div>
<p><button type="button" @click="changeAge">按钮button>p>
<ul>
<li><a href="#">首页--{{msg}}a>li>
<li><a href="#">新闻--{{username}}a>li>
<li><a href="#">用户--{{age}}a>li>
<li><a href="#">关于--{{address}}a>li>
ul>
div>
template>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript">
/**
* 组件的数据与函数
* data: 数据
* 组件中的数据data是一个函数,并且函数有返回值,返回值为字面量对象(此字面量对象为数据)
* 好处:
* 1.数据可以拥有自己的过程代码(对数据进行初步处理)
* 2.组件中的数据在组件复用时,每个组件实例中的数据是隔离(相互不影响)
*/
var listNav={
template: '#listNav',
data() {
//数据函数体:初步数据处理
return {
msg: '组件',
username: 'zhangsan',
age: 24,
address: '北京'
}
},
//组件中的事件函数
methods: {
changeAge(){
this.age++;
}
}
}
var vm = new Vue({
el: '#app',
data: {
message: 'hello vuejs'
},
components: {
listNav
}
});
script>
父组件可以将属性和方法传给子组件
在父组件中绑定子组件属性,和传递方法
<sub-component v-bind:msg="message" v-on:demo="test"></sub-component>
<div id="app">
<h2>父组件中的数据:{{message}}h2>
<p><button type="button" @click="message+='666'">修改父组件中的数据button>p>
<sub-component :msg="message" @demo="test">sub-component>
div>
<template id="sub">
<div>
<h2>子组件中的数据:{{username}}h2>
<h2>子组件接收父组件传递的数据: {{msg}}h2>
<p><button type="button" @click="myFun">调用父组件中的函数button>p>
div>
template>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript">
//子组件
var subComponent={
template: '#sub',
data() {
return{
username:'tom'
}
},
/**
* 接收
* 通过props配置来接收父组件传递过来的数据
*
* props的值
* 1.数组: 数组中存放就是接收数据的变量名称
* 2.对象:属性名称即变量名称,其值为数据类型
*/
// props: ['msg']
props: {
msg: String
},
methods: {
myFun(){
/**
* 在子组件中通过触发调用,来调用父组件中传递过来的函数
* $emit('调用的函数名', 函数参数)
*/
// this.demo()
this.$emit('demo', 'hello');
}
}
};
//父组件
var vm = new Vue({
el: '#app',
data: {
message: 'hello vuejs'
},
methods: {
test(param){
console.log('test函数执行了...'+param)
}
},
components: {
subComponent
}
});
script>
子组件将属性和方法传递给父组件
1.向子组件传数据,添加一个关键字(修饰符)
<sub-component :msg.sync="message" @damo="test">sub-component>
2.通过触发调用函数,向父组件传递数据
//$emit('update:props中的变量名称', 传递的数据值);
this.$emit('update:msg','你好vuejs');
<div id="app">
<h2>父组件中的数据:{{message}}h2>
<p><button type="button" @click="message += '666'">修改父组件中的数据button>p>
上面是父组件<hr color="red">下面是子组件
<sub-component :msg.sync="message" @damo="test">sub-component>
div>
<template id="sub">
<div>
<h2>子组件中的数据: {{username}}h2>
<h2>子组件接收父组件传递的数据: {{msg}}h2>
<p><button type="button" @click="myFun">调用父组件中的函数button>p>
<p><button type="button" @click="msg += '123'">修改子组件中的propsbutton>p>
<p><button type="button" @click="changeMsg">子传父的方法button>p>
div>
template>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript">
//子组件
var subComponent={
template: '#sub',
data() {
return {
username: 'xxx'
}
},
/**
* 父组件中的数据变化,子组件中的数据也会变化
* 但是,如果子组件中的props数据变化,父组件中的数据是不会变化。数据传递为单向, 父 --> 子
* 注意: porps的数据是不允许修改的,仅允许读取
*/
props: {
msg: String
},
methods:{
myFun() {
this.$emit('demo', 'hello')
},
changeMsg(){
/**
* 2.通过触发调用函数,向父组件传递数据
* $emit('update:props中的变量名称', 传递的数据值);
*/
this.$emit('update:msg','你好vuejs');
}
}
};
//父组件
var vm = new Vue({
el: '#app',
data: {
message: 'hello vuejs'
},
methods: {
test(param){
console.log('test函数执行了....' + param)
}
},
components:{
subComponent
}
});
script>
<template>
<div>div>
template>
<script>
//组件的js代码区域
export default {
data(){
return {}
},
methods: {},
props: {},
watch: {},
computed: {},
components: {},
mounted(){}
}
script>
<style scoped>
/**
css代码区域
注意:样式是整个项目中所有的.vue文件共享
scoped属性表示当前组件中的样式为私有样式
*/
.demo{
font-size: 30px;
}
style>
vue-router.js文件<div id="app">
<h1>欢迎使用路由h1>
<router-link to="/login">登录router-link>
<router-link to="/reg">注册router-link>
<router-view>router-view>
div>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript" src="./js/vue-router.js">script>
<script type="text/javascript">
//1.定义组件
var login = {template: '登录组件
'};
var register = {template: '注册组件
'};
//2.定义路由
//路由作用:切换组件,组件之间的数据传递
var router = new VueRouter({
//路由模式,默认hash,历史模式history
// mode: 'history',
//路由列表: 路径与组件的对应
routes: [
/**
* 单个路由对象
* path: 路由路径字符串,值必须以斜杠开头
*/
{path: '/login', component: login},
{path: '/reg', component: register}
]
});
var vm = new Vue({
el: '#app',
data: {
message: 'hello vuejs'
},
//3.在vue对象中设置路由
router
});
script>
<div id="app">
<h1>欢迎使用路由h1>
<router-link to="/login?username=tom&password=123">登录router-link>
<router-link to="/reg/101/zhangsan">注册router-link>
<router-view>router-view>
div>
<template id="login">
<div>
<h1>登录组件h1>
<p>{{$route.query}}p>
<p>{{$route.query.username}}p>
<p>{{$route.query.password}}p>
div>
template>
<template id="reg">
<div>
<h1>注册组件h1>
<p>{{$route.params}}p>
<p>{{$route.params.id}}p>
<p>{{$route.params.username}}p>
div>
template>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript" src="./js/vue-router.js">script>
<script type="text/javascript">
//1.定义组件
var login = {template: '#login'};
var register = {template: '#reg'};
//2.定义路由
var router = new VueRouter({
routes: [
{path: '/login', component: login},
{path: '/reg/:id/:username', component: register}
]
});
var vm = new Vue({
el: '#app',
data: {
message: 'hello vuejs'
},
//3.在vue对象中设置路由
router
});
script>
<div id="app">
<h1>欢迎使用路由h1>
<h2>声明式导航h2>
<p>
<router-link to="/login">登录router-link>
<router-link to="/reg">注册router-link>
<router-link to="/user">用户router-link>
<router-link to="/emp">员工router-link>
p>
<h2>编程式导航h2>
<p>
<button type="button" @click="doRedirect('login')">登录按钮button>
<button type="button" @click="doRedirect('reg')">注册按钮button>
<button type="button" @click="doRedirect('user')">用户按钮button>
<button type="button" @click="doRedirect('emp')">员工按钮button>
p>
<p>
<button type="button" @click="doBackward">后退button>
<button type="button" @click="doForward">前进button>
p>
<router-view>router-view>
div>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript" src="./js/vue-router.js">script>
<script type="text/javascript">
//1.定义组件
var login = {template: '登录组件{{$route.query}}
'};
var register = {template: '注册组件{{$route.query}}
'};
var user = {template: '用户组件{{$route.params}}
'};
var emp = {template: '员工组件{{$route.params}}
'};
//2.定义路由
//路由作用:切换组件,组件之间的数据传递
var router = new VueRouter({
routes: [
//name: 路径的名称
{path: '/login', name: 'login', component: login},
{path: '/reg', name: 'reg', component: register},
{path: '/user', name: 'user', component: user},
{path: '/emp', name: 'emp', component: emp}
]
});
var vm = new Vue({
el: '#app',
data: {
message: 'hello vuejs'
},
//3.在vue对象中设置路由
router,
methods: {
/**
* 编程式导航
* $router 全局路由对象
*
* push() 在路由导航的同时,在历史列表中添加一个新的历史记录
* replace() 在路由导航的同时,在历史列表中替换最后一个历史
* go() 导航到指定的历史记录
*/
doRedirect(name){
// this.$router.replace('/'+name);
/*两种传参方式*/
//1.query
// this.$router.push({
// path: '/' + name,
// query: {
// id: 10,
// name: '张三'
// }
// });
//2.params
//编程式导航通过params传递参数时,不能使用路径进行导航,应该使用路径名称
this.$router.push({
// path: '/'+name,
name: name,
params: {
id: 20,
name: '李四'
}
});
},
doForward(){
this.$router.go(1);
},
doBackward(){
this.$router.go(-1);
}
}
});
script>
<div id="app">
<h1>欢迎使用路由h1>
<p>
<router-link to="/login">登录router-link>
<router-link to="/main">主页router-link>
p>
<router-view>router-view>
div>
<template id="main">
<div>
<h2>导航h2>
<p>
<router-link to="/main/user">用户router-link>
<router-link to="/main/emp">员工router-link>
<router-link to="/main/dept">部门router-link>
p>
<router-view>router-view>
div>
template>
<script type="text/javascript" src="./js/vue.js">script>
<script type="text/javascript" src="./js/vue-router.js">script>
<script type="text/javascript">
//1.定义组件
var login = {template: '登录组件
'};
var main = {template: '#main'};
var user = {template: '用户组件
'};
var emp = {template: '员工组件
'};
var dept = {template: '部门组件
'};
//2.定义路由
var router = new VueRouter({
routes: [
{path: '/login', name: 'login', component: login},
{
path: '/main',
name: 'main',
component: main,
//嵌套路由,子路由列表
children: [
//嵌套路由:1.相对路径:不以斜杠开头(父路径+子路由路径) 2绝对路径:以斜杠开头
// 如果子路由路径为user,真实路径为/main/user
// 如果子路由路径为/user,真实路径为/user
{path: 'user', name: 'user', component: user},
{path: 'emp', name: 'emp', component: emp},
{path: 'dept', name: 'dept', component: dept}
]
}
]
});
var vm = new Vue({
el: '#app',
data: {
message: 'hello vuejs'
},
router
});
script>
Node.js 是一个开源和跨平台的 JavaScript 运行时环境
作用:以前需要把 js 代码写到html文件中执行,现在可以直接执行了
#例如执行 hello.js
node hello.js
Nodejs package managerment
npm是node提供的一个包管理系统,类似于maven
通过npm去安装依赖包,就不需要在页面上使用script标签引入了
建立 node.js 项目
npm init
建立完项目会生成package.json文件
脚本:json文件中的 scripts
...
"scripts": {
"test": "echo 'hello nodeJs'"
},
...
#运行脚本
npm run test
管理当前项目依赖:dependencies
如使用命令
npm install md5
生成node_modiles文件夹,此文件夹存放第三方的依赖
命令
#配置淘宝下载源
#设置
npm config set registry https://registry.npm.taobao.org
#查看
npm config get registry
#根据package.json文件中依赖下载当前项目中所有的依赖
npm install
#简化写法
npm i
#安装指定包
npm install 包名
#下载指定版本
npm install 包名@版本号
#搜包的网站:https://www.npmjs.com/
#安装指定包到dev环境
npm install --save-dev 包名
#也可简写为
npm i -D 包名
npm i -D axios@0.26.1
#安装到全局(非当前项目目录,在所有的项目中都可使用)
npm install -g 包名
#npm镜像加速配置
npm install -g cnpm --registry=https://registry.npm.taobao.org
#查看版本
nnpm -v
#卸载
npm uninstall 包名
npm uninstall -g 包名
#设置全局安装目录,注意:需要修改环境变量
#查看
npm config get prefix
#设置
npm config set prefix 位置
npm config set prefix D:\RuanJian\nodejs_cache\npm
#设置npm缓存目录
#查看
npm config get cache
#设置
npm config set cache 位置
dependencies:开发与发布环境都可使用的依赖
devDependencies:开发环境使用的依赖
vue-cli(vue脚手架),它是一个专门为单页面应用快速搭建繁杂的脚手架
它可以轻松的创建新的应用程序而且可用于自动生成vue和webpack的项目模板。
vue-cli是有Vue提供的一个官方cli,专门为单页面应用快速搭建繁杂的脚手架。
它是用于自动生成vue.js+webpack的项目模板
安装vue-cli脚手架
npm install -g @vue/cli@4.5.19
执行命令配置项目
vue create 项目名称
#使用图形化界面创建项目
vue ui
打开npm工具窗口:package.json右键—>show npm Spripts
包:前端项目
模块:一个独立的js文件(类似于Java中类)
demo / user.js
//模块:定义的变量和函数都是私有的
var id=20;
var username='xxx';
var password='13413';
var login=function (){
console.log('登录函数');
}
//导出:普通导出,可以导出多个变量和函数,也可以多次导出
export {id,username,password,login}
student / index.js
var stu = {
id: 10,
name: '张三',
age: 21,
address: '上海'
}
//导出默认:仅能导出一次,一次仅能有一个对象
export default stu;
main.js
//启动项目即被执行
import Vue from 'vue'
import App from './App.vue'
import router from './router'
//导入user.js导出的文件
import {id,username,password,login} from "@/demo/user";
// import {id,username,password,login} from "./demo/user";
//导入student
import student from './student'
//打印导入的值
console.log("用户ID", id);
console.log("用户名", username);
console.log("密码", password);
login();
console.log("学生", student);
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')//这里定义了入口组件
复用组件:可复用
页面式组件:不复用的,独此一份
Dept.vue
<template>
<div>
<h1>部门页面h1>
<table border="1" width="450" align="center">
<tr>
<th>部门编号th>
<th>部门名称th>
<th>部门位置th>
tr>
<tr v-for="dept in deptList" :key="dept.id">
<td>{{dept.id}}td>
<td>{{dept.name}}td>
<td>{{dept.loc}}td>
tr>
table>
div>
template>
<script>
export default {
name: "Dept",
data() {
return {
deptList: []
}
},
methods: {
listHandle(){
this.deptList = [
{id: 11, name: '研发部', loc: '北京'},
{id: 12, name: '生产部', loc: '上海'},
{id: 13, name: '采购部', loc: '深圳'},
{id: 14, name: '销售部', loc: '杭州'},
{id: 15, name: '人力部', loc: '苏州'}
];
}
},
mounted() {
this.listHandle();
}
}
script>
<style scoped>
style>
用于加载组件
两种加载方式:立即加载 延迟加载
index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
//立即导入(立即加载)组件
import Home from '../views/Home.vue'
//使用路由
Vue.use(VueRouter)
//路由列表
const routes = [
{path: '/', name: 'Home', component: Home},
//组件延迟加载
{path: '/about', name: 'About', component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')},
{path: '/dept', name: 'dept', component: () => import(/* webpackChunkName: "dept" */ '@/views/Dept.vue')},
{path: '/emp', name: 'emp', component: () => import(/* webpackChunkName: "emp" */ '@/views/Emp.vue')}
]
const router = new VueRouter({
routes
})
export default router
在App.vue入口组件中添加路由
App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/">Homerouter-link> |
<router-link to="/about">Aboutrouter-link> |
<router-link to="/dept">部门router-link> |
<router-link to="/emp">员工router-link>
div>
<router-view/>
div>
template>
...
安装
$ npm install axios
在XXX.Vue文件
axios.get(url, config)
axios.post(url, data, config)
axios.put(url, data, config)
axios.delete(url, config)
/* 传递参数:
* get与delete在配置中定义一个属性params(路径拼接传递参数)
*post与put提价数据时在data参数填写数据即可,data参数本身是一个字面量对象,提交时会被转换为json字符串提交
* axios发送请求时,ContentType内容类型默认为application/json
*/
axios({
method: 'post',
url: '/test',
data: {
id: 10,
name: 'zhangsan'
}
});
axios.get('/getTest',{
params: {
id: 20,
name: 'list'
}
});
axios.post('/postTest', {
id: 30,
name: 'wangwu'
});
/**
* 注意:如果需要进行跨域异步请求,路径必须写成完整
* 连调函数then()成功回调,catch()失败回调
* 此两个函数的参数也是一个函数,回调处理程序
* 回调函数的参数为axios封装的一个对象,在此对象中有一个属性data为服务端真正响应的数据
*/
var that = this;
axios.get('http://localhost:8080/dept/list').then(function(res){
console.log('响应内容', res.data.data);
//在function函数中this关键字指向发生了改变
that.deptList = res.data.data;
console.log('deptList:',that.deptList)
}).catch(function (){
});
/**
* 箭头函数:类似于Java lamda表达式
* 替代匿名函数
* function(){}
* () => {}
*
* function(id){}
* id => {}
*
* function(id,name){}
* (id,name) => {}
*
* function(){console.log();}
* () => console.log();
* 好处:函数体内不改变this关键字的指向
*/
axios.get('http://localhost:8080/dept/list').then(res => {
if(res.data.code == 0){
this.deptList = res.data.data;
}
}).catch(res => console.log(res));
上面的写法还是太麻烦
创建xxx.js文件,配置axios
//导入axios
import axios from 'axios';
//创建axios对象,进行公共配置
var instance = axios.create({
//基础路径
baseURL: 'http://localhost:8080',
//请求超时时间
timeout: 10000
});
//发送请求允许携带凭证(cookie)
instance.defaults.withCredentials=true;
//请求拦截器:在axios发送请求之前作出处理
instance.interceptors.request.use(config => {
console.log('请求的配置对象', config);
//设置请求头部信息
config.headers['myToken'] = 'hello axios';
return config;
}, error => Promise.reject(error));
//响应拦截器:在axios收到响应之后作出处理
instance.interceptors.response.use(response => {
//将服务器响应的数据从axios的封装中取出,直接返回
return response.data;
}, error => Promise.reject(error));
//导出axios对象
export default instance;
使用工具类
在main.js中导入,并挂载到全局
//导入axios工具类
import request from '@/utils/request'
...
//将axios工具类对象挂载到全局(Vue对象),$ajax是自定义的属性名,用的时候保持一致就可以
Vue.prototype.$ajax = request;
在xxx.vue中使用
//this 是vue对象
this.$ajax.get('/dept/list').then(res => {
console.log('服务端响应的数据:', res)
if(res.code == 0){
this.deptList = res.data;
}
}).catch(res => console.log(res));
(){
});
#### 箭头函数
```js
/**
* 箭头函数:类似于Java lamda表达式
* 替代匿名函数
* function(){}
* () => {}
*
* function(id){}
* id => {}
*
* function(id,name){}
* (id,name) => {}
*
* function(){console.log();}
* () => console.log();
* 好处:函数体内不改变this关键字的指向
*/
axios.get('http://localhost:8080/dept/list').then(res => {
if(res.data.code == 0){
this.deptList = res.data.data;
}
}).catch(res => console.log(res));
上面的写法还是太麻烦
创建xxx.js文件,配置axios
//导入axios
import axios from 'axios';
//创建axios对象,进行公共配置
var instance = axios.create({
//基础路径
baseURL: 'http://localhost:8080',
//请求超时时间
timeout: 10000
});
//发送请求允许携带凭证(cookie)
instance.defaults.withCredentials=true;
//请求拦截器:在axios发送请求之前作出处理
instance.interceptors.request.use(config => {
console.log('请求的配置对象', config);
//设置请求头部信息
config.headers['myToken'] = 'hello axios';
return config;
}, error => Promise.reject(error));
//响应拦截器:在axios收到响应之后作出处理
instance.interceptors.response.use(response => {
//将服务器响应的数据从axios的封装中取出,直接返回
return response.data;
}, error => Promise.reject(error));
//导出axios对象
export default instance;
使用工具类
在main.js中导入,并挂载到全局
//导入axios工具类
import request from '@/utils/request'
...
//将axios工具类对象挂载到全局(Vue对象),$ajax是自定义的属性名,用的时候保持一致就可以
Vue.prototype.$ajax = request;
在xxx.vue中使用
//this 是vue对象
this.$ajax.get('/dept/list').then(res => {
console.log('服务端响应的数据:', res)
if(res.code == 0){
this.deptList = res.data;
}
}).catch(res => console.log(res));