模板语法
{{10+20}}
{{title + 'title'}} //状态和字符串
{{true?'ActiveClass:''}}
{{title.substring(0,1)}}
指令语法
<div v-html="状态"></div>
<div v-bind:class="状态(三目运算符)"></div>
<div :class="状态(三目运算符)"></div>
<div :class="数组/对象写法"></div>
数组写法
new vue({
data:{
xx:["a"]
}
})
对象写法
new vue({
data:{
xx:{
"a":true
}
}
})
<div v-if="状态"></div> //直接删除节点
<div v-show="状态"></div> //display:block/none
应用场景:当数据还没有返回回来的时候不渲染该节点
<div v-if="datalist.length"></div>
<button v-on:click="函数方法"></button>
<button @click="函数方法"></button>
<li v-for="(item,index in datalist)" :key="index"></li>
<div v-if="状态"></div>
<div v-else-if="状态"></div>
<div v-else="状态"></div>
push方法返回的是数组的长度
空字符串为假
<div :style="数组写法或对象写法"></div>
数组写法:
new vue({
data:{
xx:[{background:'red'}]
}
})
对象写法:
new vue({
data:{
xx:{
background:'red'
}
}
})
template标签不会被渲染出来
for-of和for-in在vue中是关键字作用,都能遍历数组和对象
在原生的js中for-of是不能遍历对象的,原生js中for-in遍历的是对象的属性
基本结构
var vm=new vue({
el:#box,
data:{
//data是放数据的地方 将来可以通过改变数据 驱动页面更新
},
methods:{
}
})
diff算法
key值对比
组件对比
层级对比
像
<div v-if="状态"></div>
<div v-else></div>
无法加上过渡效果是因为根据diff算法,他只会发生替换,不会发生dom元素的增删
应用场景:
one:改变key值引发重新触发mounted生命周期
two:用索引值直接修改数组的坑(vm[xx]=newValue无法getter和setter拦截到) vue.set(obj,"属性","属性值")
v-model
特别注意与input上的绑定
<input type="checkbox" v-model="数组状态" :value=""/>
<input type="radio" v-model="字符串状态" :value="" name=""/>
<input type="text" v-model="数组状态"/>
v-model.lazy
v-model.trim
v-model.number
v-for相关问题
<li v-for="n,index in 10">{{n}}--{{index}}</li>
输出为
1 0
2 1
... ...
10 9
过滤应用
复制一份完整的数组,因为filter对原数组不会产生影响,利用这一点让想要动态显示的数组数据修改即可
this.datalist = this.list.filter((item)=>item.indexOf(this.mytext)>-1);
应用场景:结合计算属性 基于依赖重新计算
vue中监听一个对象的属性是否被修改
Object.defineProperty(obj,propName,des)
直接在一个新对象上定义一个新属性,或者修改一个已经存在的属性,并且返回一个对象
Object.keys(对象)
返回的是一个真正的对象属性数组,自身可枚举属性组成的数组
数组方法总结
["a","b","c"].splice(2,2,"e","f")
输出为:["a","b","e","f"] 直接修改原数组,会得到被替换下来的数组
concat 合并现有数组创建一个新数组,返回一个新数组,不会改变现有数组
slice(index,length) 创建新数组,不会改变新数组
ARRAY.ForEach((item,index,arr)=>{return XX}) //不会遍历空数组
ARRAY.map((item,index,arr)=>{return XX})
every
indexOf
'kerwin'.indexOf("") // 输出为 0 判断空字符串永远是0
some
find
findIndex
filter return true 全部筛选 return false 空数组
var {foo,bar} ={foo:"ss",bar:"ss"}
a=1 + ' ' + 2
a.split(' ')
a[0] 输出为1
函数调用方式
通过函数调用
应用场景
one:
不加括号可以直接拿到事件对象
<button @click="handleAdd1">add1</button>
new vue({
methods:{
handleAdd1(ev){
console.log(ev.target)
}
}
})
two:
加括号得传$event才行
<button @click="handleAdd1($event)">add1</button>
new vue({
methods:{
handleAdd1(ev){
console.log(ev.target)
}
}
})
点击事件函数应用
@click.stop
@click.prevent
@click.self
@click="isActive & 函数方法 " // 前面是真才会执行后面函数方法
表单控件绑定
vue:<input type="checkbox" v-model="checkedgroup" value="vue"/>
react:<input type="checkbox" v-model="checkedgroup" value="react"/>
jquery:<input type="checkbox" v-model="checkedgroup" value="jquery"/>
checkbox是多选框
radio是单选框 设置name是因为同属于一个组别
vue:<input type="radio" value="vue" name="favorlan" v-model="picked"/>
react:<input type="radio" value="react" name="favorlan" v-model="picked"/>
jquery:<input type="radio" value="jquery" name="favorlan" v-model="picked"/>
计算属性--computed
//计算属性不用加小括号,可以根据依赖关系进行缓存
// 计算属性是靠返回值渲染到页面上的
//计算属性需要有返回值
//watch不需要写return
//要让状态true是布尔值要加冒号:
//计算属性中的一个方法,方法的返回值作为属性值
<div id="box">
单价<input type="text" v-model="myprice" />
数量<input type="text" v-model="mynumber" />
<p>{{computedsum}}</p>
</div>
<script type="text/javascript">
var vm = new Vue({
el:"#box",
data:{
myprice:100,
mynumber:1,
},
computed:{
computedsum(){
var sum = this.myprice*this.mynumber;
if(sum>1000){
return sum;
}
return sum+100;
}
//双向关联 计算属性高级通过getter/setter实现对属性数据的显示和监视
//计算属性存在缓存,多次读取只执行一次getter计算
xxx:{
get(){
//回调函数 你定义的 你没有调用 它执行了
//什么时候调用 用来做什么 当需要读取当前属性值时回调,根据相关的数据计算并返回当前属性的值
//计算并返回当前属性的值
},
//当属性值发生改变的时候的时候回调,更新相关的属性数据
//监视当前属性值的变化
set(value){ //value就是xx的最新属性值
}
}
}
})
watch
监听某个状态的值是否发生改变,多个时需要监听多个
写着属性的做着方法的事
<div id="box">
单价<input type="text" v-model="myprice" />
数量<input type="text" v-model="mynumber" />
<p>{{sum}}</p>
</div>
var vm = new Vue({
el:"#box",
data:{
myprice:100,
mynumber:1,
sum:0
},
watch:{
myprice(){
console.log("price改变",this.myprice)
if(this.mynumber*this.myprice>1000){
this.sum = this.mynumber*this.myprice;
}else{
this.sum = this.mynumber*this.myprice+100;
}
},
mynumber(){
console.log("number改变",this.mynumber)
if(this.mynumber*this.myprice>1000){
this.sum = this.mynumber*this.myprice;
}else{
this.sum = this.mynumber*this.myprice+100;
}
}
}
})
axios和fetch的应用
fetch 应用
fetch post-1
fetch("json/test.json",{
method:"post",
headers:{
"Content‐Type": "application/x‐www‐form‐urlencoded"
},
credentials: 'include', //包含cookie
body:"name=kerwin&age=100"
}).then(res=>res.json()).then(res=>{
console.log(res);
})
fetch post-2
fetch("json/test.json",{
method:"post",
headers:{
"Content‐Type": "application/json"
},
body:JSON.stringify({
name:"kerwin",
age:100
})
}).then(res=>res.json()).then(res=>{
console.log(res);
})
fetch要把返回来的数据json化才能打印出来
axios应用
axios({
url:"https://m.maizuo.com/gateway?cityId=110100&pageNum=1&pageSize=10&type=1&k=1384809",
headers:{
'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.0.4","e":"154277371928424093566579"}',
'X-Host': 'mall.film-ticket.film.list'
}
}).then(res=>{
console.log(res.data);
this.datalist= res.data.data.films
})
axios的数据在返回来的数据的data属性里
vue.mixin
混入对象可以包含任意组件选项
当组件使用混入对象的时侯,所有混入对象的选项将被混入该组件本身的选项
覆盖中vue实例的定义的优先级最高
场景一:
a:{
methods:{}
...
}
new Vue({
el:"#box1",
data:{
name:"vue定义的name",
},
mixins: [a(对象)],
})
场景二:
Vue.mixin({
data(){
return {
age:100
}
}, //涉及组件的中, data必须是一个函数 返回真正的状态
methods:{
hello(){
console.log("11111")
}
},
computed:{
}
})
组件
全局组件与局部组件
组件与组件之间data状态必须隔离所以设计成函数并且需要有return返回值对象
Vue.component("app-child",{
template: `
<div>child</div>`
})
Vue.component("navbar",{
template: `<nav style="background:red">
<button @click="handleClick()">返回-{{text}}</button>
<span>导航栏</span>
<app-child></app-child>
<navbarchild></navbarchild>
</nav>`,
data(){
return {
text:"111111"
}
// 组件与组件 的状态需要相互隔离, 要设计成函数。
},
methods:{
handleClick(){
console.log("click--navbar");
this.text="222222";
}
},
局部组件
components:{
navbarchild:{
template:`<div>navbarchild--{{title}}</div>`,
data(){
return {
title:"111111111"
}
}
}
}
})
组件间通信-父传子
<navbar myword="home" :myshow="false"></navbar>
Vue.component("navbar",{
template: `<nav style="background:red">
<button @click="handleClick()" v-show="myshow">返回-{{text}}</button>
<span>导航栏--{{myword}}---{{myshow}}</span>
</nav>`,
//接受父组件传来的属性
// props:["myword","myshow"],
//属性验证
props:{
myword:String,
myshow:Boolean
},
data(){
return {
text:"111111"
}
// 组件与组件 的状态需要相互隔离, 要设计成函数。
},
methods:{
handleClick(){
console.log("click--navbar");
this.text="222222";
}
}
})
var vm = new Vue({
el:"#box",
data:{
title:"根组件中定义的title"
}
}) //根组件(root )
组件间通信-子传父亲
<div id="box">
<child @myevent="handleMyEvent($event)"></child>
</div>
<script type="text/javascript">
//子组件
Vue.component("child",{
template:`<div>
child-<button @click="handleClick">send</button>
</div>`,
data(){
return {
money:1000000
}
},
methods:{
handleClick(){
console.log("把消息传给父组件")
this.$emit("myevent",this.money);// emit 分发 丢给谁 丢什么
}
}
})
var vm = new Vue({
el:"#box",
data:{
},
methods:{
handleMyEvent(data){
console.log("我收到了钱",data)
}
}
})
</script>
ref的应用
<div id="box">
<button @click="handleClick()">get</button>
<child ref="mychild"></child> //this.$ref 获得的是组件对象
<input type="text" ref="mytext"/> //this.$ref 获得的是dom节点
<button @click="handleAdd">add</button>
</div>
bus中央事件总线
bus中央事件总线
游离于组件化创建一个模块存放new vue实例谁引用谁引入
<div id="box">
<child1></child1> //child1和child2通信 借助独立于五行之外的共用的bus实例
<child2></child2>
</div>
<script type="text/javascript">
// eventEmitter .on .emit
var bus = new Vue()// 空vue实例 中央事件总线
Vue.component("child1",{
template:`<div>
child1---<button @click="handleClick()">通信</button>
</div>`,
methods:{
handleClick(){
// 向自己兄弟child1 发送一句
// setInterval(() => {
// bus.$emit("kerwin","兄弟,这是麻药");
// }, 1000)
bus.$emit("kerwin","我是丑八怪");
}
},
mounted(){
console.log("这个函数会在child1组件创建成功后自动被vue调用")
}
})
Vue.component("child2",{
template:`<div>
child2--一直显示
<ul v-show="isShow">
<li>111111</li>
</ul>
</div>`,
data(){
return {
isShow:true
}
},
mounted(){
console.log("这个函数会在child2组件创建成功后自动被vue调用")
bus.$on("kerwin",(data)=>{
console.log(data);
this.isShow = !this.isShow
})
}
})
new Vue({
el:"#box",
// template:"<div>hello template</div>"
})
动态组件
<div id="box">
<keep-alive>
<component :is="who"></component>
</keep-alive>
<footer>
<ul>
<li><a @click="who='home'">首页</a></li>
<li><a @click="who='list'" >列表页</a></li>
<li><a @click="who='shopcar'">购物车页面</a></li>
</ul>
</footer>
</div>
<script type="text/javascript">
//babel-loader ES6=>ES5
var home= {
template:`<div>
home
<input type="text"/>
</div>`
}
var list= {
template:`<div>
list
</div>`
}
var shopcar= {
template:`<div>
shopcar
</div>`
}
var vm = new Vue({
el:"#box",
data:{
// isHomeShow:true,
// isListShow:false,
// isShopcarShow:false
who:"home"
},
components:{
// home:{
// template:`<div>home组件</div>`
// },
// list:{
// template:`<div>list组件</div>`
// },
// shopcar:{
// template:`<div>shopcar组件</div>`
// }
home, //home:home 简写
list,
shopcar
}
})
slot
<div id="box">
<hello>
<ul slot="a">
<li>111</li>
<li>111</li>
<li>111</li>
<li>111</li>
</ul>
<ul slot="b">
<li>222</li>
<li>222</li>
<li>222</li>
<li>222</li>
</ul>
<ul >
<li>333</li>
<li>333</li>
<li>333</li>
<li>333</li>
</ul>
</hello>
</div>
var hello = {
template:`<div>
<slot name="b"></slot>
hello
<slot name="a"></slot>
<slot></slot>
</div>`
}
new Vue({
el:"#box",
data:{
},
components:{
hello
}
})
transition-过渡效果
transition
transition-group
1.结合类名的过渡效果
<transition name="kerwinfade">
<p v-show="isShow">11111111111111111</p> //一个
</transition>
<transition name="bounce">
<p v-show="isShow">2222222222222</p> //一个
</transition>
<transition enter-active-class="animated bounceInRight" leave-active-class="animated bounceOutRight">
<p v-show="isShow">33333333333333333</p> //一个
</transition>
2.多个元素过渡 元素内的内容只允许单个出现
<transition name="bounce" mode="out-in">
<div v-if="isShow" key="1">111111</div> //同一时间只能一个出现
<div v-else key="2">222222</div>
</transition>
3.多个组件的过渡 只允许同时出现一个组件
<keep-alive>
<transition name="bounce" mode="out-in">
<component :is="who"></component> //同一时间只能一个出现
</transition>
</keep-alive>
4.里面的元素会一直变动用transition-group
<transition-group tag="ul" name="bounce">
<li v-for="(data,index) in datalist" :key="data">
{{data}}--{{index}}<button @click="handleDelClick(index)">del</button>
</li>
</transition-group>
组件生命周期
mounted 只会触发一次,但通过改变key值会让其重新挂载并再次触发mounted :key="data.length"
swipe初始化过早问题解决方案
1.vue.directive
2.this.$nextTick
3.在mounted中利用diff算法 :key="data.length"
4.updated 弊端(频繁更新的话多次触发)
Vue.component("child",{
template:``,
data(){
return {
}
},
methods:{
},
beforeCreate(){
console.log("beforeCreate")
},
created(){
console.log("created")
},
beforeMount(){
console.log("beforeMount")
},
mounted(){
console.log("mounted","访问dom,setInterval,window.onscroll, 监听事件 ajax")
},
beforeUpdate(){
console.log("beforeUpdate")
},
updated(){
console.log("updated","更新之后可以访问dom")
// var otitle = document.getElementById("title");
// console.log(otitle.innerHTML);
},
beforeDestroy(){
console.log("beforeDestroy");
},
destroyed(){
console.log("destroyed--clearInterval ,window.onscroll=null,$off")
}
})
swipe
注意事项:
在mounted中请求的异步数据在对其赋值到相应数组试图直接渲染到页面的时候会发现
Dom还有数据没来,swiper初始化过早,动不起来的问题。
这是因为数据创建完成不等于dom页面渲染完成,vue中数据是异步更新。
<link rel="stylesheet" href="lib/swiper/css/swiper.css">
<script src="lib/swiper/js/swiper.js"></script>
<div class="swiper-container kerwin">
<div class="swiper-wrapper">
<div class="swiper-slide">Slide 11111</div>
<div class="swiper-slide">Slide 22222</div>
<div class="swiper-slide">Slide 333333</div>
</div>
<!-- 如果需要分页器 -->
<div class="swiper-pagination"></div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- 如果需要滚动条 -->
<div class="swiper-scrollbar"></div>
</div>
<script type="text/javascript">
new Swiper ('.kerwin',{
pagination: {
el: '.swiper-pagination',
},
// direction: 'vertical',
loop: true,
autoplay: {
delay: 2500,
disableOnInteraction: false,
},
// 如果需要前进后退按钮
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
})
</script>
<script type="text/javascript">
var vm = new Vue({
el:"#box",
data:{
datalist:[]
},
mounted(){
setTimeout(() => {
this.datalist=["111","222","333"]
//数据更新完了 === dom更新完了吗? no 这个过程是异步
// var oslide= document.querySelector(".swiper-slide");
// console.log(oslide);
}, 2000)
},
//解决方案一:在updated(){}生命周期函数中初始化
updated(){
// var oslide= document.querySelectorAll(".swiper-slide");
// console.log(oslide);
new Swiper ('.kerwin',{
pagination: {
el: '.swiper-pagination',
},
// direction: 'vertical',
loop: true,
autoplay: {
delay: 2500,
disableOnInteraction: false,
},
// 如果需要前进后退按钮
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
})
}
})
</script>
自定义指令
<div v-hello="'red'">11111111</div>
<div v-hello="'yellow'">22222222</div>
<div v-hello="color">333333333333333</div>
生命周期
bind
inserted 一辈子执行一次
updated
componentupdated
unbind
Vue.directive("hello",{
//指令的生命周期-第一次插入节点调用
inserted(el,binding,vnode){
// vnode ,vdom, virtual node, 虚拟节点 虚拟dom
//newvnode.context 可以访问vue实例
//newvnode.context.list
//el 只要节点可访问el就是该节点,当前dom节点
//bind 对象
//指令可以接收参数 v-hello='"red"'
console.log("此时dom节点创建",vnode)
el.style.backgroundColor = binding.value;
},
update(el,binding){
console.log("此时绑定的状态改变时会执行")
el.style.backgroundColor = binding.value;
}
})
context: Vue$3 {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue$3, …}
binding 输出为
{name: "hello", rawName: "v-hello", value: "red", expression: "'red'", modifiers: {…}, …}
这一个函数简写包含了五个生命周期,在这里写的方法所有周期都会自己跑一遍
Vue.directive("hello",function(){})
指令中的inserted周期能够判断数据是否全部被插入到数组中,
根据指令获取插入的深度和数组中的长度比较
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="data,index in list" v-swipe="index">
{{data}}
</div>
</div>
</div>
<script type="text/javascript">
Vue.directive("swipe",{
inserted(el,binding,vnode){
console.log(binding.value);
//方案二:
if(binding.value === vnode.context.list.length-1){
var mySwiper = new Swiper ('.swiper-container', {
// direction: 'vertical', // 垂直切换选项
// 如果需要分页器
pagination: {
el: '.swiper-pagination',
}
})
}
}
})
new Vue({
el:"#box",
data:{
list:[]
},
mounted(){
setTimeout(() => {
this.list = ["111","2222","3333"];
console.log("节点创建完了????","没有,异步渲染")
}, 2000)
},
//方案一:
updated(){
// console.log("节点创建完了????","更新阶段渲染")
// var mySwiper = new Swiper ('.swiper-container', {
// // direction: 'vertical', // 垂直切换选项
// // 如果需要分页器
// pagination: {
// el: '.swiper-pagination',
// }
// })
}
})
</script>
过滤器
<div id="box">
<ul>
<li v-for="data in datalist">
{{data.nm}}
<!-- <img :src="handlePath(data.img)"/> -->
<img :src="data.img | kerwinpath"/>
{{ data.img | kerwinpath }}
</li>
</ul>
</div>
Vue.filter("kerwinpath",function(path){
return path.replace('w.h','128.180')
})
vue-cli脚手架安装
<template></template>
<script>
export default {}
</script>
<style lang="scss" scoped></style>
项目入口页面 main.js
import Vue from 'vue' // ES6 导入方式 // var Vue = require("vue") commonJS
import App from './App.vue'
// import router from './router'
// import store from './store'
Vue.config.productionTip = false
new Vue({
// router,
// store,
render: h => h(App) // render是一个回调 渲染app 组件
}).$mount('#app') // 把渲染完的组件挂载到 app节点 这一个节点在dist目录下的index.html中
每一个vue是单文件组件,组件中只能由一个root节点
vue.config.js 跨域问题 http-proxy-middleware
module.exports = {
devServer: {
proxy: {
//遇到这个路径往target发送请求
'/ajax': {
target: 'http://m.maoyan.com',
// ws: true,
changeOrigin: true
},
'/foo': {
target: '<other_url>'
}
}
},
lintOnSave: false
}
better-scroll(库)的应用
https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/
cnpm install --save better-scroll
import BetterScroll from "better-scroll"
<script>
export default{
this.nextTick({})
}
</script>
mounted(){
var myscroll = new BScroll('.cinema',{
//配置下拉刷新
pullDownRefresh: {
threshold: 50,
stop: 20
},
scrollbar: {
fade: true,
interactive: false // 1.8.0 新增
},
////配置上拉加载
pullUpLoad: {
threshold: 50
}
})
myscroll.on("pullingDown",()=>{
console.log("下拉刷新了...")
setTimeout(() => {
this.datalist.unshift("新的数据-下拉刷新")
myscroll.finishPullDown();// 结束了
}, 2000)
})
myscroll.on("pullingUp",()=>{
console.log("到底了...")
setTimeout(() => {
this.datalist.push("新的数据-上拉加载")
myscroll.finishPullUp();// 结束了
}, 2000)
})
}
<style lang="scss" scoped>
.cinema{
overflow:hidden; //很精髓
height: 300px;
position: relative;
li{
height: 100px;
}
}
</style>
吸顶的几个小技巧运用
mounted(){
window.onscroll=function(){}
}
destroy(){
window.onscroll=null
}
this.$ref.xx.XX.offsetHeight
根据传过来的商品数据id加载相应不同的商品数据详情页
同一页面用了两次swiper相互影响的问题
因为是swiper根据类名初始化相关节点,所以多个时需要传递自定义类名
不经常传送删除可以用index作为key值
函数的返回值是undefined
'.'+this.swiper
:class="'swiper-container ' + swipername" 一个是字符串一个是状态
<div v-if="data"></div> 在异步请求的数据中只有数据成功请求回来并赋值才会渲染出来
路由
mode:history
vue.use(Router)
export default new router({
routes:[
path:'/flim',
component:Film
]
})
同时要在页面中留好一个容器 <router-view></router-view>
routes: [
//一级路由
{
path: '/film',
// name: 'home',
component: Film,
// 二级路由 嵌套路由
children: [
{
path:"nowplaying",
component:Nowplaying
},
{
path:"comingsoon",
component:Comingsoon
},
{
path:"",
redirect:'/film/nowplaying' //孩子的重定向
}
]
},
// 一级路由, 路径 存在父子关系, 组件间没有父子关系
// {
// path: '/film/comingsoon',
// component:Comingsoon
// },
{
path: '/cinema',
// name: 'home',
component: Cinema
},
{
path: '/center',
// name: 'home',
component: Center,
alias: '/kerwin'//别的名字
},
{
path: '/detail/:kerwinid', // 动态路由
name: 'detail', //命令路由
component: Detail
},
// {
// path: '/detail', //
// name: 'detail', //命令路由
// component: Detail
// },
{
path: '/',
redirect: '/film'
}
]
路由守卫
当路由守卫执行前,组件还没实例化,不能获取组件实例
<script>
export default{
beforeRouteEnter(to,form,next){}
}
</script>
router.beforeEach(to,from,next){}
beforeRouteEnter (to, from, next) {
//路由生命周期- 路由钩子函数
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
console.log("麻药来了");
if(true){
next();
}else{
next("/login");
}
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
if(this.mytext!=""){
alert("还未保存");
}else{
next();
}
}
声明式导航 vs 编程式导航
声明式导航
<a href="#/film"></a>
<router-link to="/flim" activeClass="类名" tag="标签(例如li)"></router-link>
编程式导航
methods:{
xx(){
this.$router.push("/detail")
}
}
动态路由
router.js 动态路由配置
{
path:"/detail/:id"
name:'detail'
component:detail
}
methods:{
xx(){
//这里是$route 当前页面显示的路由对象
this.$route.id.XX
this.$router.push({name:'detail'})
this.$router.push({
name:'detail',
params:{id}
})
}
}
第三方插件库
ELEMENEUI
cnpm install --save 'element-ui'
import ElementUi from 'element-ui'
import 'xx.css'
Vue.use(ElementUi)
MintUi同理
英文字母的筛选
A.charCodeAt() 65
String.fromCharCode(65) "A"
String.fromCharCode(97) "Z"
[].substring(0,1)
[].push({
index:arr[i],
city:arr
})
var x=[];
for(var i=65;i<97;i++){
arr.push(String.fromCharCode(i))
}
vuex
getters:可以从store 中的 state 中派生出一些状态,getters的返回值会根据 它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
在组件中dispatch发送到Action中,在Action中做异步(同步)处理,等待数据返回后commit到mutations中,在mutate改变state。状态改变后会影响依赖状态的组件,重新渲染组件
actions
dispatch commit
vue component commit mutations
render mutate
state
同步请求直接commit到mutations即可
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
getters:{
}
})
export default new Vuex.Store({
state: {
},
mutations: {
//唯一能修改状态的位置,
MaizuoTabbarMutation(state,payload){
console.log("MaizuoTabbarMutation",payload)
state.isTabbarShow = payload;
},
GetComingSoonMutation(state,payload){
state.comingsoonlist = payload;
}
},
actions: {
//专门做异步处理
GetComingSoonAction(store){
axios(xx).then(res=>{
console.log(res.data)
store.commit("GetComingSoonMutation",res.data.data.films)
})
}
}
})
mounted(){
//隐藏tabbar
// this.$store.state.isTabbarShow =false; //万一出错 ,无法调试
this.$store.commit("MaizuoTabbarMutation",false)
// $route 是当前路由对象
console.log(this.$route.params.kerwinid,"利用这个id 获取新的数据");
// console.log(this.$route.query.id,"利用这个id 获取新的数据");
axios(xx).then(res=>{
console.log(res.data);
this.datainfo = res.data.data.film
})
// 获取tabbar 的节点, display:none;
},
destroyed(){
//显示tabbar
// this.$store.state.isTabbarShow = true;
this.$store.commit("MaizuoTabbarMutation",true)
}
写法二:计算属性写法
computed(){
XX(){
return this.$store.state.isTabShow
}
}
写法三:import {mapState} from 'vuex'
computed:{
...mapState(['xx']),
xx
}
写法四:
const A ="a"
const B ="b"
export{A,B}
import {A,B} from 'xx'
[A](){}
nuxt.js
cnpm install -g create-nuxt-app
create-nuxt-app test1906
npx create-nuxt-app
移动端适配问题
1px问题
300ms延迟问题
hammer.js
https://github.com/hammerjs/hammer.js
zepto