07ref父子通信,props,混入,插件,vuex,本地存储,vue-router

【一】ref父子通信总结

1.1之前学过的

#1.放在普通标签上
#2.放在组件上
在js中用this.$refs.ref名获取该对象

1.2父传子

就是直接
this.$refs.组件的ref.属性=父组件的变量就可以直接传值了
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./vue2/vue.js"></script>
</head>
<body>
<div id="app">
    <h1>父亲拿到值{{username}}</h1>
    <child ref="child"></child>
    <button @click="senddata">点我子传父</button>
    <button @click="sendson">点我父传子</button>
</div>
​
</body>
<script>
    Vue.component('child', {
        template: `
          <div>我是子组件
          {{this.getname}}
          我是子组件
          </div>
        `,
        data() {
            return {
                name: 'llh',
                getname: ''
            }
        },
        methods: {}
    })
    new Vue({
        el: '#app',
        data: {
            username: 'llh',
        },
        methods: {
            senddata() {
                this.username = this.$refs.child.name
            },
            sendson(){
                this.$refs.child.getname=this.username
            }
        }
    })
</script>
</html>

1.3父传子

直接获取自组建的值
父组件属性=this.$refs.组件的ref.属性
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./vue2/vue.js"></script>
</head>
<body>
<div id="app">
  <h1>父亲拿到值{{username}}</h1>
    <child ref="child"></child>
    <button @click="senddata">点我子传父</button>
</div>
​
</body>
<script>
    Vue.component('child',{
        template:`<div>我是子组件</div>`,
        data(){
            return{
                name:'llh'
            }
        },
        methods: {
​
        }
    })
    new Vue({
        el:'#app',
        data:{
            username:'',
        },
        methods:{
            senddata(){
                this.username=this.$refs.child.name
            }
        }
    })
</script>
</html>

1.4补充-子组件中拿到父组件对象

# this.$parent但是这个一般不用因为如果有多个父组件呢

1.5总结:父子通信的方式

# 1 自定义属性
props
# 2 自定义事件
this.$emit('事件名',参数)
# 3 通过ref属性:this.$refs
# 4 子组件中通过 this.$parent

【二】props使用方式的总结

# props是用来父传子时,自定义属性,在子组件中声明,才能使用当前属性
​
#方式一:
props:['msg']
    
#方式二:限制类型--》如果传的不是string,那么也会可以运行但是会报警告,类似于python的弱类型
 props:{myname:String}
​
 #方式三:/默认值父亲没有name才会给默认值,若是空字符串那也是有值的
props:{
            myname: {
              type: String, //类型
              required: true, //必要性
              default: '老王' 
        }

【三】混入

# 1 抽取公共的代码,
	-多个组件中都会有的代码,抽出来
    -哪个组件用,使用mixin引入即可
    
    """注意,他导出的是共同代码,用的时候,类似于字典,无则新增,有则用原来的"""
#方式1,局部
1.在vue中的使用
import mixin from '@/mixin/llh'
export default {
  data(){
    return {name:'llh'}
  },
  methods:{
    handleclick(username){
      this.name="阿华"
    }
  },
mixins:[mixin]
}

2.js,混用文件
export default  {
    data(){
    return {name:'llh'}
  },
  methods:{
    handleclick(changename){
      this.name=changename
    }
  }
}

#方式2全局使用---》可以多每个vue实例都用混用
import m1 from '@/mixin'
import m2 from '@/mixin2'
Vue.mixin(m1)
Vue.mixin(m2)



"""优先级:自己有》局部定义》全局"""

【四】插件

#1 功能:用于增强Vue

#2 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据


#3 使用了vue-router插件,vuex插件,elementui
this.$router    this.$store    this.$alert    this.$message 

# 4 使用别人写好的第三方插件  
Vue.use(ElementUI);


"""$指令都在原型类中,类似于对象的继承,找不到就一层一层往父亲找"""

4.1自定义插件

#做一个axios的插件案例把这个指令变成长得和jquery很像的ajax请求

1.第一步:做一个插件
"""注意: 
1.为了防止变量污染,所以我们一般都给插件的指令用的时候加$
2.那么就要给原型类加Vue.prototype
3.插件要导出用所以先来个导出"""
import axios from "axios";
export default {
    install(Vue){
 Vue.prototype.$ajax = axios    Vue.prototype.$BASE_URL='http://127.0.0.1:8000/'
    }
}

2.第二步:在main.js进行全局声明
//插件要先声明一下
import selfset from '@/plugin'
Vue.use(selfset)


3.第三步使用
 handleclick(changename){
      this.$ajax.get('http://192.168.1.108:8000/chatroom/').then(response=>{
            alert("axios")
      }).catch(error => {
            console.error('请求失败:', error);
          })
    }

    
    # 咱们需要掌握的;
	-有些第三方插件,用了以后,增强了vue功能
    -this.$router
    -全局组件 :el-button
    -this.$message--->
    -this.$http.get

4.2自定义指令

1.定义全局指令:跟v-model一样,获取焦点

  Vue.directive("v-bind", {
      //指令与元素成功绑定时(一上来)
      bind(element, binding) {
          element.value = binding.value;
      },
      //指令所在元素被插入页面时
      inserted(element, binding) {
          element.focus();
      },
      //指令所在的模板被重新解析时
      update(element, binding) {
          element.value = binding.value;
      },
  });

【五】vuex

#1 第三方插件:状态管理器--》管理状态--》管理变量的---》统一的位置管理变量--》实现组件间通信
	-vue2 :vuex
    -vue3:vuex,pinia:用的多
    
    
# 2 使用vuex 
	-创建项目时候,已经装了
    	-项目依赖有了
        -项目中有个 store文件夹-->index.js
        -main.js 中,引入且使用了
        
    -在创建项目时,没装
    	-安装:cnpm install vuex@3.6.2
        	 cnpm install element-ui@2.15.13 -S
        -在项目中新建 store--》index.js
        	-在index.js中写入代码
                import Vue from 'vue'
                import Vuex from 'vuex'
                Vue.use(Vuex)
                export default new Vuex.Store({
                  state: {
                  },
                  mutations: {
                  },
                  actions: {
                  }
                })
        在main.js中使用
        	import store from './store'
            new Vue({
                store,
                render: h => h(App)
            }).$mount('#app')

            
            
# 3 具体使用
记住一个思想,类似于去点餐,三种方式
1.自己直接炒
2.直接叫厨师炒commit("函数名",参数)
3.通过服务员点单,服务员叫厨师炒dispatch("函数名",参数)



# 4 作用和好处
	-1 降低代码耦合度
    -2 实现组件间通信

5.1具体使用

1.在store里的index.js
export default new Vuex.Store({
  //存原值
  state: {
    count:1
  },
  getters: {
    getCount(state) {
            return state.count + 100
        }
  },
  mutations: {
    //这里会自动传入state对象
    add(state){
     state.count++

    }
  },
  //服务员--》调commit
  actions: {
  //  ctx就是上下文,这里调用函数会自动传入一个上下文参数
    add(ctx){
      //通知厨师长炒菜
      ctx.commit('add')

    }
  },
  modules: {
  }
})

2.在组件中调用
stateclick(){
#方式一:直接改,容易出问题,没有校验之类的
this.$store.state.count++
#方式二: 叫厨师直接炒,直接调用commit方法
 this.$store.commit('add')
#方式三:一套流程
先告诉服务员dispatch--》他会自动调用commite叫厨师炒菜
  this.$store.dispatch('add')

}
调用getters-->this.$store.getters.getCount



# 3 为什么经过 actions和mutations 
    -可以跟后端交互,可以做数据验证

# 8 getters:
    	可以通过getters获取数据--》对state中的数据,再做处理
    
# 9 modules:
    	分到不同模块中,不同模块有自己的state,actions

【六】本地存储

# 1 能存储数据的位置,登录成功---》token存储
	vuex: 页面重新加载--》数据会恢复
	cookie:登录信息放这里,有过期时间,一旦过期,就没了
    sessionStorage:当前浏览器生效---》关闭浏览器,数据就没了
    localStorage:永久生效,除非代码删除或清空浏览器缓存
    	-未登录,加购物车
        
        
#2 cookie 需要下载 vue-cookies
cnpm install vue-cookies -S


#在main.js要声明一下插件
import cookies from 'vue-cookies'
Vue.prototype.$cookies=cookies
1.vuex-->炒菜也能存但是页面重新加载--》数据会还原

2.localStorage
    #存命令
    localStorage.setItem("user", JSON.stringify(user))--》注意这个必须是一个字符串
    #获取
    localStorage.getItem('user')
    #删
    localStorage.removeItem('name')
    localStorage.clear()

3.sessionStorage
    #存命令
    sessionStorage.setItem("name", '彭于晏')
    #获取
    sessionStorage.getItem('name')
    #删
    sessionStorage.removeItem('name')
    sessionStorage.clear()

2.cookie
    #存命令
    this.$cookies.set('name', 'zzzz', '100s')--》注意这里的过期时间必须是1d,1m,1s,这样如果写数字,它就变成session关了就没了
    #获取
    this.$cookies.get('name')
    #删
    this.$cookies.remove('name')

【七】vue-router

# 1 如果我们创建项目时,已经安装了
	-router--》index.js
    -main.js 引入了
    -后期在组件中:
    	-js中:
            this.$router # 跳转路径
            this.$route   # 目前没学
        -template中:
        	<router-view/>  # 当访问某个路径时,会把页面组件替换到这
            <router-link></router-link>

            
            
# 2 创建项目没有安装,自行引入
	-创建文件夹router---index.js
    -index.js写代码
    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import HomeView from "@/views/HomeView";
    Vue.use(VueRouter)
    const routes = [
        {
            path: '/',
            name: 'home',
            component: HomeView
        },

    ]
    const router = new VueRouter({
        mode: 'history',
        base: process.env.BASE_URL,
        routes
    })
    export default router
 -main.js中使用
        import router from './router'
        new Vue({
            router,
            render: h => h(App)
        }).$mount('#app')
        
   -后续所有组件中
	    -js中:
            this.$router # 跳转路径
            this.$route   # 目前没学
        -template中:
        	<router-view/>  # 当访问某个路径时,会把页面组件替换到这
            <router-link></router-link>

7.1 路由跳转

1.之前我们所知
<router-view/>通过路径切换组件
2.注册路径-->routes
    const routes = [
            {
                path: '/',
                name: 'home',
                component: HomeView
            },

        ]
"""这样做了以后访问某路径,就会切换到指定组件上"""

7.1.1路径跳转的方式(重点)

1.直接传路径
this.$router.push('/about')

2.可以传一个对象
this.$router.push({'path': '/about'})
this.$router.push({'name': 'about'})

3.携带参数跳转
this.$router.push('/about?name=lqz&age=19')
this.$router.push({'name': 'about',query:{name:'zhangsan',age:19}})
this.$router.push({'path': '/about',query:{name:'zhangsan',age:19}})

4.template中跳转:router-link组件--》类似导航栏
    4.1直接传路径
    <router-link to="/about">
               <button>点我跳转到about页面-router-link</button>
            </router-link>
    4.2传对象
    <router-link :to="{name:'about',query:{name:'xxx'}}">
           <button>点我跳转到about页面-router-link</button>
        </router-link>
        
        
        
5.取参数------------》重点
this.user1 = this.$route.query.参数名; 

"""#route与router的区别"""
console.log(this.$router) // VueRouter 的对象
console.log(this.$route)  // 当前路由对象


6."""若不是想之前的路由拼接,而是想之前的路径转换器一样/99/lqz"""
    6.1 路由写法变了
             {
                path: '/:pk/lqz',
                name: 'lqz',
                component: LQZView
            },
    6.2 传递数据
            -js:
                this.$router.push("/99/lqz")
                                this.$router.push({name:'lqz',params:{pk:666}})
    6.3router-link:
          <router-link to="/99/lqz">
    	  <router-link :to="{name:'lqz',params:{pk:666}}">---》注意这个to是一个属性变量了
            
  	6.4 另一个页面获取数据
	this.$route.params.指定名字
    this.$route.params.pk

7.2 相关api

1 指的是:this.$router--->方法
2 常用的
this.$router.push(path): 相当于点击路由链接(可以返回到当前路由界面)
this.$router.replace(path): 用新路由替换当前路由(不可以返回到当前路由界面)
this.$router.back(): 请求(返回)上一个记录路由
this.$router.go(-1): 请求(返回)上一个记录路由
this.$router.go(1): 请求下一个记录路由

7.3 多级路由

类似模板的block 把某些位置给固定,点击导航栏就只有中间变

"子路由的path路径前不能写/否则就会变成单独一个路径,就不是mul下的子路由了"

1.MulRouterView

<template>
  <div>

    <div style="height: 80px;background-color: pink"></div>


    <el-container>
      <el-aside width="200px">
        <div style="background-color:greenyellow;height:700px ">
          <p><router-link to="/mul/">首页</router-link></p>
          <p><router-link :to="{name:'order'}">订单</router-link></p>
          <p><router-link to="/mul/good">商品</router-link></p>
        </div>
      </el-aside>
      <el-container>
        <el-header>
          <div style="background-color:rebeccapurple"></div>
        </el-header>
        <el-main>
          <div style="height:500px;background-color: aqua">

            <router-view></router-view>



          </div>
        </el-main>
        <el-footer>
          <div style="background-color: pink;height:50px"></div>
        </el-footer>
      </el-container>
    </el-container>

  </div>
</template>

<script>
export default {
  name: "MulRouterView"
}
</script>

<style scoped>

</style>

2.路由

{
    path:'/mul',
    name:'mul',
    component: MulRouterView,
    children:[
      {
        path:'',
        name:'index',
        component: IndexView,
      },{
        path:'good',
        name:'good',
        component: GoodView,
      },{
        path:'order',
        name:'order',
        component: OrderView,
      },
    ]

  }

3 .IndexView.vue--->order和goods与这一样就改个h1里的字

<template>
<div>
  <h1>后台首页</h1>
</div>
</template>

<script>
export default {
  name: "IndexView"
}
</script>

<style scoped>

</style>

7.4路由守卫

# 1 路由守卫是什么
从名字可以得出就是守护路由看你有没有资格去访问

eg:你没登陆可以访问某页面,登录了可以访问某页面
    
# 2 全局守卫、独享守卫、组件内守卫

一般我们只用全局守卫
#1. to: 要去的路由对象
#2. from:来自哪个路由对象
#3. next:跳转到某个路径
#4. 要去的路径,如果不是/login或 /  就要判断有没有登录【登录后token保存到localStorage中了】
"""注意如果不是在vue文件中用相关的组件,那么要自己重新导入一下
import cookies from 'vue-cookies'
import Element from 'element-ui';
"""
router.beforeEach((to, from, next) => {
    if(to.name=='login' ||to.name=='register'){
        next()
    }else{
        console.log(cookies.get('token'))
        if(cookies.get('token')){
            next()
        }else{
            Element.Message.error('您没有登录,请先登录')
            this.router.push({name:'login'})
        }
    }
})

7.4路由的两种工作模式

# 1 对于一个url来说,什么是hash值?——      # 及其后面的内容就是hash值 

# 2 hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器。


# 3 hash模式:
    地址中永远带着#号,不美观 。
    若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
    兼容性较好
# 4 history模式:
    地址干净,美观 。
    兼容性和hash模式相比略差。
    应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题-->
因为后端服务器只有一个首页的地址,所以多了其他的路径就会报找不到路径404的错
    

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值