国际化商城站点开发陌生点记录

1、中英文语言切换

1.1 定义多语言json文件

1.2 在main.js中引入

import { createApp } from 'vue'
import App from './App.vue'
import { createI18n } from 'vue-i18n';
import en from './locals/en.js';
import zh from './locals/zh.js';
// 组合语言包对象
const messages = {
  en,
  zh
}
// 创建i18n实例
const i18n = createI18n({
  legacy: false,  // 启用 composition API 模式
  messages,
  locale: navigator.language === 'zh-CN' ? 'zh' : 'en',
})

const app = createApp(App)
app.use(i18n)

1.3 在vue组件中使用

<template>
<div class="header-right">
      <el-dropdown>
        <span class="el-dropdown-link">
          <!-- 在模板使用多语言变量需要使用 $t() 包裹-->
          {{ $t("Head.switch") }}&nbsp;&nbsp;&nbsp;
        </span>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item @click="changeLocale('zh')"> 中 文 </el-dropdown-item>
            <el-dropdown-item @click="changeLocale('en')">English</el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
    </div>
</template>

import { useI18n } from "vue-i18n";
const { t, locale } = useI18n(); //t表示翻译函数,locale表示当前语言值
// 切换语言
const changeLocale = (lang) => {
   locale.value = lang;
};
//在js中定义多语言变量,需要用 t() 包裹
const buttons = computed(() => {
      return [
        { type: "info", category: 1, text: t('Head.category.device') },
        { type: "info", category: 2, text: t('Head.category.food') },
        { type: "info", category: 3, text: t('Head.category.decoration') },
        ...
      ];
    })

2、pinia简单使用

3、按关键词和类别搜索

3.1 前端

<template>
<Box>
      <div class="operate">
        <el-col :span="4">
          <el-button type="primary" @click="batchHandling">批量处理</el-button></el-col>
        <el-col :span="6">
          <div class="checkbox-group">
            <!-- '待处理': 0,'已处理': 1 -->
            <el-checkbox-group v-model="handleType">
              <el-checkbox label="已处理" name="type" />
              <el-checkbox label="待处理" name="type" />
            </el-checkbox-group>
          </div>
        </el-col>
        <el-col :span="6">
          <el-input placeholder="输入反馈关键词" v-model="keyword" @keyup.enter="searchFeedback" /></el-col>
        <el-button type="primary" @click="searchFeedback">
          搜索</el-button>
      </div>
    </Box>
</template>

<script>
export default {
data(){
   return{handleType: ['待处理'],}
}
computed: {
    tansformHandleType() {
      const mapping = {
        '待处理': 0,
        '已处理': 1
      };
      return this.handleType.map(item => mapping[item])
    }
  },

methods:{
    searchFeedback() {
      this.loading = true;
      const param = {
        keyword: this.keyword,
        handleType: this.tansformHandleType
      }
      service.post("/user/feedback/search", param).then((response) => {
        this.feedbacks = response;
        this.loading = false;
      }).catch(() => {
        this.loading = false;
        this.$message({
          type: 'error',
          message: '搜索出错'
        });
      });
    },
 }
}

3.2 后端

    public List<UserFeedback> searchFeedback(String keyword, List<Integer> handleType) {
        System.out.println("keyword:" + keyword);
        System.out.println("handleType:" + handleType);
        List<UserFeedback> resFeedback = new ArrayList<>();
        if (handleType != null && !handleType.isEmpty()) {
            for (Integer type : handleType) {
                resFeedback.addAll(userMapper.searchFeedback(keyword, type));
            }
        } else {
            // 如果处理类型列表为空,则只根据关键字进行搜索
            resFeedback = userMapper.searchFeedback(keyword, null);
        }
        return resFeedback;
    }

//----------------------
Mapper.xml
 <select id="searchFeedback" resultType="com.example.mall.entity.UserFeedback">
        SELECT *
        FROM feedback
        <if test="keyword != null and keyword != ''">
            WHERE feedback LIKE CONCAT('%', #{keyword}, '%')
            <if test="type != null">
                AND status = #{type}
            </if>
        </if>
        <if test="keyword == null or keyword == ''">
            <if test="type != null">
                WHERE status = #{type}
            </if>
        </if>
    </select>

4、子传父组件通信

子传父

充值余额组件(子组件),向信息组件(父组件)传递充值的金额

import { defineEmits } from 'vue';
const emit = defineEmits(['updateAmount'])
let recharge = {
    id: localStorage.getItem("userid"),
    amount: selectedAmount.value || customAmount.value //选择金额或者输入金额
 }
service.post("/user/recharge", recharge).then(res => {
    if (res.data == 1) {
        ElMessage.success(`充值成功¥${recharge.amount}`);
        // 父传子更新数据
        emit('updateAmount', recharge.amount)
    }
})

信息组件(父组件),接收来自子组件的 金额 信息

<el-dialog style="width: 500px" v-model="showRecharge">
    <!-- 子传父自定义事件对应的函数不加参数!!! -->
    <Recharge @updateAmount="handleAmount"></Recharge>
</el-dialog>

//通过自定义updateAmount事件触发handleAmount 
const handleAmount = (amount) => {
  console.log(amount)
  profile.balance += amount;
  showRecharge.value = false;
};

子父通信

<el-dialog style="width: 500px" v-model="showUpdate">
    <!-- 父传子直接绑定值即可 -->
    <updateInfo :info="profile" @updateData="handleUpdateInfo"></updateInfo>
  </el-dialog>

const handleUpdateInfo = (data) => {
  profile.username = data.username;
  profile.address = data.address;
  profile.balance = data.balance;
  profile.password = data.password;
  profile.phone = data.phone;
  showUpdate.value = false;
};
const emit = defineEmits(['updateData'])
const { info } = defineProps(['info']);
//潘顿原始值和修改值是否相同
const modified = Object.keys(originalUser).some(key => originalUser[key] !== user.value[key]);
if (!modified) {
    return; // 不提交数据
}
//如果修改了密码,则hash  未修改则使用原密码的hash
if (user.value.password == '') {
    user.value.password = info.password;
} else {
    user.value.password = md5(user.value.password);
}
const response = await service.post(`/user/update/${user.value.user_id}`, user.value);
// 更新成功,传递给父组件
if (response.data === "ok") {
    service.get(`/user/id=${localStorage.getItem("userid")}`)
    .then((res) => {
         emit('updateData', res.data);
         ElMessage.success("修改成功")
         //改了密码则跳转到登录页
         if (user.value.password != info.password) {
               router.push("/login")
         }})
    .catch((e) => {
         ElMessage.error("修改失败")
     })
}

5、对ref reactive的误会

以前只觉得ref处理简单的,reactive处理复杂的;突发奇想用reactive去包裹一个字符串

<input type="text" v-model="a">{{ a }}

let a = reactive("111")
onMounted(() => {
    console.log(1, a)
    a = "222"
    console.log(2, a)
}
    

如下所示,并非响应式,必须嵌套在对象属性里才可以是响应式

ref 可以处理任意类型的值,包括对象。但是ref处理复杂对象需要用.value去访问,略显复杂。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值