文章目录
vue项目结构说明:
vue文件结构.png
vue项目结构.png
vue操作元素的数据绑定
- 在vue的模板里面所有的内容 需要一个根节点包裹起来
- data(){} 业务逻辑里面定义的数据
- return {} 里面定义数据
- v-bind:title=“url” 绑定属性 或者 简写 :titile=“url”
- v-html 浏览器解析Html 绑定HTML
- 绑定数据的另一种方法 v-txt 也可以绑定数据
- v-bind:class =“对象” v-bing:class="{‘red’:flag,‘blue’:!flag}" flag = true
- v-bind:style 绑定一个样式
vue 双向数据绑定 和 获取表单数据 (dom 节点获取)
- MVVM 框架
- M : model V: view model改变会影响view view改变会影响 mode
- 双向数据绑定在 表单中使用
- ref = “userinfo” console.log(this.$ref.userinfo); //获取dom 节点
- ref 主要用来获取 DOM节点
vue 事件以及方法
- v-on:click=“run1()” //点击事件 触发run1() 方法 @click 简写
vue ToDoList vue实现TODOList
mounted(){} //声明周期函数 vue页面刷新就会触发的方法 和 data() 平级
vue中的组件: 有 模板 业务逻辑 css
vue中所有的内容要被根节点包含起来
组件的使用 :
1: 引入组件
<script>
//引入组件
import Home from "./components/Home.vue";
export default {
data() {
return {
msg: "你好vue"
};
},
components: {
"v-home": Home
}
};
</script>
2: 挂载组件
<script>
import Home from "./components/Home.vue";
export default {
data() {
return {
msg: "你好vue"
};
},
//挂载组件
components: {
"v-home": Home
}
};
</script>
3: 在模板中使用
<template>
<div id="app">
{{msg}}
//在模板中使用
<v-home></v-home>
</div>
</template>
scoped 在css 中的作用 使当前组件的样式只作用当前组件 css局部作用域
组件的名字不能和HTML的标签的名字相同
vue生命周期以及钩子函数
vue生命周期.png
-
生命周期函数是组件挂载 以及组件更新 销毁 的时候触发的一系列的方法,这些方法叫做生命周期函数;
-
<script> export default { data() { return { msg: "我是一个vue生命周期函数的组件" }; }, methods: { setMsg() { this.msg = "我是改变后的方法"; } }, beforeCreate() { console.log("实例刚刚被创建1"); }, created() { console.log("实例已经创建完成2"); }, beforeMount() { console.log("模板编译之前3"); }, mounted() { /*请求数据, 操作dom 放在这个里面 mounted 这个方法很重要*/ console.log("模板编译完成4"); }, beforeUpdate() { console.log("数据更新之前"); }, updated() { console.log("数据更新完毕"); }, beforeDestroy() { /*页面销毁的时候要保存一些数据 就可以监听这个销毁的生命周期函数*/ console.log("实例销毁之前"); }, destroyed() { console.log("实例销毁完成"); } }; </script>
vue请求数据的模块:
- vue-resource
-
官方提供的 vue的一个插件
-
(1)安装 npm install vue-resource --save
//在package.json中生成 "vue-resource" "dependencies": { "vue": "^2.5.2", "vue-resource": "^1.5.1", "vue-router": "^3.0.1" },
-
(2)引用 插件
//在main.js 中引入vue-resource import Vue from 'vue' import App from './App' import router from './router' import VueResource from 'vue-resource' Vue.config.productionTip = false Vue.use(VueResource); new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
-
(3)在组件中使用
methods: { getData() { var api = "http://192.168.0.106:8899/ypgzt_new/api/ypgzt/v1/getJzCode"; this.$http.get(api).then( function(response) { console.log(response); this.list = response.body.result; }, function(error) { console.log(error); } ); } }, //使用剪头函数 methods: { getData() { var api = "http://192.168.0.106:8899/ypgzt_new/api/ypgzt/v1/getJzCode"; this.$http.get(api).then(response => { console.log(response); this.list = response.body.result; },response => { console.log(error); } ); } },
-
axios 第三方插件
-
安装 npm install axios --save
//在package.json中生成 "axios" "dependencies": { "axios": "^0.19.0", "vue": "^2.5.2", "vue-resource": "^1.5.1", "vue-router": "^3.0.1" },
-
哪里用哪里引入
<script> import Header from "../components/Header.vue"; import Lify from "../components/Lify.vue"; import Axios from 'axios'; //此处注意引入 export default { data() { return { flag: true, list: [] }; }, methods: { getData() { var api = "http://192.168.0.106:8899/ypgzt_new/api/ypgzt/v1/getJzCode"; Axios.get(api) .then(response => { console.log(response); this.list=response.data.result; }) .catch(error => { console.log(error); }); } }, mounted() { this.getData(); }, components: { "v-header": Header, "v-lify": Lify } }; </script>
-
-
fetch-jsonp JSONP 仅支持GET方法
-
安装 npm install fetch-jsonp --save
//在package.json中生成 "fetch-jsonp" "dependencies": { "axios": "^0.19.0", "fetch-jsonp": "^1.1.3", "vue": "^2.5.2", "vue-resource": "^1.5.1", "vue-router": "^3.0.1" },
-
使用
<template> <div id="Fetchjsonp"> <p>{{msg}}</p> </div> </template> <script> import Fetchjsonp from "fetch-jsonp"; //引入 export default { name: "Fetchjsonp", data() { return { msg: "Fetchjsonp" }; }, mounted() { let api = "http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1"; Fetchjsonp(api) .then(res => { return res.json(); }) .then(res => { console.log(res); }); } }; </script>
-
vue父子组件传值:
https://cn.vuejs.org/v2/guide/components-props.html#Prop-%E9%AA%8C%E8%AF%81
父组件给子组件传值
-
父组件调用子组件的时候,绑定动态属性
-
在子组件里面通过 props接受父组件传过来的数据 props: [“title”] 应用 : {title}
-
可以把一个 属性 方法 整个实例
/*父组件*/ <template> <div class="div"> <v-header :title="title" :run="run" :home="this"></v-header> <br /> <hr /> <h2>我是首页-{{msg}}</h2> </div> </template> <script> import Header from "./Header.vue"; import Axios from "axios"; export default { data() { return { msg: "我是home组件", title: '父组件传值给子组件1' }; }, methods: { run(message){ alert("我是父组件的run方法"+message); } }, mounted() {}, components: { "v-header": Header } }; </script> <style scoped> </style> /*子组件*/ <template> <div id="div1"> <h3>我是头部组件----{{title}}---------{{msg}}</h3> <button @click="run('----我是子组件传过来的值')">点击出发父组件的方法</button> <br> <button @click="getPerson()">点击触发父组件的数据和方法</button> </div> </template> <script> export default { data() { return { msg: "我是header组件" }; }, methods: { getPerson(){ // alert(this.title); // alert(this.home.title); this.home.run() } }, props: ["title", "run","home"] }; </script>
-
也可以使用props 进行验证父组件传来的值得格式是否正确
<template> <div id="div1"> <h3>我是头部组件----{{title}}---------{{msg}}</h3> <button @click="run('----我是子组件传过来的值')">点击出发父组件的方法</button> <br /> <button @click="getPerson()">点击触发父组件的数据和方法</button> </div> </template> <script> export default { data() { return { msg: "我是header组件" }; }, methods: { getPerson() { alert(this.title); alert(this.home.title); this.home.run(); } }, //验证父组件传来的类型是否一致 props: { title: String, run: Function, home: Object } }; </script>
父组件主动获取子组件的数据和方法
-
调用子组件的时候定义一个 ref
<v-header ref="header"></v-header>
-
在父组件里面通过
this.$refs.header.属性 this.$refs.header.方法
//父组件 <template> <div class="div"> <v-header :title="title" :home="this" ref="header"></v-header> //定义一个ref <br /> <hr /> <h2>我是首页-{{msg}}</h2> <br /> <button @click="getSon()">点击调用子组件的值</button> </div> </template> <script> import Header from "./Header.vue"; import Axios from "axios"; export default { data() { return { msg: "我是home组件", title: '父组件传值给子组件1' }; }, methods: { getSon(){ // alert(this.$refs.header.msg); //获取数据 this.$refs.header.run(); //获取方法 } }, mounted() {}, components: { "v-header": Header } }; </script> <style scoped> </style> //子组件 <template> <div id="div1"> <h3>我是头部组件----{{title}}---------{{msg}}</h3> <button @click="run('我是子组件传过来的值')">点击组件的方法</button> <br /> <button @click="getPerson()">点击触发父组件的数据和方法</button> </div> </template> <script> export default { data() { return { msg: "我是header组件" }; }, methods: { getPerson() { alert(this.title); alert(this.home.title); }, run(message){ alert("子组件:"+message); } }, props: { title: String, home: Object } }; </script>
子组件主动获取父组件的数据和方法
-
this.$parent.数据
-
this.$parent.方法
//父组件 <template> <div class="div"> <v-header ref="header"></v-header> //定义一个ref <br /> <hr /> <h2>我是首页-{{msg}}</h2> <br /> <button @click="getSon()">点击调用子组件的值</button> </div> </template> <script> import Header from "./Header.vue"; import Axios from "axios"; export default { data() { return { msg: "我是home组件", title: "父组件传值给子组件1" }; }, methods: { getSon() { // alert(this.$refs.header.msg); this.$refs.header.run(); }, personFf(){ alert("我是父组件中的方法!"); } }, mounted() {}, components: { "v-header": Header } }; </script> <style scoped> </style> //子组件 <template> <div id="div1"> <h3>我是头部组件---{{msg}}</h3> <button @click="run('我是子组件传过来的值')">点击组件的方法</button> <br /> <button @click="getPerson()">点击触发父组件的数据和方法</button> </div> </template> <script> export default { data() { return { msg: "我是header组件" }; }, methods: { getPerson() { // alert(this.$parent.title); //获取数据 this.$parent.personFf(); //获取方法 }, run(message){ alert("子组件:"+message); } }, }; </script>
vue中非父子组件传值(兄弟组件):
-
新建一个.js 引入Vue 然后实例化 Vue 最后暴露这个实例
-
在要广播的地方引入刚才定义的实例
-
通过VueEmit.$emit( ‘名称’ , 数据) 广播数据
-
在接收数据的地方通过$on接收广播的数据
VueEmit.$on('名称'),Function(){ }
/*创建一个js文件 用于以下步骤:*/ //引入Vue实例 import Vue from 'vue'; //实例化Vue var VueEvent = new Vue(); //暴露这个实例 export default VueEvent;
<template> <div class="div"> <h2>我是首页-{{msg}}</h2> <button @click="getNews()">点击给news兄弟广播数据</button> <br /> </div> </template> <script> import VueEvent from "../model/VueEvent.js"; //引入定义的实例 import Axios from "axios"; export default { data() { return { msg: "我是home组件的信息" }; }, methods: { getNews() { VueEvent.$emit("to-news", this.msg); //广播数据 } }, mounted() { //监听news 广播的数据 VueEvent.$on("to-home", function(data) { console.log(data); }); } }; </script> <style scoped> </style> /*News组件*/ <template> <div id="div1"> <h3>我是新闻组件---{{msg}}</h3> <button @click="getHome()">点击给Home组件广播数据</button> </div> </template> <script> import VueEvent from "../model/VueEvent.js"; //引入定义的实例 export default { data() { return { msg: "我是header组件" }; }, methods: { getHome() { VueEvent.$emit("to-home", this.msg); //广播数据 } }, mounted() { VueEvent.$on("to-news", function(data) { //监听数据 console.log(data); }); } }; </script>
vue路由:
-
安装: npm install vue-router --save
-
在引用(main.js):
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter)
-
配置路由:
-
创建组件 引入组件
-
定义路由
const routes = [ { path: '/foo', component: Foo }, { path: '/bar', component: Bar }, { path: '*', redirect: '/home'} //默认跳转路由 ]
-
实例化VueRouter
const router = new VueRouter({ routes // short for `routes: routes` })
-
创建并挂载根实例
const app = new Vue({ router }).$mount('#app')
-
在根组件的模板中将 放在 App.vue 中
-
//Home.vue
<template>
<div class="div">
<h2>我是首页-{{msg}}</h2>
<br />
</div>
</template>
<script>
import Axios from "axios";
export default {
data() {
return {
msg: "我是home组件的信息"
};
}
};
</script>
<style scoped>
</style>
//News.vue
<template>
<div id="div1">
<h3>我是新闻组件---{{msg}}</h3>
</div>
</template>
<script>
export default {
data() {
return {
msg: "我是header组件"
};
},
};
</script>
//App.vue
<template>
<div id="app">
<router-link to="/home">首页</router-link>
<router-link to="/news">新闻</router-link>
<hr />
//使用
<router-view></router-view>
</div>
</template>
<script>
import Home from "./components/Home.vue";
import News from "./components/News.vue";
export default {
data() {
return {
msg: "你好vue"
};
},
};
</script>
<style scoped>
</style>
//main.js
import Vue from 'vue'
import App from './App.vue'
//引用
import VueRouter from 'vue-router'
Vue.use(VueRouter)
//创建组件
import Home from '@/components/Home.vue'
import News from '@/components/News.vue'
//配置路由
const routes = [
{ path: '/home', component: Home },
{ path: '/news', component: News },
{ path: '*', redirect: '/home' } //默认跳转到home组件
]
//实例化VueRoutes
const router = new VueRouter({
routes
})
//挂载路由
new Vue({
el: '#app',
router,
render: h => h(App)
})
路由的写法2:
//App.vue
<template>
<div id="app">
<router-link to="/home">首页</router-link>
<router-link to="/news">新闻</router-link>
<hr />
<router-view></router-view>
</div>
</template>
<script>
export default {
data() {
return {
msg: "你好vue"
};
},
};
</script>
<style scoped>
</style>
// router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import News from '@/components/News'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/home',
name: 'Hmoe',
component: Home
},
{
path: '/news',
name: 'News',
component: News
},
{ //默认跳转路由
path: '*',
redirect: '/home'
}
]
})
//main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
vue动态路由:
-
配置动态路由
{ path: '/content/:pid', /*动态配置路由*/ name: 'Content', component: Content },
-
页面传值
<ul> <li v-for="(item,key) in list" :key="item.key"> <router-link :to="'/content/'+key">{{key}}--{{item}}</router-link> </li> </ul>
-
在对应的页面获取传来的值
mounted() { console.log(this.$route.params); },
动态路由之 get传值:
//Home.vue
<ul>
<li v-for="(item,key) in list" :key="item.key">
<router-link :to="'/pcontent?aid='+key">{{key}}--{{item}}</router-link> //get传值
</li>
</ul>
//Pcontent.vue
mounted() {
console.log(this.$route.query);
},
//index.js
{
path: '/pcontent',
name: 'Pcontent',
component: Pcontent
},
vue程序导航路由(编程式导航):
除了<router-link>
用于创建声明性导航的锚标记之外,我们还可以使用路由器的实例方法以编程方式进行此操作。
1:跳转方式
-
第一种跳转方式(字符串):
this.$router.push("news");
-
第二种跳转方式(对象):
this.$router.push({ path: "/content?aid=499" });
-
第三种跳转方式(命名的路由,params 可以传值):
this.$router.push({ name: "Content", params: { aid: "498" } }); //indes.js 写法 { path: '/content?aid=:aid', /*动态配置路由*/ name: 'Content', component: Content }, //Content.vue 获取值得方法 var aid = this.$route.params.aid;
-
第四种跳转方式(带查询参数 http://localhost:8080/#/content?aid=459 )
this.$router.push({ path: "content", query: { aid: "459" } }); //index.js 写法 { path: '/content', name: 'Content', component: Content }, //Content.vue 获取值得方法 var aid = this.$route.query.aid;
2:History模式
哈希模式 的默认模式vue-router
是-使用URL 哈希模拟 完整的URL,以便在URL更改时不会重新加载页面。
要摆脱哈希值,我们可以使用路由器的History模式,该模式利用history.pushState
API实现URL导航而无需重新加载页面:
export default = new Router({
mode: 'history',
routes: [
]
})
箭头函数 和 function 的区别:
- 在function中,this指向的是调用该函数的对象
- 在箭头函数中,this永远指向定义函数的环境
- 箭头函数不可以当构造函数,由于箭头函数没有自己的this,所以当然也就不能用call()、apply()、bind()这些方法去改变this的指向
- function存在变量提升,可以定义在调用语句后,箭头函数以字面量形式赋值,是不存在变量提升的
**箭头函数: **ES6新语法;箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或 new.target。这些函数表达式更适用于那些本来需要匿名函数的地方,并且它们不能用作构造函数;
在联系vue的时候用到axios, 但是发现axios 请求之后的回调函数里this并不指向当前vue实例 ;
// 如下代码
loginSubmit() {
//此时回调函数 内部的this并非指向当前的vue实例
UserLoginAction(this.loginMessage).then(function(response) {
if (response.data == true) {
this.$Message.success("登录成功!");
this.$router.push({ path: "/home" });
} else {
this.$Message.error("登录失败!");
}
});
}
//更改后的代码
loginSubmit() {
//在使用function 的时候 需要用外部函数定义的变量存储的this,也就是当前vue的实例, 不然回调函数的内部的this并非指向当前的vue实例
var _this = this;
UserLoginAction(this.loginMessage).then(function(response) {
if (response.data == true) {
_this.$Message.success("登录成功!");
_this.$router.push({ path: "/home" });
} else {
_this.$Message.error("登录失败!");
}
});
}
//建议使用ES6 新语法
loginSubmit() {
UserLoginAction(this.loginMessage).then(response => {
if (response.data == true) {
this.$Message.success("登录成功!");
this.$router.push({ path: "/home" });
} else {
this.$Message.error("登录失败!");
}
});
}
//箭头函数相当于匿名函数,并且简化了函数定义。看上去是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。此时this在箭头函数中已经按照词法作用域绑定了。很明显,使用箭头函数之后,箭头函数指向的函数内部的this已经绑定了外部的vue实例了.
路由的嵌套
-
配置路由
-
父路由里面配置子路由显示的地方
//router/index.js { path: '/user', name: "User", component: User, children:[ { path: 'useradd', name: "Useradd", component:UserAdd }, { path: 'userlist', name: "UserList", component:UserList } ] },
-
在父组件中加
代码:
user.vue
<template>
<div id="home">
<div class="user">
<div class="left">
<ul>
<li id="lis">
<router-link to="/user/useradd"> 增加用户</router-link>
</li>
<li id="lis">
<router-link to="/user/userlist">用户列表</router-link>
</li>
</ul>
</div>
<div class="right">
<router-view/>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
msg: "我是一个user组件"
};
}
};
</script>
<style scoped>
.user {
display: flex;
}
.left {
width: 200px;
min-height: 400px;
border-right: 1px solid #eee;
}
#lis{
line-height: 4;
}
</style>
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Login from '@/components/Login'
import CeShi from '@/components/CeShi'
import User from '@/components/User'
import UserList from '@/components/User/UserList'
import UserAdd from '@/components/User/UserAdd'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/helloworld',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/login',
name: 'Login',
component: Login
},
{
path: '/ceshi',
name: "CeShi",
component: CeShi
},
{
path: '/user',
name: "User",
component: User,
children:[
{
path: 'useradd',
name: "Useradd",
component:UserAdd
},
{
path: 'userlist',
name: "UserList",
component:UserList
}
]
},
{
path: '*',
redirect: '/login'
},
]
})
App.vue
User/userAdd.vue
User/userList.vue
<template>
<div id="app">
<router-link to="/ceshi"> 测试 </router-link>
<router-link to="/helloworld"> 列表 </router-link>
<router-link to="/user"> 用户 </router-link>
<hr>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 0px;
}
</style>
<template>
<div id="useradd">
添加用户
</div>
</template>
<template>
<div id="userlist">
用户列表
</div>
</template>
Element-UI的使用
官网地址: https://element.eleme.cn/#/zh-CN
npm 安装 : npm i element-ui --save
引入element-ui的css和插件
//mian.js下
import ElemeentUI from 'element-ui' //导入element-UI组件库
import 'element-ui/lib/theme-chalk/index.css' //导入element-UI样式
Vue.use(ElemeentUI)
配置file_loader(可选 不报错就不用配置)
//webpack.config.js中配置(因为无法识别element-UI的字体类型组件,但是现在不需要)
{
test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/,
loader: 'file-loader'
},
//并且 在package.json 中还需要引入模块
"devDependencies": {
...
"file-loader": "^1.1.4", //npm install file-loader --save
...
}
vuex
**定义:**Vuex是一个专为Vue.js 应用程序开发的状态管理模式. 它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. Vuex也集成到Vue的官方调试工具 devtools extension ,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能.
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式
1. vuex 解决了组件之间同一状态的共享问题 (解决了不同组件之间的数据共享)
2.组件里面数据的持久化
3.小项目不建议使用
4. 不同组件的数据共享 以及数据持久化
vuex的使用:
-
src目录下面新建一个vuex的文件夹
-
vuex文件夹里面新建一个store.js
-
安装vuex
- npm install vuex --save
-
在刚才创建的store.js 中引入vue 并且 use vuex
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex); /**1.state 在vuex中用来存储市局 (定义数据)*/ var state = { count: 1 } /**2.mutations里面放的是方法,方法主要用于改变state里面的数据 (定义方法)*/ var mutations = { inCount() { ++state.count; }, outCount() { --state.count; } } //vuex 实例化 Vuex.store (暴露) const store = new Vuex.Store({ state, mutations }) export default store
组件中使用 Vuex
-
引入 store
import store from "../vuex/store.js";
-
注册
export default { data() { return {}; }, store, methods: { incCount() { //改变vuex 中store.js中的count this.$store.commit("inCount"); /**触发state里面的方法修改数据 */ } } };
-
获取state里面的数据
{{this.$store.state.count}}
-
触发 mutations 改变 state里面的数据
this.$store.commit("inCount"); /**触发state里面的方法修改数据 */
代码:
//HomeVuex.vue <template> <div id="home"> 首页组件 <br /> <hr /> {{this.$store.state.count}} <hr /> <button @click="incCount()">点击增加+</button> </div> </template> <script> //1.引入 store import store from "../vuex/store.js"; //2.注册 export default { data() { return {}; }, store, methods: { incCount() { //改变vuex 中store.js中的count this.$store.commit("inCount"); /**触发state里面的方法修改数据 */ } } }; </script> //NewsVuex.vue <template> <div id="new"> 新闻组件 <hr /> {{this.$store.state.count}} <hr /> <button @click="incCount()">点击减少-</button> </div> </template> <script> //1.引入 store import store from "../vuex/store.js"; //2.注册 export default { data() { return {}; }, store, methods: { incCount() { //改变vuex 中store.js中的count this.$store.commit("outCount"); /**触发state里面的方法修改数据 */ } } }; </script>
-