Yew

Yew is a modern Rust framework for creating multi-threaded front-end Web applications using WebAssembly.

Create the initial project

Use Cargo to create a project named Router:

cargo new router
cd router
Copy the code

Add a dependency to Cargo. Toml:

[dependencies] yew-router = "dependencies"Copy the code

Add the following initial code to SRC /main.rs:

use yew::{html, Component, ComponentLink, Html, ShouldRender};

pub enum Msg{}pub struct Router {
    link: ComponentLink<Self>,}impl Component for Router {
    type Message = Msg;
    type Properties = ();

    fn create(_props: Self::Properties, link: ComponentLink<Self- > >)Self {
        Self { link }
    }

    fn update(&mut self, msg: Self::Message) -> ShouldRender {
        true
    }

    fn change(&mut self, _props: Self::Properties) -> ShouldRender {
        false
    }

    fn view(&self) -> Html { html! {"Hello,world!"}}}fn main() {
    yew::start_app::<Router>();
}
Copy the code

Running Trunk Serve and opening the website displays the following:

Hello,world!

The following is quoted in mian. Rs:

use yew_router::prelude::*;
use yew_router::service::RouteService;
use yew_router::Switch;
Copy the code

Then add the routing structure:

#[derive(Switch, Clone)]
enum AppRoute {
    // Match url/bedroom for all paths
    #[to = "/#/bedroom"]
    // Matches all paths of the current URL /
    Bedroom(usize),
    #[to = "/"]
    Home,
}
Copy the code

The implementation generated by the derived macro of Switch will try to match each variable in the order from the first to the last, so if any route could match two specified annotations, the first will match and the second will never be tried.

That is, if Home (/) is before Bedroom (/ Bedroom), Bedroom will not be matched.

Routes can be subject to user changes (from the browser) as well as application changes. Routing change messages can be received or sent for updates.

First, save the route:

pub struct Router {
    link: ComponentLink<Self>,
    // Used to set the route
    route_service: RouteService<()>,
    // Current route
    route: Route<()>,
    // Routing proxy
    router_agent: Box<dyn Bridge<RouteAgent>>,
}
Copy the code

Set route change message:

pub enum Msg {
    ChangeRoute(Route<()>)
}
Copy the code

The message is sent in the callback of the browser routing change:

fn create(_props: Self::Properties, link: ComponentLink<Self- > >)Self {
    // Handle routing
    let route_service = RouteService::new();
    Self { 
        link, 
        route_service:route_service,
        // The current path has
        route:route_service.get_route(),
        // Send a message when the user (browser) changes the route
        router_agent:RouteAgent::bridge(link.callback(Msg::ChangeRoute))
     }
}
Copy the code

Processing routing change messages:

fn update(&mut self, msg: Self::Message) -> ShouldRender {
    match msg {
        Msg::ChangeRoute(route) => {
            self.route_service.replace_route(&route, ());
            self.route = route;
            ConsoleService::log("RouteChanged"); }}true
}
Copy the code

Run Trunk Serve and change the route, you’ll see “RouteChanged” in the console

http://127.0.0.1:8080/#/test

Note that a page refresh will not be triggered if the route is changed!

Next, match each route to determine the specific content of the page:

fn view(&self) -> Html { html! {match AppRoute::switch(self.route.clone()) {
            Some(AppRoute::Bedroom)=> {"This is the bedroom."},
            Some(AppRoute::Home)=> {"This is home."},
            None= > {"Not theoretically..."}}}}Copy the code

Run, and then view

http://127.0.0.1:8080 或者 http://127.0.0.1:8080/#/

http://127.0.0.1:8080/#/bedroom

You can also match messages:

#[derive(Switch, Clone)]
enum AppRoute {
    #[to = "/#/bedroom"]
    Bedroom,
    #[to = "/#/say:{}"]
    Say(String),
    #[to = "/"]
    Home,
}
/ *... * /
fn view(&self) -> Html {
    let temp;
    html! {
        match AppRoute::switch(self.route.clone()) {
            Some(AppRoute::Bedroom)=> {"This is the bedroom."},
            Some(AppRoute::Say(s))=>{
                temp = s;
                &temp
            },
            Some(AppRoute::Home)=> {"This is home."},
            None= > {"Not theoretically..."}}}}Copy the code

test

http://127.0.0.1:8080/#/say:Hello, the world!