vue使用

自学vue

1.MVVM模式

MVVM模式包含三个部分
	M   模型
	V   视图
	VM	视图模型

实例化vue类的时候,要传递参数对象
	通过el属性与页面中的模板绑定上
	通过data属性与模型数据绑定上

//小例子
<body>
<div id="app">
    <span>{{ msg }}</span>
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el:'#app',
        data:{
            msg:'我和我的女友'
        }
    })
    //视图改变 数据更新  改变之后span标签中会是耿泽世
    vm.msg ='耿泽世'

</script>
</body>


2.数据绑定的实现

<body>
<div id="app">
    <span>{{ msg_list[0] }}---{{ msg_list[1] }}</span>
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el:'#app',
        data:{
            msg_list:['我和我的女友','我和女友相处的日子']
        }
    })
    //修改完值以后打印的还是   我和我的女友---我和女友相处的日子
    vm.msg_list[0]='耿泽世'


</script>
</body>

----------------------------------
//解决上面的问题 (新数组替换)
<body>
<div id="app">
    <span>{{ msg_list[0] }}---{{ msg_list[1] }}</span>
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el:'#app',
        data:{
            msg_list:['我和我的女友','我和女友相处的日子']
        }
    })
    //解决办法  数组替换
    vm.msg_list=['耿泽世','我和女友相处的日子']


</script>
</body>


//前段对象
<body>
<div id="app">
    //执行结果  小敏  和  18  有数据丢失 
    <span>{{ names.name }}---{{ names.age }}---{{ names.sex }}</span>  
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el:'#app',
        data:{
            names:{
                name:'小敏',
                age:18
            }
        }
    })
    vm.names.total = '女'


</script>
</body>

//解决办法
<body>
<div id="app">
    <span>{{ names.name }}---{{ names.age }}---{{ names.sex }}</span>
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el:'#app',
        data:{
            names:{
                name:'小敏',
                age:18
            }
        }
    })
    vm.names={
        name: '小敏',
        age:18,
        sex:'女'
    }
</script>
</body>

$set方法为了解决上面数据丢失的问题

第一个参数表示数据对象
	可以是vue实例化对象  也可以是其他对象
第二个参数表示属性名称
第三个参数表示属性值

<body>
<div id="app">
    <span>{{ names.name }}---{{ names.age }}---{{ names.sex }}</span><br>
    <span>{{ color_list[0] }}----{{ color_list[1] }}</span>
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el:'#app',
        data:{
            color_list:['red','blue'],
            names:{
                name:'小敏',
                age:18
            }
        }
    })
    vm.$set(vm.color_list,0,'greeb')
    vm.$set(vm.names,'age',10)
</script>
</body>

计算属性数据定义在comptued属性中

定义的是方法,获取的时候,会将执行的结果返回(是计算的)
computed与data的用法是一样的 ,添加给vue实例化对象自身,并设置了特性,定义的时候都是一个对象
	key  表示数据名称   value  是一个函数

参数和this都指向vue实例化对象,因此通过参数或者this可以获取vue中的其他数据
	必须有返回值  就是获取的数据 

<body>
<div id="app">
    <span>{{ names.name }}---{{ names.age }}---{{ names.sex }}</span><br>
    <span>{{ color_list[0] }}----{{ color_list[1] }}</span>
    <span>{{ deaMax }}</span>
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el:'#app',
        data:{
            color_list:['red','blue'],
            names:{
                name:'小敏',
                age:18
            },
            msg:'hello'
        },
        computed:{
            deaMax(v,...args){
                return v.msg.toUpperCase();
            }
        }
    })

</script>
</body>

属性绑定

属性绑定的语法:v-bind:key="value"
        
语法糖:语法糖就是对某个操作的简化,来提高我们的开发效率
    v-bind指令的语法糖是冒号语法糖
    v-bind:key="value" 可以写成:key="value"
            
#v-bind的使用
<body>
<div id="app">
    <span v-bind:title="tit">{{ msg }}</span>
    <span v-bind:title="msg.toUpperCase()">{{ msg }}</span>
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el:'#app',
        data:{
            color_list:['red','blue'],
            names:{
                name:'小敏',
                age:18
            },
            msg:'hello',
            tit:'这是一个属性标签'
        },
    })
</script>
</body>


#v-html  可以识别html标签的
<body>
<div id="app">
    <span v-html="msg+'hello'"></span>
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el:'#app',
        data:{
            msg:'<a href="https://baidu.com">点击我跳转百度</a>'
        },
    })
</script>
</body>

#v-text   不会识别html标签
#只能渲染元素的全部内容  避免插值符号闪烁问题
<body>
<div id="app">
    <span v-text="msg"></span>
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el:'#app',
        data:{
            msg:'<a href="https://baidu.com">点击我跳转百度</a>'
        },
    })
</script>
</body>

#v-once  该指令用来让内容单次渲染  该指令不需要设置属性值

插值过滤器

"""
插值过滤器技术有三个优势
	避免模板臃肿的问题
	可以复用
	可以跨组件使用
"""

#使用过滤器
"""
语法{{data | 过滤器(参数1,参数2)|过滤器2.....}}
"""

#自定义过滤器
"""
vue自定义过滤器的两种方式

第一种:全局定义,全局定义的过滤器可以在任何实例化对象(组件)中使用

	通过:Vue.filter(name,fn)
	
第二种:局部定义:局部定义的过滤器只能在当前实例化对象(组件)中使用
	
	在vue实例化对象(组件)中,通过filters属性定义
	filters:{name:fn}
		name表示过滤器名称:建议驼峰式命名
		fn(data,...args)表示函数过滤器函数:data表示处理的数据,args表示使用过滤器时传递的参数
		必须有返回值  就是处理的结果

全局定义过滤器的时候,注意点:
	filter方法不能解构   
	要在vue实例化对象之前使用
"""

#全局定义过滤器
<body>
<div id="app">
    <span >{{ msg|upper(100,200) }}</span>
</div>
<script src="vue.js"></script>
<script>
    Vue.filter('upper',(str,...args)=>{
        console.log(str)
        console.log(args)
        return str.toUpperCase()
    })
    let vm = new Vue({
        el:'#app',
        data:{
            msg:'hello world'
        },
    })
</script>
</body>

#局部定义过滤器
<body>
<div id="app">
    
    <span>{{ addr|upper1(11,23) }}</span>
</div>
<script src="vue.js"></script>
<script>
    
    let vm = new Vue({
        el:'#app',
        data:{
            msg:'hello world',
            addr:"i'm student "
        },
        filters:{
            upper1(str,...args){
                alert(str)
                alert(args)
                return str.toUpperCase()
            }
        }
    })
</script>
</body>

数据双向绑定

#v-model指令
数据双向绑定有两个方向:
    数据由模型进入视图:通过数据绑定实现的  为value绑定模型数据
   	数据由视图进入模型:通过事件监听实现的  监听input事件,更新数据
        
#v-clock
用来解决插值符号闪烁的问题
只需要两步:
    第一步:为容器元素设置v-cloak
        
    第二步:在style标签内,(style标签要定义在容器元素的前面),通过v-cloak属性选择器  设置 display:none样式 将元素隐藏
       
注意:
    style标签要定义在容器元素的前面
    v-cloak只能给容器元素内部的元素使用(包括容器元素)

单选框

#单选框:对单选框实现数据双向绑定,也是用v-model指令
"""
一组单选框绑定同一份数据
选框的值通过value属性定义
此时checked属性失效了
一组单选框的默认值就是绑定数据的值
"""

#单选框的数据绑定
<body>
<div id="app" v-cloak>
   <p>
       <span>喜欢的运动</span>
       <label>篮球<input type="radio" value="篮球" v-model="sport"></label>
       <label>足球<input type="radio" value="足球" v-model="sport"></label>
       <label>羽毛球<input type="radio" value="羽毛球" v-model="sport"></label>
   </p>
    <h1>{{ sport }}</h1>
</div>
<script src="vue.js"></script>
<script>

    let vm = new Vue({
        el:'#app',
        data:{
            //sport:''
            sport:'篮球'
        },
    })
</script>
</body>

#多选框
type属性为checkbox   也是用v-model
特点:
    一组多选框绑定不同的数据,为了访问方面,将其放在一个命名空间下
    选框的值默认是布尔值 通过v-bind:true-value以及v-bind:false-value可以自定义其值
    checked属性失效了
    玉一组多选框的默认值就是绑定数据的值,如果自定义:true-value以及 :false-value就是自定义数据值
            
<body>
<div id="app" v-cloak>
   <p>
       <span>喜欢的兴趣爱好</span>
       <label>篮球<input type="checkbox" v-bind:true-value="'选中了篮球'" :false-value="msg" v-model="inst.baskball"></label>
       <label>足球<input type="checkbox"  v-model="inst.football"></label>
       <label>羽毛球<input type="checkbox"  v-model="inst.yunmao"></label>
   </p>
    <h1>你选择的兴趣爱好:{{ inst }}</h1>
</div>
<script src="vue.js"></script>
<script>

    let vm = new Vue({
        el:'#app',
        data:{
            inst:{
                //设置默认属性值
                yunmao:'选中了羽毛球'
            },
            msg:'没有选中篮球'
        },
    })
</script>
</body>

数据监听器

key   被监听的数据名称
value 当数据改变的时候  执行的回调函数
	第一个参数表示新的值   第二个参数表示旧的值
    this指向vue实例
    
#例子
<body>
<div id="app" v-cloak>
    <input type="text" v-model="num1">
    <h1>{{ num1 }}</h1>
    <h2>{{ total }}</h2>
</div>
<script src="vue.js"></script>
<script>
    let timebar;
    let vm = new Vue({
        el:'#app',
        data(){
            return {
                num1:100,
                total:100
            }
        },
        watch:{
            //监听num1 的变化  num1改变会执行
            num1(val,...args){
                clearInterval(timebar)
                timebar = setInterval(()=>{
                    this.total += this.num1>this.total?1:-1;
                    if (this.total == this.num1) {
                        clearInterval(timebar)
                    }
                },10)
            }

        }
    })
   
</script>
</body>

DOM事件

#事件绑定:vue为了绑定dom事件 提供了v-on指令
语法:v-on:click=-"fn()"
v-on指令的语法糖是@
	也可以写成 @click="fu()"
fn代表事件回调函数,定义在vue实例的methods属性中
	methods中定义的方法跟data中的定义的数据一样,添加实例化对象自身了
    methods中定义的方法不仅仅可以在事件中使用,所有可以获取实例化对象的地方,都可以通过实例化对象来使用该方法

事件修饰符之事件

#通用修饰符

语法:
	v-on:click.修饰符 = "fn"

stop:实现阻止冒泡的修饰符  prevent:实现阻止默认行为的修饰符
once:表示单次触发的修饰符   self:表示绑定事件的元素与触发事件的元素是同一个元素

这些修饰符还可以混合使用

#例子
<body>
<div id="app" v-cloak>
   <div @click="fun_par">
       parte
        <button @click.stop="fun_son">请点击</button>
   </div>
</div>
<script src="vue.js"></script>
<script>
    let timebar;
    let vm = new Vue({
        el:'#app',
        data(){
            return {
                msg:'这是绑定事件'
            }
        },
        methods:{
            fun_par(...args){
                console.log('你们好啊!!!')
            },
            fun_son(...args){
                console.log('我是儿子方法!!!!')
            }

        }

    })
   
</script>
</body>

事件修饰符之鼠标

鼠标键修饰符
	left:点击鼠标左键     right:点击鼠标右键
    middle:点击鼠标中间件
<body>
<div id="app" v-cloak>
   <button @click.right="fun_par">点击</button>
   <button @click.left="fun_par">点击</button>
   <button @click.middle="fun_par">点击</button>
</div>
<script src="vue.js"></script>
<script>
    let timebar;
    let vm = new Vue({
        el:'#app',
        data(){
            return {
                msg:'这是绑定事件'
            }
        },
        methods:{
            fun_par(...args){
                console.log('你们好啊!!!')
            }

        }

    })
   
</script>
</body>       
        
 
辅助键修饰符
	ctrl:点击ctrl辅助键   shift:点击shift辅助键
    alt:点击alt辅助键	 meta:点击windows|command辅助键
<body>
<div id="app" v-cloak>
   <button @click.ctrl="fun_par">点击</button>
   <button @click.alt="fun_par">点击</button>
   <button @click.shift="fun_par">点击</button>
</div>
<script src="vue.js"></script>
<script>
    let timebar;
    let vm = new Vue({
        el:'#app',
        data(){
            return {
                msg:'这是绑定事件'
            }
        },
        methods:{
            fun_par(...args){
                console.log('你们好啊!!!')
            }

        }

    })
   
</script>
</body>           
      
            
            
            
                  
    
键盘事件修饰符(键盘事件:keydown  keyup  keypress(输入有效键))
	有效修饰符:esc  tab  space  enter   delete
    up  down left right 以及所有字母键
<body>
<div id="app" v-cloak>
   <input @keypress.a="inputkey">点击</input>
</div>
<script src="vue.js"></script>
<script>
    let timebar;
    let vm = new Vue({
        el:'#app',
        data(){
            return {
                msg:'这是绑定事件'
            }
        },
        methods:{
            inputkey(e){
                console.log(e.key,e.keyCode)
                console.log(e.key,e.keyCodes,1111)
            }

        }

    })
   
</script>
</body>

    

类的绑定

在vue中  为元素绑定类有三种方式

方式一
:class="{}"
    key  表示一组类的名称(可以包含空格,切割成多个类)】
方式二
:class="[]"
    每一个成员代表一组类 (可以包含空格,切割成多个类)
方式三
:class=="str"  类名之间用空格隔开
    
#三种方式的例子
<style>
    .red1{
        color: aqua;
        background-color: rebeccapurple;
    }
    .height1{
        height: 100px;
        width: 200px;
    }
    .green1{
        color: aquamarine;
        background-color: red;
    }
    .font-si{
        font-size: 20px;
    }
    .color2{
        color: black;

    }
    .bac{
        background-color: chartreuse;
    }
</style>
<body>
<div id="app" v-cloak>
    方式一
    <h1 :class="{'red1 height1':true}">耿家庄存</h1>
    <h1 :class="{'red1 height1':false}">耿家庄存</h1>
    方式二
    <h2 :class="['green1 font-si']">我们是辛集市</h2>

    方式三
    <h3 :class="'color2 '+msg">我爱你中国</h3>
</div>
<script src="vue.js"></script>
<script>
    let timebar;
    let vm = new Vue({
        el:'#app',
        data(){
            return {
                msg:'bac'
            }
        },


    })
   
</script>
</body>


vue基础部分

vue历史介绍

有时间学习  react

前端框架与库的区别


vue起步

<body>
    <div id='app'>
        <h1>
           {{msg}} 
        </h1>
        <h3>
            {{2}}
        </h3>
        <h3>
            "hello"
        </h3>
        <h3>
            //插入对象  第三层花括号的左右两边要有空格以示区分
            {{ {id:1} }}
        </h3>
        <h3>
            //插入表达式
            {{1>2?"真的":"假的"}}
        </h3>
        <h3>
            //翻转字符串 先用空字符分隔 然后翻转 然后拼接
            {{text.split('').reverse().join('')}}
        </h3>
        <h3>
            //插入函数
            {{getCont()}}
        </h3>
    </div>
</body>

//去vue官网下载vue
//通过srcipt标签引入下载的vue.js文件
//初始化
	const vm = new Vue({
		el:'#app',
		//声明的是数据属性
		data(){
			msg:'hello vue',
			text:'hello',
			context:'你好',
			msg3:'<h3>你好</h3>'
		},
		//写所有方法
		methods:{
			getCont(){
				//return '你好'
				return this.msg +" " +this.context
			}
		}
	})

v-text和v-html

<div id='app'>
	<h1>
        <h2 v-text="msg4">
            
        </h2>
        <h2 v-html="msg3">
            
        </h2>
    </h1>
</div>
//{{}}和v-text的作用是一样的,都是插入值 直接渲染 像js innerText
//v-html 既能插入值 又能插入标签   像js  innerHtml
const vm = new Vue({
		el:'#app',
		//声明的是数据属性
		data(){
			msg3:'<p>你好</p>',
			msg4:'插入标签'
		},
		//写所有方法
		methods:{
			
		}
	})

v-if和v-show v-else-if v-else 后边可以跟表达式

<div id='app'>
	<div v-if="Math.random()>0.5">
        显示
    </div>
    <div v-else>
        隐藏
    </div>
    
    <div>
        <h2 v-show="show">
            正常显示
        </h2>
    </div>
</div>


const vm = new Vue({
		el:'#app',
		//声明的是数据属性
		data(){
			show:true
		},
		//写所有方法
		methods:{
			
		}
	})


v-if和v-show的区别: v-if 为假删除整个元素  v-show为假改变样式

v-bind绑定

<div id='app'>
    //方式一
	<a v-bind:href="res.url" v-bind:title="res.title" ></a>
    //方式二
    <a :href="res.url" :title="res.title" >{{res.name}}</a>
    //isActive为真会渲染  为假不会渲染
    <h3 v-bind:class="{active:isActive}">
        v-bind指令
    </h3>
    <h3 :style='{color:isColor,fontSize:fontSize+"px"}'>
    你好啊
    </h3>
</div>





const vm = new Vue({
		el:'#app',
		//声明的是数据属性
		data(){
			res:{
				name:'百度',
				url:"https://baidu.com",
				title:'百度一次',
				isColor:red,
				fontSize:39
			},
			isActive:true
		},
		//写所有方法
		methods:{
			
		}
	})

v-on绑定事件

<style>
    .box{
        width:200px;
        height:200px;
        background-color:red
    }
    .active{
        background-color:green;
    }
</style>


<div id='app'>
    <h3>
        {{num}}
    </h3>
    //方式一
    <button v-on:click="num+1">
        +1
    </button>
    //方式二
     <button v-on:click="handClick">
        +1
    </button>
    
    
    <div class="box" :class={active:isActive}>
        
    </div>
    <button @click="changClick">
        切换
    </button>
    
    
</div>



const vm = new Vue({
		el:'#app',
		//声明的是数据属性
		data(){
			num:0,
			isActive:false
		},
		//写所有方法
		methods:{
			handClick(){
				this.num+=1;
			},
			changClick(){
				//方式一
				if(this.isActive==true){
					this.isActive=false
				}else{
					this.isActive=true
				}
				//方式二
				this.isActive = !this.isActive
			},
		}
	})

vue指令之事件修饰符

 <button @click.stop="changClick">  //阻止事件冒泡
 //提交事件不在重载页面  组件form表单的submit提交事件(默认提交)
 <form v-on:submit.stop.preven="onSubmit">
     
 </form>
  
//可以串联
 <form v-on:submit.stop.preven="onSubmit">
     
 </form>
     
     
.stop
.prevent
.capture
.self
.once
.passive
     
     
<input v-on:keyup.enter="方法名">
.enter
.tab
.delete
.esc
.space
.up
.down
.left
.right
     
     
为什么在html中监听事件
1.扫一眼html模板便能轻松定位在js代码里对应的方法
2.因为无须在js里动手绑定事件,viewmode代码可以是非常纯粹的逻辑
3.当一个viewmode被销毁时,所有的事件处理器都会自动被删除,无须担心如何清理

v-for列表渲染

<div id="app">
    <div>
        //方式一
        <lu>
        	<li v-for="item in menus">
            	<p>
                    id:{{item.id}}菜名{{item.name}}
                </p>
               
            </li>
        </lu>
        //方式二
        <lu>
        	<li v-for="(item,index) in menus" :key="item.id">
            	<p>
                    id:{{item.id}}菜名{{item.name}}
                </p>
               
            </li>
        </lu>
        //遍历对象 方式一
        <ol>
            <li v-for="value in obj">
            	{{value}}
            </li>
        </ol>
        //遍历对象 方式二
        <ol>
            <li v-for="(val,key) in obj" >
            	{{value}}----{{key}}
            </li>
        </ol>
        
        //遍历对象 方式三
        <ol>
            <li v-for="(val,key) in obj" >
            	{{value}}----{{key}}
            </li>
        </ol>
        
    </div>
</div>



const vm = new Vue({
		el:'#app',
		//声明的是数据属性
		data(){
			menus:[
				{id:1,name:'大腰子'},
				{id:2,name:'烤鸡翅'},
				{id:3,name:'烤韭菜'},
			],
			obj:{
				title:"你好",
				author:'小马哥'
			}
		},
		//写所有方法
		methods:{
			
		}
	})

v-model双向数据绑定

<div id="app">
    <p>
       {{msg}} 
    </p>
    <input type="text" v-model="msg">
</div>




const vm = new Vue({
		el:'#app',
		//声明的是数据属性
		data(){
			msg:''
		},
		//写所有方法
		methods:{
			
		}
	})

复选框单选

v-model="checked"  //获取的值不是 true  就是 false

复选框多选

网址练习里面有很多 单选框  多选框  等等
http://cn.vuejs.org/v2/guide/forms.html#单选按钮

<div id="app">
    <label for='a'>黄瓜</label>
    <input type='checkbox' id='a' value='黄瓜' v-mode="checkName">
    
    <label for='c'>西红柿</label>
    <input type='checkbox' id='c' value='西红柿' v-mode="checkName">
    
    <label for='b'>毛豆</label>
    <input type='checkbox' id='b' value='毛豆' v-mode="checkName">
</div>

<span>{{listName}}</span>

const vm = new Vue({
		el:'#app',
		//声明的是数据属性
		data(){
			listName:[]
		},
		//写所有方法
		methods:{
			
		}
	})



<label>{{txt}}</label>
<input v-model.lazy='txt'>
.number数值类型 输入的是文本  会转为数值类型
.trim 过滤用户输入的收尾空白字符
const vm = new Vue({
		el:'#app',
		//声明的是数据属性
		data(){
			txt:''
		},
		//写所有方法
		methods:{
			
		}
	})

侦听器

<div id="app">
    <input type="text" v-model='msg'>
	<h3>
        {{msg}}
    </h3>
    
    
    
    <h3>
        {{stus[0].name}}
    </h3>
    <button @click='stus[0].name'>
        改变
    </button>
</div>


const vm = new Vue({
		el:'#app',
		//声明的是数据属性
		data(){
			msg:'',
			stus:[{name:'jack'}]
		},
		//写所有方法
		methods:{
			
		},
		watch:{
			//msg 是属于data对象的属性名  value:监视后的行为
			'msg':function(newV,oldV){

			},
			//深度监视   object  Array
			'stus':{
				deep:'true', //表示深度监视
				handler:functioni(newV,oldV){
					console.log(newV[0].name)
				},
			}
		}
	})

//基本的数据类型可以使用watch直接监听  复杂数据类型要深度监视

计算属性

<div id="app">
    {{reverseMsg}}
    <h3>
       {{fullName}} 
    </h3>
</div>

const vm = new Vue({
		el:'#app',
		//声明的是数据属性
		data(){
			msg:'hellow',
			firstname:'小马',
			lastName:'哥'
		},
		//写所有方法
		methods:{
			
		},
		computed:{
			//计算属性最大的优点,产生缓存 如果数据没有产生变化直接从缓冲中取
			//存放方法 computed默认只有getter方法
			reverseMsg:function(){
				return this.msg.split('').reverse().join('')
			},
			
			fullName:function(){
				return this.firstname + this.lastName
			},
		}
	})

过滤器filters

<div id="app">
    <h3>
        //方式一
        {{price | myPrice}}
        //方式二
        {{price | myPrice('人民币')}}
        //全局过滤器
        <h3>
            {{msg | 过滤器名字}}
        </h3>
    </h3>
</div>
//过滤器 为数据添油加醋
const vm = new Vue({
		el:'#app',
		//声明的是数据属性
		data(){
			price:10,
			msg:'过滤器'
		},
		//写所有方法
		methods:{
			
		},
		filters:{
			//局部过滤器
			//方式一
			myPrice:function(price){
				return '$' + price
			},
			myPrice:function(price,a){
				return a + price
			},
		}
	})

//创建全局过滤器
Vue.filter(过滤器名字,(val,可以有多个参数)=>{
	return val.split('').reverse().join('')
})


vue组件开发

局部组件的创建和使用

//入口
<div id='app'>
    //第三部使用子组件
    <App></App>
</div>

//引入vue.js文件
<script src="vuejs"></script>
<script>
    //创建子组件
    //使用局部组件的打油诗:创建   挂载  使用
    //第一步
    const App = {
        //还可以写data
        data(){
            return {
                msg:'我是app组件'
            }
        }
        //template是写html的地方
        template:
        `
        <div>
    		<h3>{{msg}}</h3>
			<h2>我是一个APP组件</h2>
			<button @click=handleClick>按钮</button>	
			
    	</div>
		`   ,
        //还可以写methods方法
        methods:{
            handleClick(){
                this.msg='学习局部组件'
            },
        },
        computed:{
            
        }
    }
    
    
	new Vue({
        el:"#app",
        data(){
            return{
                
            }
        },
        components:{
            //第二步
            //挂载子组件
            App
        }
    })


</script>

全局组件

//入口
<div id='app'>
    //第三部使用子组件  全局组件可以直接使用
    <App></App>
</div>

//引入vue.js文件
<script src="vuejs"></script>
<script>
    //创建全局组件
    //Vue.component('组件名',对象)
     Vue.component('Liu',{
         template:`
			<div>
    			我是导航组件
    		</div>
		`
     })
    
    
    
    //创建子组件
    //使用局部组件的打油诗:创建   挂载  使用
    //第一步
    const App = {
        //还可以写data
        data(){
            return {
                msg:'我是app组件'
            }
        }
        //template是写html的地方
        template:
        `
        <div>
			//使用全局组件
    		<Liu></Liu>	
			
    	</div>
		`   ,
        //还可以写methods方法
        methods:{
            handleClick(){
                this.msg='学习局部组件'
            },
        },
        computed:{
            
        }
    }
    
    
	new Vue({
        el:"#app",
        data(){
            return{
                
            }
        },
        components:{
            //第二步
            //挂载子组件
            App
        }
    })


</script>

组件通信父传子

//入口
<div id='app'>
    //第三部使用子组件  全局组件可以直接使用
    <App></App>
</div>

//引入vue.js文件
<script src="vuejs"></script>
<script>
    //全局组件
    
    //子组件
    Vue.component('Child',{
     	template:`
		<div>
    		<h2>我是一个子组件</h2>
			//父传子 第三部 使用
			<h3>{{childData}}</h3>
    	</div>

		`,
        //父组件传值给子组件需要定义的东西(下面可以是字符串 数组等)	// 父传子 第二步  接收值
        props:['childData']
     
                  
     })
    
    //创建子组件
    //使用局部组件的打油诗:创建   挂载  使用
    //第一步
    
    //父组件
    const App = {
        //还可以写data
        data(){
            return {
                msg:'我是父组件传进来的值	'
            }
        }
        //template是写html的地方
        template:
        `
        <div>
			//父组件向子组件传值的方式
			//父传子  第一步  传值
			<Child :childData='msg'></Child>
			
    	</div>
		`   ,
        
        
        components:{
            //用于挂载组件
        },
    }
    
    
	new Vue({
        el:"#app",
        data(){
            return{
                
            }
        },
        components:{
            //第二步
            //挂载子组件
            App
        }
    })


</script>

1.在子组件中声明props接收父组件挂载的属性
2.可以在子组件的template中任意使用
3.在父组件绑定自定义的属性

上面都有例子

组件通信子传父

//入口
<div id='app'>
    //第三部使用子组件  全局组件可以直接使用
    <App></App>
</div>

//引入vue.js文件
<script src="vuejs"></script>
<script>
    //全局组件
    
    //子组件
    Vue.component('Child',{
     	template:`
		<div>
			//子传父  第一步
    		<input type="text" @input="handlInput">
    	</div>

		`,
        methods:{
        	handlInput(e){
        		const val = e.target.value
                //子传父  第二步   第一个参数是父组件的
                this.$emit('inputhandl',val)
    		},          
        }
                  
     })
    
    //创建子组件
    //使用局部组件的打油诗:创建   挂载  使用
    //第一步
    
    //父组件
    const App = {
        //还可以写data
        data(){
            return {
                msg:'我是父组件传进来的值	',
                newV:''
            }
        }
        //template是写html的地方
        template:
        `
        <div>
			<div class="father">
    			数据{{newV}}
    		</div>
			//第三部   inputhandl  写到子组件中的$emit 的第一个参数
			<Child :childData='msg' @inputhandl="input"></Child>
			
    	</div>
		`   ,
        
        methods:{
        	//第四部
        	input(newV){
                console.log(newV)
                this.newV=newV
            }
    	},
        
        
        components:{
            //用于挂载组件
        },
    }
    
    
	new Vue({
        el:"#app",
        data(){
            return{
                
            }
        },
        components:{
            //第二步
            //挂载子组件
            App
        }
    })


</script>


//子往父传值
1.在父组件中  子组件上绑定自定义事件
2.在子组件中  触发原生的事件 在事件函数通过this.$emit触发自定义的事件

组件通信之平行通信

//入口
<div id='app'>
    //第三部使用子组件  全局组件可以直接使用
    <App></App>
</div>

//引入vue.js文件
<script src="vuejs"></script>
<script>
    //创建公交车  
    const bus = new Vue()
    
    
    Vue.component('B',{
        template:`
			<div>{{count}}</div>

		`,
        data(){
            return{
                count:0
            }
        },
        created(){
       		//$on  绑定事件
            this.$on('add',(n)=>{
                this.count+=n
            })
            //$emit  触发事件
        },
    })
    
    Vue.component('A',{
        template:`
			<div>
    			<button @click="hanlderClick">加入购物车</button>
    		</div>

		`,
        data(){
            return{
                
            }
        },
        methods:{
            hanlderClick(){
                this.$emit('add',1)
            },
        }
    })
    
  
    
    //父组件
    const App = {
        //还可以写data
        data(){
            return {
               
            }
        }
        //template是写html的地方
        template:
        `
        <div>
			<A></A>
			<B></B>
			
    	</div>
		`   ,
        
        methods:{
        	//第四部
        	input(newV){
                console.log(newV)
                this.newV=newV
            }
    	},
        
        
        components:{
            //用于挂载组件
        },
    }
    
    
	new Vue({
        el:"#app",
        data(){
            return{
                
            }
        },
        components:{
            //第二步
            //挂载子组件
            App
        }
    })


</script>

组件通信其他方式

//入口
<div id='app'>
    //第三部使用子组件  全局组件可以直接使用
    <App></App>
</div>

//引入vue.js文件
<script src="vuejs"></script>
<script>
    
    //provide
    //inject
    //父组件 provide来提供变量,然后在子组件中通过inject来注入变量,无论组件嵌套多深
    
    
    
    //创建公交车  
    const bus = new Vue()
    
    
    Vue.component('B',{
        template:`
			<div>{{count}}</div>
			<div>{{msg }}</div>

		`,
        data(){
            return{
                count:0
            }
        },
        inject:['msg'],
        created(){
            //页面创建时需要父组件的数据 这样用this去
          console.log(this.msg)  
        },
        
    })
    
    Vue.component('A',{
        template:`
			<div>
    			<B></B>
    		</div>

		`,
        data(){
            return{
                
            }
        },
        created(){
            //获取父组件this.$parent
            console.log(this.$parent.title)
            
           	console.log(this.$children)
            
            
        },
        methods:{
            hanlderClick(){
                this.$emit('add',1)
            },
        }
    })
    
  
    
    //父组件
    const App = {
        //还可以写data
        data(){
            return {
               title:'我是老爹'
            }
        },
        provide(){
            return {
                msg:'老爹的数据'
            }
        }
        //template是写html的地方
        template:
        `
        <div>
			<A></A>
			
			
    	</div>
		`   ,
        
        methods:{
        	//第四部
        	input(newV){
                console.log(newV)
                this.newV=newV
            }
    	},
        
        
        components:{
            //用于挂载组件
        },
    }
    
    
	new Vue({
        el:"#app",
        data(){
            return{
                
            }
        },
        components:{
            //第二步
            //挂载子组件
            App
        }
    })


</script>

插槽

//入口
<div id='app'>
    //第三部使用子组件  全局组件可以直接使用
    <App></App>
</div>

//引入vue.js文件
<script src="vuejs"></script>
<script>
    Vue.components('MBtn',{
        template:`
			<button>
				//留槽
    			<slot></slot>
    		</button>
		`
    })
    
  
    
    //父组件
    const App = {
        //还可以写data
        data(){
            return {
               title:'我是老爹'
            }
        },
        
        //template是写html的地方
        template:
        `
        <div>
			<MBtn><a>登录</a></MBtn>
			<MBtn>注册</MBtn>
    	</div>
		`   ,
        
        methods:{
        	//第四部
        	input(newV){
                console.log(newV)
                this.newV=newV
            }
    	},
        
        
        components:{
            //用于挂载组件
        },
    }
    
    
	new Vue({
        el:"#app",
        data(){
            return{
                
            }
        },
        components:{
            //第二步
            //挂载子组件
            App
        }
    })


</script>

具名插槽

//入口
<div id='app'>
    //第三部使用子组件  全局组件可以直接使用
    <App></App>
</div>

//引入vue.js文件
<script src="vuejs"></script>
<script>
    Vue.components('MBtn',{
        template:`
			<button>
				//留槽
    			<slot name="login"></slot>
                <slot name="submit"></slot>
                <slot name="regist"></slot>
    		</button>
		`
    })
    
  
    
    //父组件
    const App = {
        //还可以写data
        data(){
            return {
               title:'我是老爹'
            }
        },
        
        //template是写html的地方
        template:
        `
        <div>
			<MBtn>
    			<template slot='login'>
    				<a>登录</a>
    			</template>
    		</MBtn>
			<MBtn>
    			<template slot='submit'>
    				<a>提交</a>
    			</template>
    		</MBtn>

			<MBtn>
    			<template slot='regist'>
    				<a>注册</a>
    			</template>
    		</MBtn>
    	</div>
		`   ,
        
        methods:{
        	//第四部
        	input(newV){
                console.log(newV)
                this.newV=newV
            }
    	},
        
        
        components:{
            //用于挂载组件
        },
    }
    
    
	new Vue({
        el:"#app",
        data(){
            return{
                
            }
        },
        components:{
            //第二步
            //挂载子组件
            App
        }
    })


</script>

作用域插槽

//有时间在重新看一遍

vue中的声明周期

//入口
<div id='app'>
    //第三部使用子组件  全局组件可以直接使用
    <App></App>
</div>

//引入vue.js文件
<script src="vuejs"></script>
<script>
    Vue.component('Test',{
        data(){
            msg:'周润发'
        },
        template:`
			<div>
    			<h3>{{msg}}</h3>
    		</div>
		
		`,
        //组件创建之前执行的方法
        beforeCreate(){
            
        },
        //组件创建完成执行
        created(){
            //做非常重要的事情 发送ajax请求数据向后端
        },
        //挂载之前触发的方法
        beforeMount(){
            
        },
        mounted(){
            //发送ajax  也可以
            //挂载完成触发
        },
        beforeUpdate(){
            //获取更新之前的dom
            //更新之前触发
        },
        updated(){
            //获取最新的dom
            //更新之后触发
        },
        beforeDestroy(){
            //销毁之前触发
        },
        destroyed(){
            //销毁完成
        },
        activated(){
          //组件被激活了  
        },
        deactivated(){
          //组件被停用了  
        },
        //deactivated和activated需要配合keep-alive标签使用,keep-alive和html标签一样使用,但是需要激活或者停用的代码写在keep-alive里面
    })
    
      
    
    
   const App={
       data(){
         return{}  
       },
       components:{},
       template:`
			<Test></Test>
		`
   }
    
    
	new Vue({
        el:"#app",
        data(){
            return{
                
            }
        },
        components:{
            //第二步
            //挂载子组件
            App
        }
    })


</script>

异步组件加载

//创建一个js文件
export default {
	data(){
		return{
			msg:'小马哥'
		}
	},
	template:`
		<h3>
        		{{msg}}    
		</h3>
	`
}


//入口
<div id='app'>
    //第三部使用子组件  全局组件可以直接使用
    <App></App>
</div>

//引入vue.js文件
<script src="vuejs"></script>
<script type="module">
   
    
      
    
    
   const App={
       data(){
         return{}  
       },
       components:{},
       template:`
			<Test></Test>
		`,
       comonents:{
       	Test:()=>import('./Test.js')
   	   },
   }
    
    
	new Vue({
        el:"#app",
        data(){
            return{
                
            }
        },
        components:{
            //第二步
            //挂载子组件
            App,
        }
    })


</script>

vue中的ref属性

//引入vue.js文件
<script src="vuejs"></script>
<script type="module">
   
    
      
    
    
   const App={
       data(){
         return{}  
       },
       components:{},
       template:`
			<button ref="btn">按钮</button>
			<input type="text" ref='input'>
		`,
       comonents:{
       	Test:()=>import('./Test.js')
   	   },
       mounted(){
           
          //如果给标签添加ref,获取的就是真实的dom节点
          //如果给子组件添加ref,获取的是当前子组件对象
         //获取button按钮
         console.log(this.$refs.btn)  
         //自动获取焦点
         this.$refs.input.focus();
       },
   }
    
    
	new Vue({
        el:"#app",
        data(){
            return{
                
            }
        },
        components:{
            //第二步
            //挂载子组件
            App,
        }
    })


</script>

nextTick的用法

<div id="app">
    <h3>
        {{msg}}
    </h3>
</div>
//引入vue.js文件
<script>
	const vm=new Vue({
        el:'#app',
        data(){
            return{
                msg:"小马哥"
            }
        }
    })
    vm.msg='新小马哥'
    Vue.nextTick(()=>{
        console.log(vm.$el.textContent)
    })

</script>

minxin偷懒技术

<div id="app">
    <h3>
        {{msg}}
    </h3>
</div>
//引入vue.js文件
<script>
    const myMixin = {
        data(){
            return{
                msg:'123'
            }
        },
        created(){
          this.sayHello()  
        },
        methods:{
            sayHello(){
                console.log('你哈')
            }
        }
    }
    //minxin来分发Vue组件中的可复用功能
    
	const vm=new Vue({
        el:'#app',
        data(){
            return{
                title:"小马哥"
            }
        },
        mixins:[myMinxin]
    })
    

</script>

进阶了

Vue Cli3脚手架

//基本配置
	安装nodejs
	终端中输入node -v  保证已安装完成
//安装淘宝镜像源
	npm install -g cnpm --registry=https://registry.npm.taobao.org	
	以后的npm可以用cnpm代替
//安装Vue cli3 脚手架
	cnpm install -g @vue/cli
//检查其版本是否正确
	vue --version

快速的原型开发

//进入一个文件初始化
npm init

//使用vue  serve和vue build 命令对单个*.vue文件进行快速原型开发,不过这需要先额外安装一个全局的扩展
npm install -g @vue/cli-service-global


vue serve 的缺点就是它需要安装全局依赖,这使的它在不同机器上的一致性不能得到保证,因此这只适用于快速原型开发

需要的仅仅是一个App.vue文件

<template>
//编写html
	<div>
        <h2>
          hello word 单页面组件  
    	</h2>
    </div>
</template>

<script>
    //编写js
	export default{
        
    }
</script>


<style scoped>
	//编写css样式
</style>

创建项目

vue create 项目名字

需要知道的代码

let sum = 0
this.cart.forEache(c =>{
	if(c.active ){
		sum += c.price*c.count;
	}
})
return sum




return this.cart.reduce((sun,c)=>{
	if(c.active){
		sum += c.price*c.count
	}
	return sum
}0)

购物车代码

//需要加微信要代码

组件深入

//使用element-ui需要先下载
npm install element-ui安装
//在main.js 中 写入一下代码

//完整导入
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css0';
import App fro './App.vue'

Vue.user(ElementUI)


//按需求导入
第一步
npm install babel-plugin-component -D
第二步
将.babelrc修改为
{
  "presets": [["es2015", { "modules": false }]],
  "plugins": [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

第三部
接下来,如果你只希望引入部分组件,比如 Button 和 Select,那么需要在 main.js 中写入以下内容:
import Vue from 'vue';
import { Button, Select } from 'element-ui';
import App from './App.vue';

Vue.component(Button.name, Button);
Vue.component(Select.name, Select);
/* 或写为
 * Vue.use(Button)
 * Vue.use(Select)
 */

new Vue({
  el: '#app',
  render: h => h(App)
});

//方式二安装
在vue-cli中可以使用vue add element 安装
安装之前注意提前提交当前工作内容,脚手架会覆盖若干文件

发现项目发生了变化,打开App.vue  ctrl+z  撤回 

自定义组件

<div>
    <input :type="type" :value="inputVale" @input="handleInput">
</div>


<script>
	export default{
        props:{
            type:{
                type:String,
                default:'text'
            },
            value:{
                type:String,
                default:""
            }
        },
        data(){
            return{
                inputVale:this.value
            }
        },
        methods:{
            handleInput(e){
                this.inputVal = e.target.value
                //通知父组件值的更新
                this.$emit('input',this.inputVal)
            }
        },
    }

</script>


//在另一个文件中使用
先导入
<m-input v-model=ruleForm.name></m-input>
<m-input type='password' v-model="ruleForm.pwd"></m-input>

vue-router

vue-element-admin  有时间自己预习一下

//如果创建vue项目的时候没有安装  vue-router插件 解决办法
//方法一
npm i vue-router -S
在 main.js中配置
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

//方法二
vue add router

vue-router基本使用

//在没有安装vue-router的情况下执行
npm i vue-router -S
会创建一个router文件夹 里面有index.js文件 文件中这样写
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

//导入页面组件

//配置路由
export default new VueRouter({
	routes:[
		{
			path:'/',
			component:Home
		}
	]
})


//在main.js中引入  创建出来的router文件夹
import router from './router'

//挂载router
new Vue({
	router,
})

命名路由

//router中的index.js
export default new VueRouter({
	routes:[
		{
			path:'/',
			name:'home',  //命名路由
			component:Home
		}
	]
})


在template中的使用
比如:
<router-link :to="{name:'home'}">首页</router-link>

动态路由匹配和路由组件使用

export default new VueRouter({
	routes:[
		{
			path:'/user/:id',  //动态路由匹配  
			name:'user',  //命名路由
			component:Home
		}
	]
})

在template中的使用
比如:
<router-link :to="{name:'user',params:{id:1}}">首页</router-link>

<router-link :to="{name:'user',params:{id:2}}">首页</router-link>

//获取user路径后的id值
template中获取
{{$route.params.id}}

//在script中任何地方获取
this.$route.params.id


#可以在监听事件中获取user后面的id
watch:{
	$route:(to,from)=>{
		console.log(to.params.id)
	}
}

//关于路由的方法
beforeRouteUpdate(to,from,next){
	console.log(to.params.id)
	//一定要调用next方法不然路由会形成堵塞
	next()
}

路由和路由匹配优先级

//路由匹配优先级  从上往下

export default new VueRouter({
	routes:[
		{
			path:'/user-*',  //动态路由匹配  
			name:'user',  //命名路由
			component:Home
		}
	]
})

在template中
<h4>
    {{$route.params.pathMatch}}  //可以匹配到user-*的部分
</h4>

路由查询参数

export default new VueRouter({
	mode:'history',  //可以产生干净的地址栏地址
	routes:[
		{
			path:'/page',    
			name:'page',  //命名路由
			component:()=>import('@/views/Page')
		}
	]
})	
templeate中 就是这种请求地址  https://www.page/?id=2&title=foo
<router-link :to="{name:'page',query:{id:2,title:'foo'}}">Page</router-link>


//获取问好后面的值
const title = this.$route.query.title
const id = thie.$route.query.id

const {id,title} = this.$route.query

路由的重定向和别名

export default new VueRouter({
	mode:'history',  //可以产生干净的地址栏地址
	routes:[
		{
			path:'/'  //访问/
			redirect:'/home' //重定向到home页面  方式一

			redirect:{name:'home'}    方式二
	
		}
		{
			path:'/home',  (可以在页面路径使用)
			name:'home',  //命名路由
			component:()=>import('@/views/home'),
			alias:'/aaaa'  //起别名  (可以在页面路径使用)
		}
	]
})	

路由组件传值

export default new VueRouter({
	mode:'history',  //可以产生干净的地址栏地址
	routes:[
		{
			path:'/user/:id',    
			name:'user',  //命名路由
			component:()=>import('@/views/User'),
			props:true  //方式一
			props:(route)=>({    //方式二
				id:route.params.id,
				title:route.query.title
			})
		}
	]
})	


在user组件中使用
props:['id']  //方式一

props:['id','title']//方式二


template中使用
{{id}}  //方式一

{{id}}{{title}} //方式二

这样访问
localhost:80000/user/2?title=foo

编程式导航

this.$router.push(跳转地址)
this.$router.push({
	path:'/'
})


this.$router.push({
	name:'user',
	params:{id:2}
})


this.$router.go()  //0 表示刷新  1  表示前进  -1 表示后退

嵌套路由使用

Profile.vue文件
template中写的  
<h1>
    我是Profile.vue文件
</h1>


Posts.vue文件
template中写的
<h1>
    我是Posts.vue文件
</h1>




export default new VueRouter({
	mode:'history',  //可以产生干净的地址栏地址
	routes:[
		{
			path:'/user/:id',    
			name:'user',  //命名路由
			component:()=>import('@/views/User'),
			props:true  //方式一
			props:(route)=>({    //方式二
				id:route.params.id,
				title:route.query.title
			}),
			children:[
				{
					path:'profile',
					component:()=>import('@/views/Profile')
				},
				{
					path:'posts',
					component:()=>import('@/views/Posts')
				}
			]
		}
	]
})	



user.vue中写
//子路由的出口
<router-view></router-view>


在别的文件中使用
<router-link to="/user/1/profile">profile</router-link>
<router-link to="/user/1/posts">posts</router-link>

命名视图

export default new VueRouter({
	mode:'history',  //可以产生干净的地址栏地址
	routes:[
		{
			path:'/home',    
			name:'home',  //命名路由
			components:{
				default:Home,  //默认名字
				//main:Main    
				main:()=>import('@/views/Main'),
				tabanner:()=>import('@/views/Tabanner')
				....
			}
			
			
		}
	]
})	


App.vue中的使用
<router-view></router-view>  //默认是home页面的出口
<router-view name='main'></router-view>
<router-view name='tabanner'></router-view>


导航守卫

//全局守卫

const router=new VueRouter({.....})

router.beforeEach((to,from,next)=>{
	//....
})


需求  用户登录只有才可以查看网站中的各个页面
模拟

创建Notes.vue文件
template中写的
<div>
    <h3>
        我是Notes文件
    </h3>
</div>

创建登录页面Login.vue文件
template
<h2>
    登录页面
</h2>



配置路由
export default new VueRouter({
	mode:'history',  //可以产生干净的地址栏地址
	routes:[
		{
			path:'/notes',
			name:'notes',
			component:()=>import('@/views/Notes')
		},
		{
			path:'/login',
			name:'login',
			component:()=>import('@/views/Login')
		},
	]
})	



App.vue文件中写的
<router-link :to='{name:'notes'}'>我的笔记</router-link>


在main.js中写全局守卫
router.beforeEach((to,from,next)=>{
	//to  到哪去
	// from  从哪来
	if(to.path==='/notes'){
		//用户访问了我的笔记页面
		const user = JSON.parse(localStorage.getItem('user'))
		if(user){
			//用户登录
			next()
		}else{
			//用户没有登录  跳转登录页面
			next('/login')
		}		
	}
	next()//必须调用
})




//组件内部的守卫
beforeRouteEnter  取不到this



beforeRouteUpdate
beforeRouteLeave  离开该路由是被调用 可以使用this  

上面三个函数 都有三个参数  to  from  next

路由meta元信息实现权限管理

创建一个Blog.vue文件
template中写的是
<h3>
    我是blog
</h3>

export default new VueRouter({
	mode:'history',  //可以产生干净的地址栏地址
	routes:[
		{
			path:'/blog',
			name:'blog',
			component:()=>import('@/views/Blog'),
			meta:{
				//加到黑名单
				requireAuth:true
			}
		},	
	]
})	

<router-link :to='{name:'blog'}'>我的博客</router-link>



在main.js中写全局守卫
router.beforeEach((to,from,next)=>{
	if(to.matched.some(record=>record.meta.requireAuth)){
	//需要权限
	if(!localStorage.getItem('user')){
		next({
			path:'/login',	

			query:{
				redirect:to.fullPath//完整的路径
			}
		})
	}else{
		next();
	}
}

	next()
})

vuex

vuex是一个专门vue.js应用程序开发的 状态管理模式

vuex管理状态(向共享的状态)

vuex的基本使用

//线程的项目,如果项目中没有vuex的话 可以使用 vue add vuex下载
下载完成之后会在src目录中多一个  store目录

需要 导入 
import store from './store'
和router一样 在vue中注册
new Vue({
	router,
	store,
	.....
})


store文件夹中的index.js文件中的内容
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
const store =  new Vuex.Store({
	state:{
		//当前的状态]
		count:0
	},
	mutations:{
		//同步的方法声明  第二步    方法一  和 方法二都需要
		increment(state){
			//修改状态
			state.count++
		}
	},
	actions:{
		//异步的方法声明   第一步  方法一
		//increment({commit}){
			//commit mutations中声明的方法
			//commit('increment')
		///}


		//修改状态的唯一方法就是提交mutation

	},
	modules:{
		
	}
})

export default store;



在home组件中

<templeate>
	{{count}}
    <button @click="increment">
        
    </button>
</templeate>

<script>
export default{
    
    computed:{
        count(){
            return this.$store.state.count
        }
    },
    methods:{
    	increment(){
            //dispathch 触发actions中声明的方法
            this.$store.dispatch('increment')//方法一
            
            this.$store.commit('increment')//方法二
            
        },
    },
}
	
</script>

vuex系列辅助函数

//线程的项目,如果项目中没有vuex的话 可以使用 vue add vuex下载
下载完成之后会在src目录中多一个  store目录

需要 导入 
import store from './store'
和router一样 在vue中注册
new Vue({
	router,
	store,
	.....
})


store文件夹中的index.js文件中的内容
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
const store =  new Vuex.Store({
	state:{
		//当前的状态
		count:0,
		username:'小白'
	},
	getters:{
		evenOrOdd(state){
			return state.count % 2 ===	0?'偶数':'基数'	
		}
	},
	mutations:{
		//同步的方法声明  第二步    方法一  和 方法二都需要
		increment(state){
			//修改状态
			state.count++
		}
	},
	actions:{
		//异步的方法声明   第一步  方法一
		//increment({commit}){
			//commit mutations中声明的方法
			//commit('increment')
		///}




	},
	modules:{
		
	}
})

export default store;



在home组件中

//重点使用
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'


<templeate>
    //方式一
	{{count}}
    {{username}}
    
    
   	//方式二
    {{myCount}}
    {{user}}
    ----------------------
    {{evenOrOdd}}
    
        
    </button>
</templeate>

<script>
export default{
    
    computed:{
        /*count(){
            return this.$store.state.count
        },
        username(){
    		return this.$store.state.username
		},*/
        
        /*...mapState(['count','username'])*/方法一
        ...mapState({
        	myCount:'count',
        	user:'username'
    	}),
    
    	--------------
    	evenOrOdd(){
            return this.$store.getters.evenOrOdd
        },
            
        ...mapGetters(['evenOrOdd'])
    	-----------------
        ...mapMutations(['increment'])
    	------------------------------
    
    	...mapActions(['increment'])
    
    
    	----------------------------------
    	注意:如果router文件夹中有多个文件是这样使用
        ...mapGetters('文件名',['方法名'])
        
        
    },
    methods:{
    	increment(){
            
            
        },
    },
}
	
</script>

如何在组件内部提交数据给vuex

//线程的项目,如果项目中没有vuex的话 可以使用 vue add vuex下载
下载完成之后会在src目录中多一个  store目录

需要 导入 
import store from './store'
和router一样 在vue中注册
new Vue({
	router,
	store,
	.....
})


store文件夹中的index.js文件中的内容
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
const store =  new Vuex.Store({
	state:{
		//当前的状态
		count:0,
		username:'小白'
	},
	getters:{
		evenOrOdd(state){
			return state.count % 2 ===	0?'偶数':'基数'	
		}
	},
	mutations:{
		//同步的方法声明  方法一
		/*increment(state,amount){
			//修改状态
			state.count += amount
		}*/

		//方法二
		increment(state,amount){
			//修改状态
			state.count += amount
		}
	},
	actions:{
		increment({commit,state},{amount}){
			commit('increment',amount)
		}




	},
	modules:{
		
	}
})

export default store;



在home组件中

//重点使用
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'


<templeate>
    //方式一
	{{count}}
    {{username}}
    
    
   	//方式二
    {{myCount}}
    {{user}}
    ----------------------
    {{evenOrOdd}}
    
        
    </button>
</templeate>

<script>
export default{
    
    computed:{
        
        
    },
    methods:{
        //方法一
    	increment(){
            this.$store.dispathc('increment',{
                amount:10
            })
            
        },
        //方法二
        increment(){
           this.$store.dispatch({
               type:'increment',
               amount
           })
            
        },
    },
}
	
</script>

store中有多个文件时 多个文件中的数据怎样共享

//在getters中获取
getters:{
	方法名(state,getters,rootState){
		//打印一下rootState就可以看出来了
		//getters可以调用getters中的自定义方法
	}
}

在一个模块中  提交另一个模块数据的时候{root:true}  要加这个
如果想提交另一个模块中的方法,那么需要第三个参数{root:true}
commit('还可以写另一个文件的方法',字典形式传参,{root:true})

posted @ 2021-04-13 09:50  甜甜太阳雨  阅读(127)  评论(0编辑  收藏  举报