在 VueJS 中将我的组件从 Javascript 重构到 Typescript 时迷失了方向



我对 VueJS 相当陌生。 我的问题是使用打字稿将我的 vuejs 项目转换为 vuejs。我已经在javascript中查看了将函数绑定到某些变量,但是我对在打字稿中执行此操作感到迷茫。下面是我的javascript代码,然后我尝试将其重构为打字稿。开发人员工具中没有显示错误,但是 vuejs 的 route.query 根本没有改变。

我正在尝试做的是创建一个类似于自动搜索的组件。我很肯定我在打字稿中使用 lodash 的方式是不正确的,但也许我的整个代码都是不正确的。下面只是一个组件,但还有另一个组件是 CharacterCard,它也监视 router.query 上的事件更改,并根据用户查询向服务器发出获取请求。另外,是否有更好的方法可以处理此方法或更好的方法?

如果您需要更多详细信息,请告诉我。

<script>
import CharacterService from '../../services/characterService'
import CharacterCard from '../../components/_shared/CharacterCard.vue'
import Lodash from 'lodash'
export default {
components: {
CharacterCard
},
data () {
return {
dialog: false,
search: ''
}
},
methods: {
dialogAndSearchReset () {
this.search = ''
this.dialog = false
}
},
watch: {
// debounce of 700ms
search: Lodash.debounce(async function (value) {
// for route query
let route:any = {}
route = {
name: 'characters'
}
if (this.search !== '') {
route.query = {
search: this.search
}
}
// || this.$route.name === 'character'
if (this.$route.name === 'characters') {
this.$router.push(route)
}
}, 700),
'$route.query.search': {
immediate: true,
handler (value) {
this.search = value
}
},
$route (to, from) {
if (this.dialog === true && this.$route.name === 'character') {
this.dialogAndSearchReset()
}
}
}
}
</script>

我的尝试:

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import CharacterSearchCard from './CharacterSearchCard.vue';
import _ from 'lodash';
@Component({
components: {
charactersearchcard: CharacterSearchCard,
},
})
export default class QuickSearch extends Vue {
// model for Dialog example
public customDialogModel: boolean = false;
public search: string = '';
// public quickSearch: any = this.$route.query.search || null; // the url search query
@Watch('search')
public searchCharacter(value: any) {
_.debounce(async () => {
// for route query
let route: any = {};
route = {
name: 'characters',
};
if (value !== '') {
route.query = {
search: value,
};
}
if (this.$route.name === 'characters') {
this.$router.push(route);
}
}, 700);
}
@Watch('$route.query.search', { immediate: true })
public searchHandler(value: any) {
this.search = value;
}
@Watch('$route')
public changeRoute(to, from) {
if (this.customDialogModel === true && this.$route.name === 'character') {
this.closeAndReset();
}
}
public closeAndReset() {
this.search = '';
this.customDialogModel = false;
}
public navigateTo(e) {
this.$router.push({
name: e,
});
}
}
</script>

这里的问题是_.debounce的使用。去抖动函数返回要去抖动的新函数,但实际上并不调用任何内容。以目前在searchCharacter中使用的方式,它创建了一个新的去抖动函数,但对它没有任何作用。

解决此问题的一种方法是在searchCharacter之外创建去抖动函数,然后调用它:

@Watch("search")
public searchCharacter(value: any) {
this.debouncedSearchCharacter(value)
}
public debouncedSearchCharacter = _.debounce((value) => {
// for route query
let route: any = {
name: "characters",
}
if (value !== "") {
route.query = {
search: value,
}
}
if (this.$route.name === "characters") {
this.$router.push(route)
}
}, 700)

我根据这个线程想通了:

https://github.com/vuejs-templates/browserify-simple/issues/6

有了这个,我关于使用去抖动的新代码是这样的:

public debouncedSearchCharacter = _.debounce((search) => {
this.searchFinder(search);
}, 700);
public searchFinder(search) {
if (this.startSearch) {
// for route query
// first check if modal is open
let route: any = {};
route = {
name: 'characters',
};
console.log(`search searching: ${search}`);
console.log('in debounce search');
if (search !== '') {
route.query = {
search,
};
}
console.log(`what route: ${route}`);
if (this.$route.name === 'characters') {
console.log(this.$router.currentRoute);
this.$router.push(route);
}
}
}

问题是箭头函数:就像我有点怀疑将关键字/属性绑定到父上下文一样,这是作为上下文中的去抖动函数,没有引用这个。现在我的路由器可以定义,这个.$router.push(route(可以工作了。

最新更新