【在线OJ】01-Vue前端项目创建与页面开发

发布于:2024-05-05 ⋅ 阅读:(34) ⋅ 点赞:(0)

目录

一、项目展示

二、项目创建

三、Vue语法

安装

基础请求

token

携带参数

配置中携带参数

请求体携带参数(默认json)

请求体携带参数(不使用json)

multipart格式(上传头像可)

代码

if-else

代码

for

代码

创建组件

导入组件

使用组件

代码

子组件

父组件

四、Element-UI

静态页面

事件绑定

代码

五、Router

六、VueX

七、开发


一、项目展示

二、项目创建

创建文件夹使用VsCode打开后,新建终端输入以下命令

打开UI创建项目

npm install -g @vue/cli # 安装vue
vue -ui # 在浏览器创建项目

UI创建步骤

配置端口与代理

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port: 9898,
    proxy: {
      '/api': {
        target: "http://localhost:9897",
        changeOrigin: true
      }
    }
  }
})

三、Vue语法

文本插值

<template>
  <div id="app">
    {{problems[0].id + problems[1].id}} {{problems[0].title}} {{problems[0].level}}
    {{problems[0].level === "easy" ? "easy" : "other"}}
  </div>
</template>

<script>
  const options = {
    data: function () {
      return {
        problems: [
          {id: 1, title: "两数之和1", level: "easy"},
          {id: 2, title: "两数之和2", level: "easy"},
          {id: 3, title: "两数之和3", level: "easy"}
        ]
      };
    }
  };
  export default options;
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

属性绑定

<template>
  <div id="app">
    <input type="text" v-bind:value="name">
    <input type="text" :value="name">
  </div>
</template>

<script>
  const options = {
    data: function () {
      return {
        name: "王五"
      };
    }
  };
  export default options;
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

事件绑定

<template>
  <div id="app">
    <input type="button" v-bind:value="msg" v-on:click="login">
      <input type="button" v-bind:value="msg" @click="login">
      </div>
</template>

<script>
  const options = {
    data: function () {
      return {
        msg: "点我"
      };
    },
    methods: {
      login: function () {
        alert(options.data().msg)
      }
    }
  };
  export default options;
</script>

<style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
</style>

案例加法器实现

<template>
  <div id="app">
    <input type="button" v-bind:value="addMessage" v-on:click="add">
      {{cnt}}
      <input type="button" v-bind:value="subMessage" @:click="sub">
      </div>
</template>

<script>
  const options = {
    data: function () {
      return {
        addMessage: "点我+1",
        subMessage: "点我-1",
        cnt: 1
      };
    },
    methods: {
      sub: function () {
        this.cnt = this.cnt - 1;
        alert(this.cnt);
      },

      add: function () {
        this.cnt = this.cnt + 1;
        alert(this.cnt);
      }
    }
  };
  export default options;
</script>

<style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
</style>

双向绑定

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

<script>
  const options = {
    data: function () {
      return {
        name: "王五"
      };
    },
    methods: {
    }
  };
  export default options;
</script>

<style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
</style>

axios

安装

npm install axios -S

基础请求

token

携带参数

配置中携带参数

请求体携带参数(默认json)

请求体携带参数(不使用json)

multipart格式(上传头像可)

代码
<template>
  <div id="app">
      <input type="button" value="简单get" @click="login">
    <input type="button" value="token" @click="token">
    <input type="button" value="查询字符串带参数" @click="params">
    <input type="button" value="配置携带参数" @click="configParams">
    <input type="button" value="请求体中的json格式" @click="bodyParams">
    <input type="button" value="请求体中的非json格式" @click="bodyParamsNoJson">
    <input type="button" value="使用multipart格式" @click="multipartParams">
    <input type="button" value="封装axios" @click="getAxios">
  </div>
</template>

<script>
import axios from "axios";
  const options = {
    data: function () {
      return {

      };
    },

    methods: {
      // 简单get
      login: async function () {
        const resp = await axios.get("http://localhost:8288/test/compile");
        alert(resp.data.data);
        localStorage.setItem("token", resp.data.data)
      },

      // 携带token
      token: async function () {
        const resp = await axios.post("http://localhost:8288/test/token", {}, {
          headers: {
            "token": localStorage.getItem("token")
          }
        })
        alert(resp.data.data);
      },

      // 携带参数在查询字符串中
      params: async function () {
        const name = encodeURIComponent("张三")
        const age = 12
        const resp = await axios.post(`http://localhost:8288/test/params?name=${name}&age=${age}`, {}, {})
        alert(resp.data.data);
      },

      // 携带参数在配置中
      configParams: async function () {
        const name = "张三"
        const age = 12
        const resp = await axios.post(`http://localhost:8288/test/params`, {}, {
          params:{
            name: name,
            age: age
          }
        })
        alert(resp.data.data);
      },

      // 请求体中传参,参数默认是json格式
      bodyParams: async function () {
        const name = "张三"
        const age = 12
        const resp = await axios.post(`http://localhost:8288/test/params`, {
          name: name,
          age: age
        }, {})
        alert(resp.data.data);
      },

      // 请求体中传参,不用json
      bodyParamsNoJson: async function () {
        const params = new URLSearchParams()
        params.append("name", "往往")
        params.append("age", 28)
        const resp = await axios.post(`http://localhost:8288/test/params`, params, {})
        alert(resp.data.data);
      },

      // 使用multipart格式---上传头像
      multipartParams: async function () {
        const params = new FormData()
        params.append("name", "lisi")
        params.append("age", 11)
        const resp = await axios.post(`http://localhost:8288/test/params`, params, {})
        alert(resp.data.data);
      },

      // 封装axios--不可用
      getAxios: async function () {
        const _axios = axios.create({
          baseURL: "http://localhost:8288",
          withCredentials: true,   // 允许携带token
        })
        const params = new URLSearchParams()
        params.append("name", "往往")
        params.append("age", 28)
        const resp = await _axios.post(`/test/paramsToken`, params, {
          headers: {
            "token":"111"
          }
        })
        alert(resp.data.data);
      },
    },

    computed: {

    }
  };
  export default options;
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

响应数据

条件渲染

if-else

代码
<template>
  <div id="app">
    <div v-if="problems.length > 0">显示数据</div>
    <div v-else>不显示</div>
  </div>
</template>

<script>
const options = {
  data: function () {
    return {
      problems: [
        {id: 1, title: "A+B1", level: "easy"},
        {id: 2, title: "A+B2", level: "easy"},
        {id: 3, title: "A+B3", level: "easy"},
        {id: 4, title: "A+B4", level: "easy"},
      ]
    };
  },

  methods: {

  },

  computed: {

  }
};
export default options;
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

列表渲染

for

代码
<template>
  <div id="app">
    <div v-if="problems.length > 0">
      <div class="row" v-for="problem of problems" :key="problem.id">
        <span>{{problem.id}} </span>
        <span>{{problem.title}} </span>
        <span>{{problem.level}} </span>
      </div>
    </div>
    <div v-else>不显示</div>
  </div>
</template>

<script>
const options = {
  data: function () {
    return {
      problems: [
        {id: 1, title: "A+B1", level: "easy"},
        {id: 2, title: "A+B2", level: "easy"},
        {id: 3, title: "A+B3", level: "easy"},
        {id: 4, title: "A+B4", level: "easy"},
      ]
    };
  },

  methods: {

  },

  computed: {

  }
};
export default options;
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

页面加载就执行方法

组件复用

创建组件

导入组件

使用组件

代码
<template>
  <div id="app">
    <my-button></my-button>
  </div>
</template>

<script>
  import MyButton from '@/components/ExamplyView.vue'
  const options = {
    data: function () {
      return {

      };
    },

    components: {
      MyButton,
    },

    mounted() {  // 组件加载就执行

    },

    methods: {

    },

    computed: {

    }
  };
  export default options;
</script>

<style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
</style>

组件插槽

自定义化组件

类似于参数传参

子组件

父组件

四、Element-UI

安装ElementUI

npm install element-ui -S

引入ElementUI

import Vue from 'vue'
  import App from './App.vue'
  import router from './router'
  import store from './store'
  import Element from 'element-ui'
  import 'element-ui/lib/theme-chalk/index.css'

  Vue.use(Element)
  Vue.config.productionTip = false

  new Vue({
  router,
  store,
  render: h => h(App)
    }).$mount('#app')

表格

<template>
  <div id="app">
    <el-table :data="problems">
      <el-table-column label="序号" prop="id"></el-table-column>
      <el-table-column label="题目" prop="title"></el-table-column>
      <el-table-column label="难点" prop="level"></el-table-column>
    </el-table>
  </div>
</template>

<script>
  import MyButton from '@/components/ExamplyView.vue'
  const options = {
    data: function () {
      return {
        problems: [
          {id: 1, title: "A+B1", level: "easy"},
          {id: 2, title: "A+B2", level: "easy"},
          {id: 3, title: "A+B3", level: "easy"},
          {id: 4, title: "A+B4", level: "easy"},
        ]
      };
    },

    components: {
      MyButton,
    },

    mounted() {  // 组件加载就执行

    },

    methods: {

    },

    computed: {

    }
  };
  export default options;
</script>

<style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
</style>

分页

静态页面

事件绑定

代码
<template>
  <div id="app">
    <el-table :data="problems">
      <el-table-column label="序号" prop="id"></el-table-column>
      <el-table-column label="题目" prop="title"></el-table-column>
      <el-table-column label="难点" prop="level"></el-table-column>
    </el-table>
    <el-pagination
      :total="problems.length"
      :page-size="pageSize"
      :current-page="currentPage"
      layout="prev, pager, sizes, next, ->, total"
      :page-sizes="pageSizes"
      @current-change="currentChange"
      @size-change="sizeChange">
    </el-pagination>
  </div>
</template>

<script>
  import MyButton from '@/components/ExamplyView.vue'
  const options = {
    data: function () {
      return {
        problems: [
          {id: 1, title: "A+B1", level: "easy"},
          {id: 2, title: "A+B2", level: "easy"},
          {id: 3, title: "A+B3", level: "easy"},
          {id: 4, title: "A+B4", level: "easy"},
          {id: 5, title: "A+B4", level: "easy"},
          {id: 6, title: "A+B4", level: "easy"},
          {id: 7, title: "A+B4", level: "easy"},
        ],
        pageSize: 2,
        currentPage: 1,
        pageSizes: [2, 4]
      };
    },

    components: {
      MyButton,
    },

    mounted() {  // 组件加载就执行

    },

    methods: {
      currentChange: function (page) {
        // 页面改变 发起请求获取分页数据
        this.currentPage = page;
        alert(page + ":" + this.pageSize)
      },
      sizeChange: function(size) {
        // 页面展示数据条数改变 发起请求获取数据
        this.pageSize = size;
        alert(this.currentPage + ":" + size)
      }
    },

    computed: {

    }
  };
  export default options;
</script>

<style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
</style>

表格+分页+搜索小demo

<template>
  <div id="app">
    <el-input size="mini" placeholder="请输入题目" style="width: 300px;" v-model="queryVo.title" clearable></el-input>
    <el-select placeholder="选择题号" size="mini" style="margin-left: 20px" v-model="queryVo.ids" clearable>
      <div v-for="problem in problems" :key="problem.id">
        <el-option :value="problem.id"></el-option>
      </div>
    </el-select>
    <el-button size="mini" type="primary" style="margin-left: 20px" @click="query">提交</el-button>
    <el-divider></el-divider>
    <el-table :data="problems">
      <el-table-column label="序号" prop="id"></el-table-column>
      <el-table-column label="题目" prop="title"></el-table-column>
      <el-table-column label="难点" prop="level"></el-table-column>
    </el-table>
    <el-pagination
      :total="problems.length"
      :page-size="pageSize"
      :current-page="currentPage"
      layout="prev, pager, sizes, next, ->, total"
      :page-sizes="pageSizes"
      @current-change="currentChange"
      @size-change="sizeChange">
    </el-pagination>
  </div>
</template>

<script>
  import MyButton from '@/components/ExamplyView.vue'
  const options = {
    data: function () {
      return {
        queryVo: {
          title: "",
          ids: []
        },
        problems: [
          {id: 1, title: "A+B1", level: "easy"},
          {id: 2, title: "A+B2", level: "easy"},
          {id: 3, title: "A+B3", level: "easy"},
          {id: 4, title: "A+B4", level: "easy"},
          {id: 5, title: "A+B4", level: "easy"},
          {id: 6, title: "A+B4", level: "easy"},
          {id: 7, title: "A+B4", level: "easy"},
        ],
        pageSize: 2,
        currentPage: 1,
        pageSizes: [2, 4]
      };
    },

    components: {
      MyButton,
    },

    mounted() {  // 组件加载就执行

    },

    methods: {
      currentChange: function (page) {
        // 页面改变 发起请求获取分页数据
        this.currentPage = page;
        alert(page + ":" + this.pageSize)
      },
      sizeChange: function(size) {
        // 页面展示数据条数改变 发起请求获取数据
        this.pageSize = size;
        alert(this.currentPage + ":" + size)
      },
      query: function () {
        // 根据条件进行查询
        alert(this.queryVo.title + ":" + this.queryVo.ids)
      }
    },

    computed: {

    }
  };
  export default options;
</script>

<style>
  .input1 {
    width: 50px;
  }

  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
</style>

级联选择器

五、Router

路由配置

路由跳转

<router-link to="target"></router-link> // 页面
this.$router.push(url)  // js

导航栏案例

六、VueX

vuex

没用到

七、开发


网站公告

今日签到

点亮在社区的每一天
去签到