Vue-Router

Vue-Router

  • npm i vue-router --save (如果上线以后还需要使用该模块加 --dev)
  • 作用:实现单页面鞥带组件之间的跳转效果
  • 配置:
    • 创建独立的Router文件夹,并在文件夹下创建index文件
      • import Vue from ‘vue’
      • import Router from ‘vue-router’
      • Vue.use(Router) // 配置Vue - Router
      • const router = new Router({ 路由匹配规则代码 })
      • export defoult router
    • 在main.js文件中引入
      • import router from ‘路径’
import Vue from 'vue'
import Router from 'vue-router'
// 对应想要现实的页面
import A from '../components/A.vue'
import B from '../components/B.vue'
import C from '../components/C.vue'

Vue.use(Router)

const router = new Router({
  // 路由匹配规则代码
  routes: [
    {
      // 重定向:当什么都不输的时候,就会自动跳转到指定页面
      path: '/',
      redirect: '/a'
    },
    {
      // path后的
      path: '/a',
      component: A
    },
    {
      path: '/b',
      component: B
    },
    {
      path: '/c',
      component: C
    },
  ]
})

export default router

路由传参

  1. 在router、index.js文件的路由规则中指定参数名称:XXX

    {
        path:'/b/:myid'
        component:B
    }
    
  2. 在B.vue中获取XXX的值

    this.$route.params.XXX

  3. 在router-link标签上添加myid的实参

    <router-link to = '/b/112233'>跳转</router-link>
    

方法二(不常用)

  1. 在router-link标签上添加XXX的实参

    <router-link to = '/a?XXX=123'></router-link><router-link :to="{path:'/a' , query:{XXX:123}}"></router-link>
    
  2. 在A.vue中获取id的值

    this.$route.query.XXX
    

二级目录跳转

  • 注:如果一级目录上有参数,则需要传三层
const router = new Router({ 
routes: [
    {
      // 重定向:当什么都不输的时候,就会自动跳转到指定页面
      path: '/',
      redirect: '/a/:myid'
    },
    {
      path: '/a/:myid',
      component: A,
      // 二级菜单
      children: [
        {
          path: 'one_son',
          component: son1
        },
        {
          path: 'two_son',
          component: son2
        }
      ]
    },
  ] 
})    
  • 父页面包含跳转的子页面(因父页面含有参数,所以变成了三级目录)

    <router-link to="/a/123/one_son">儿子1</router-link>
    <router-link to="/a/123/two_son">儿子2</router-link>
    
  • 别名

    aliasL:‘名字’

编程式导航

  1. push()能够保留历史记录的跳转
    1. this.$router.push(’/a/123’)
    2. this.$router.push({path:’/a’})
    3. this.$router.push({name:‘A’,params:{id:123}})
  2. replace()不保留历史记录的跳转(无法回退)
    1. this.$router.replace(‘参数与push一样的’)
  3. go()基于有历史记录的情况进行跳转
    1. this.$router.go(X) 前进X页
    2. this.$router.go(-X) 后退X页

命名视图

场景:一个页面中需要同时显示多个子组件,也就是说一个path多个组件

用法:假设给B组件里添加多个二级路由的命名视图

组件间信息传递

一个组件既要接收来自父组件的数据Props,又想要接受来自路由的数据Params

  1. 传递数据

    <router-link :to="{ name:'C', params: { ids: 123 } }" active-class=" myLink">跳转C</router-link>
    
  2. 在router/index.js文件中给C组件添加props属性

        {
          path: '/c/:ids',
          component: C,
          name:'C',
          props: true
        },
    
  3. 在C组件中可以直接用Props来就收参数了

    export default {
      props:['ids']
    }
    

路由的模式(面试题)

Hase模式:地址栏始终有一个#,原理是锚链接【默认】

History模式:原理是H5的history机制,没有#,优点:利于SEO,缺点:服务器必须配置对应路径

  • 例如:’/a/menu’会被服务端拦截到,当作服务端的URL地址,于是返回404
  • 例如:’/#/a/ment’不会被服务端拦截
new Router({
    model:history
})

路由懒加载(面试题)

含义:当我们访问这个地址的时候,采取加载这个对应的组件,不访问也就不加载了

语法
{
    path:'list',
        component:()=>import('路径')
}

路由守卫

路由跳转前做一些验证,比如登陆验证,也是网站的普遍要求

全局守卫:routes/index.js里
const router = new Router({......})

// 路由前置首位
router.afterEach((to,from,next)=>{
	console.log(`从哪来:${to.path}`)
	console.log(`到哪去:${from.path}`)
	next();	// 执行下一个钩子
	next(false);	// 中断
	next('/XXX');	// 跳转到
})

// 路由后置守卫
router.afterEach((to,from)=>{
  console.log(`从哪来${to.path}`);
  console.log(`到哪去${from.path}`);
})
路由独享守卫:routes/index.js里
{
  path:'/c/:title',
  component:C,
  beforeEnter(to,from,next){
    console.log('---C组件的路由独享守卫---');
    console.log("从哪儿来:",from.path)
    console.log("去哪儿:",to.path)
    next();
  }
}
组件内部守卫:写在C.vue文件中
export default {
  name:'C',
  beforeRouteEnter(to,from,next){
    console.log('---C组件内部守卫:渲染当前组件时触发---')
    next();
  },
  beforeRouteUpdate(to,from,next){
    console.log('---C组件内部守卫:参数更新时触发---')
    next();
  },
  beforeRouteLeave(to,from,next){
    console.log('---C组件内部守卫:离开当前组件时触发---')
    next();
  }
}

配置原信息

  1. 配置原信息

    const router = new Router({
        routes:[
            {
                path: '/a/:myid',
                component: A,
                meta: {
                    title: '首页',
                    keepalive: true
                },
            }
        ]
    })
    
  2. 在路由守卫中动态修改网页的标题

    // 路由前置守卫
    router.beforeEach((to, from, next) => {
      document.title = to.meta.title
      next()
    })
    
  3. 给router-view添加是否缓存

    <keep-alive v-if='$router.meta.keepAlive'>
    	<router-view></router-view>
    </keep-alive>
    <router-view v-else></router-view>
    

常见问题

  1. 不允许跳转到自身路径上,通过catch消除这个历史遗留BUG

    答:this.$router.replace(url).catch(err => err)

  2. 如果img的src是动态加载的如何渲染?

    需要使用requery进行动态导入才可以,例如:<img :src=‘requery(xxx.jpg)’

  3. 编程导航中不允许重复跳转到同一个路径上,会报错?

    通过catch消除这个历史遗留bug: this.$router.replace(url).catch(err=>err)

Vuex

Vuex是一个专为Vue.js应用程序开发的状态管理模式。

含义:集中式的数据管理仓库

场景:数据共享的时候,比如:登录状态,个人信息,账号信息

Vuex的四大核心模块

state:状态【存储数据的地方】

getters:查询【查询数据的函数】

mutations:修改数据【修改数据的唯一途径】

action:业务处理【和mutations最大的区别在于action可以写异步代码】

关于Vuex的使用

  1. 安装Vuex

    1. npm i vuex --save
      
  2. 在src下建一个store文件夹,并创建入口文件index.js

    1. import Vue from 'vue'
      import Vuex from 'vuex'
      
      Vue.use(Vuex)
      
      export default new Vuex.Store
      
    2. 在main.js中引入

      import store from './store/import'
      
      Vue.config.productionTip = false
      
      new Vue({
        store,
        render: h => h(App),
      }).$mount('#app')
      
      
  3. 使用

    export default new Vuex.Store({
      state: {
        eat: ['橘子', '香蕉', '苹果']
      },
      getters: {
        getEat(state) {
          return state.eat
        }
      },
      mutations: {},
      actions: {}
    })
    
    <template>
      <div>
        <p v-for="(value, index) in cat" :key="index">{{ value }}</p>
      </div>
    </template>
    
    <script>
    export default {
      computed: {
        cat() {
          return this.$store.getters.getEat;
        },
      },
    };
    </script>
    
  4. 添加/修改

    export default new Vuex.Store({
      state: {
        eat: ['橘子', '香蕉', '苹果']
      },
      getters: {
        getEat(state) {
          return state.eat
        }
      },
      mutations: {
        addEat(state,product){
          state.eat.push(product)
        }
      },
      actions: {}
    })
    
    <template>
      <div>
        <input type="text" v-model="my_text" />
        <button @click="gogo">添加</button>
      </div>
    </template>
    
    <script>
    export default {
      name: "add",
      data() {
        return {
          my_text: "",
        };
      },
      methods: {
        gogo() {
          this.$store.commit('addEat', this.my_text);
        },
      },
    };
    </script>
    
  5. 异步修改

    在显示页面写入
    <script>
    export default {
      computed: {
        cat() {
          return this.$store.getters.getEat;
        },
      },
      mounted() {
        // 1. 调用store/import.js的actions的loadEat方法
        this.$store.dispatch("loadEat");
      },
    };
    </script>
    
    在js文件中 
      mutations: {
        addEat(state, product) {
          state.eat.push(product)
        },
        setEat(state, list) {
          // 4. 赋值
          state.eat = list
        }
      },
      actions: {
        loadEat(context) {
          setTimeout(() => {
            // 2. 异步获取数据
            var res = ['橘子', '香蕉', '苹果']
            // 3. 调用mutations的setEat方法传参
            context.commit('setEat', res)
          }, 2000)
        }
      }
    })
    

辅助函数

  原始写法
  computed: {
    cat() {
      return this.$store.getters.getEat;
    },
  },
辅助函数写法 -- 从State里面获取
import { mapState } from "vuex";
  computed: mapState({
    cat: "eat",
  }),
辅助函数写法 -- 从Getters里面获取
import { mapGetters } from "vuex";
computed: mapGetters({
// cat定义计算属性的名字,getEat:store仓库Getters的函数名
cat: "getEat",
}),
以下是使用C#实现在一台电脑上多个程序之间通过TCP/IP传递数据的代码示例: Server端代码: ```csharp using System; using System.Net; using System.Net.Sockets; using System.Text; class Program { static void Main(string[] args) { // 本地IP地址和端口号 IPAddress localAddress = IPAddress.Parse("127.0.0.1"); int port = 12345; // 创建TCP监听器 TcpListener server = new TcpListener(localAddress, port); // 开始监听 server.Start(); Console.WriteLine("Server started."); while (true) { // 等待客户端连接 TcpClient client = server.AcceptTcpClient(); Console.WriteLine("Client connected."); // 获取客户端的网络流 NetworkStream stream = client.GetStream(); // 读取客户端发送的数据 byte[] buffer = new byte[1024]; int length = stream.Read(buffer, 0, buffer.Length); string message = Encoding.Unicode.GetString(buffer, 0, length); Console.WriteLine("Received message: " + message); // 发送响应数据给客户端 string response = "Hello from server!"; byte[] responseBuffer = Encoding.Unicode.GetBytes(response); stream.Write(responseBuffer, 0, responseBuffer.Length); // 关闭连接 client.Close(); Console.WriteLine("Client disconnected."); } } } ``` Client端代码: ```csharp using System; using System.Net; using System.Net.Sockets; using System.Text; class Program { static void Main(string[] args) { // 本地IP地址和端口号 IPAddress localAddress = IPAddress.Parse("127.0.0.1"); int port = 12345; // 创建TCP客户端 TcpClient client = new TcpClient(); // 连接服务器 client.Connect(localAddress, port); Console.WriteLine("Connected to server."); // 获取网络流 NetworkStream stream = client.GetStream(); // 发送数据给服务器 string message = "Hello from client!"; byte[] buffer = Encoding.Unicode.GetBytes(message); stream.Write(buffer, 0, buffer.Length); // 读取服务器响应数据 buffer = new byte[1024]; int length = stream.Read(buffer, 0, buffer.Length); string response = Encoding.Unicode.GetString(buffer, 0, length); Console.WriteLine("Received message: " + response); // 关闭连接 client.Close(); Console.WriteLine("Disconnected from server."); } } ``` 在运行程序之前,需要确保本地IP地址和端口号与代码中的相同。运行Server端代码后,再运行Client端代码即可看到客户端发送数据并接收到服务器的响应。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值